#ifdef SYSTEMC
/*
 * $Id: Special_Register_unit_genMealy_spr_access.cpp 123 2009-06-08 20:43:30Z 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::genMealy_spr_access"
  void Special_Register_unit::genMealy_spr_access (void)
  {
    log_begin(Special_Register_unit,FUNCTION);
    log_function(Special_Register_unit,FUNCTION,_name.c_str());

    if (PORT_READ(in_NRESET))
      {
    // ===================================================================
    // =====[ SPR_ACCESS ]================================================
    // ===================================================================
    for (uint32_t i=0; i<_param->_nb_inst_reexecute; i++)
      // not necessery if have not read enable
      if (PORT_READ(in_SPR_ACCESS_VAL [i]))
	{
          log_printf(TRACE,Special_Register_unit,FUNCTION,"  * SPR_ACCESS [%d]",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]);
	  
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * front_end_id : %d",front_end_id);
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * context_id   : %d",context_id  );
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * num_group    : %d",num_group   );
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * num_reg      : %d",num_reg     );
          
#ifdef DEBUG_TEST
          if (not _spr_access_mode [front_end_id][context_id]->exist(num_group,num_reg))
            msgWarning("Access at an invalid special register (group %d, register %d)\n",num_group,num_reg);
#endif

	  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;
	  
	  Tcontrol_t valid = _spr_access_mode [front_end_id][context_id]->read(spr_address_t(num_group,num_reg),
									       sm,
									       sumra);

          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * SM           : %d",sm);
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * SUMRA        : %d",sumra);
          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * valid        : %d",valid);

          // ISA OpenRISC : no action/exception if unauthorised spr access. Also, read 0.
//           if (not PORT_READ(in_SPR_ACCESS_WEN [i]))
//             {
          Tspr_t rdata = (valid)?(_spr[front_end_id][context_id][num_group][num_reg]->read()):0;

          log_printf(TRACE,Special_Register_unit,FUNCTION,"    * rdata        : %.8x",rdata);

          PORT_WRITE(out_SPR_ACCESS_RDATA   [i], rdata);
//             }
          PORT_WRITE(out_SPR_ACCESS_INVALID [i], not valid);
	}
      }
//     else
//       {

//       }
    
    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
