/*
 * SecBus - This file is part of SecBus
 * Copyright (C) 2012 - Telecom ParisTech
 * 
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at    
 * http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.txt
 *
 */

#include "irq_handler.h"

IrqHandler::IrqHandler(sc_module_name name, size_t nirq): 
		 sc_module(name),
		 p_clk("clk"),
		 p_resetn("resetn")
{
  m_nirq = nirq;

  irq_in = new IRQ_IN[nirq];

  SC_METHOD(transition);
  dont_initialize();
  sensitive << p_clk.pos();

  SC_METHOD(genMoore);
  dont_initialize();
  sensitive << p_clk.neg();

  DEBUG(NONE, STD, "[SECBUS] Building IrqHandler (%s) with %u interrupt sources\n", 
	basename(), nirq);
}

IrqHandler::~IrqHandler()
{
  delete irq_in;
}

void IrqHandler::transition()
{
  if (!p_resetn.read())
  {
    interrupt_s = 0;
    type_s = io_status_e_none;
    addr_s = 0;
    irq_n_s = 0;
    op_s = io_status_e_load;

    return;
  }

  for (size_t i=0;i<m_nirq;i++)
  {
    if (irq_in[i].irq.read())
    {
      irq_n_s = i;
      interrupt_s = true;
      type_s = irq_in[i].type.read();
      addr_s = irq_in[i].address.read();
      op_s = irq_in[i].op.read();

      break;
    }
    else
    {
      interrupt_s = false;
    }
  }
}

void IrqHandler::genMoore()
{
  irq_out.irq     = interrupt_s.read();
  irq_out.address = addr_s.read();
  irq_out.type    = type_s.read();
  irq_out.op      = op_s.read();

  for (size_t i=0;i<m_nirq;i++)
  {
    irq_in[i].ack = irq_out.ack.read();
  }
}
