#ifdef SYSTEMC
/*
 * $Id: Special_Register_unit_transition.cpp 97 2008-12-19 15:34:00Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Special_Register_unit/include/Special_Register_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace special_register_unit {


#undef  FUNCTION
#define FUNCTION "Special_Register_unit::transition"
  void Special_Register_unit::transition (void)
  {
    log_begin(Special_Register_unit,FUNCTION);

    if (PORT_READ(in_NRESET) == 0)
      {
	for (uint32_t i=0; i<_param->_nb_front_end; i++)
	  for (uint32_t j=0; j<_param->_nb_context[i]; j++)
	    for (uint32_t k=0; k<NB_GROUP; k++)
	      if (_param->_implement_group [i][j][k])
		for (uint32_t l=0; l<NB_REG_GROUP[k]; l++)
		  if (_spr_access_mode [i][j]->exist(k,l))
		    {
#ifdef DEBUG_TEST
		      if (_spr [i][j][k]    == NULL)
			throw ERRORMORPHEO(FUNCTION,toString(_("Group [%d] is not implemented.\n"),k));
		      if (_spr [i][j][k][l] == NULL)
			throw ERRORMORPHEO(FUNCTION,toString(_("Register [%d][%d] is not implemented.\n"),k,l));
#endif
 		      log_printf(TRACE,Special_Register_unit,FUNCTION,"Reset SPR [%d][%d][%d][%d]",i,j,k,l);
		      _spr [i][j][k][l]->reset();
		    }

      }
    else
      {
	// ===================================================================
	// =====[ SPR_ACCESS ]================================================
	// ===================================================================
	for (uint32_t i=0; i<_param->_nb_inst_reexecute; i++)
	  if (PORT_READ(in_SPR_ACCESS_VAL [i]) and internal_SPR_ACCESS_ACK [i])
	    if (PORT_READ(in_SPR_ACCESS_WEN [i]))
	      {
		Tcontext_t     front_end_id = (_param->_have_port_front_end_id)?PORT_READ(in_SPR_ACCESS_FRONT_END_ID [i]):0;
		Tcontext_t     context_id   = (_param->_have_port_context_id  )?PORT_READ(in_SPR_ACCESS_CONTEXT_ID   [i]):0;
		Tspr_address_t num_group    = PORT_READ(in_SPR_ACCESS_NUM_GROUP [i]);
		Tspr_address_t num_reg      = PORT_READ(in_SPR_ACCESS_NUM_REG   [i]);

 		SR * sr = static_cast<SR*>(_spr [front_end_id][context_id][GROUP_SYSTEM_AND_CONTROL][SPR_SR]);

		Tcontrol_t sm    = sr->sm   ;
		Tcontrol_t sumra = sr->sumra;

		if (_spr_access_mode [front_end_id][context_id]->write(spr_address_t(num_group,num_reg),
								       sm,
								       sumra))
		  _spr[front_end_id][context_id][num_group][num_reg]->write(PORT_READ(in_SPR_ACCESS_WDATA [i]));
		
	      }
	
	// ===================================================================
	// =====[ SPR_COMMIT ]-===============================================
	// ===================================================================
	for (uint32_t i=0; i<_param->_nb_front_end; i++)
	  for (uint32_t j=0; j<_param->_nb_context[i]; j++)
            {
              if (PORT_READ(in_SPR_COMMIT_VAL [i][j])) // out_SPR_COMMIT_ACK [i][j]
                {
                  SR * sr = static_cast<SR*>(_spr [i][j][GROUP_SYSTEM_AND_CONTROL][SPR_SR]);

                  if (PORT_READ(in_SPR_COMMIT_SR_F_VAL  [i][j]))
                    sr->f  = PORT_READ(in_SPR_COMMIT_SR_F  [i][j]);
                  
                  if (PORT_READ(in_SPR_COMMIT_SR_CY_VAL [i][j]))
                    sr->cy = PORT_READ(in_SPR_COMMIT_SR_CY [i][j]);
                  
                  if (PORT_READ(in_SPR_COMMIT_SR_OV_VAL [i][j]))
                    sr->ov = PORT_READ(in_SPR_COMMIT_SR_OV [i][j]);
                }

              if (PORT_READ(in_SPR_EVENT_VAL [i][j])) // out_SPR_EVENT_ACK [i][j]
                {
                  SR * sr = static_cast<SR*>(_spr [i][j][GROUP_SYSTEM_AND_CONTROL][SPR_SR]);
                  sr->dsx = PORT_READ(in_SPR_EVENT_SR_DSX [i][j]);

                  _spr [i][j][GROUP_SYSTEM_AND_CONTROL][SPR_EPCR]->write(PORT_READ(in_SPR_EVENT_EPCR [i][j]));
                  if (PORT_READ(in_SPR_EVENT_EEAR_WEN [i][j]))
                  _spr [i][j][GROUP_SYSTEM_AND_CONTROL][SPR_EEAR]->write(PORT_READ(in_SPR_EVENT_EEAR [i][j]));
                  if (PORT_READ(in_SPR_EVENT_SR_TO_ESR [i][j]))
                  _spr [i][j][GROUP_SYSTEM_AND_CONTROL][SPR_ESR ]->write(sr->read());
                }
            }
      }

#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
    end_cycle ();
#endif

    log_end(Special_Register_unit,FUNCTION);
  };

}; // end namespace special_register_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

}; // end namespace behavioural
}; // end namespace morpheo              
#endif
