#ifdef SYSTEMC
/*
 * $Id: Free_List_unit_transition.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Free_List_unit/include/Free_List_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace rename_unit {
namespace register_translation_unit {
namespace free_list_unit {


#undef  FUNCTION
#define FUNCTION "Free_List_unit::transition"
  void Free_List_unit::transition (void)
  {
    log_begin(Free_List_unit,FUNCTION);
    log_function(Free_List_unit,FUNCTION,_name.c_str());

    if (PORT_READ(in_NRESET) == 0)
      {
	internal_BANK_PRIORITY = 0;
	for (uint32_t i=0; i<_param->_nb_bank; i++)
	  {
	    _gpr_list[i].clear();
	    _spr_list[i].clear();
	  }
      }
    else
      {
	// ==================================================
	// =====[ POP ]======================================
	// ==================================================
	for (uint32_t i=0; i<_param->_nb_pop; i++)
	  if (PORT_READ(in_POP_VAL[i]) and internal_POP_ACK [i])
	    {
              log_printf(TRACE,Free_List_unit,FUNCTION,"  * POP [%d]",i);

	      if (PORT_READ(in_POP_GPR_VAL [i]))
		_gpr_list [internal_POP_GPR_BANK[i]].pop_front();
	 
	      if (PORT_READ(in_POP_SPR_VAL [i]))
		_spr_list [internal_POP_SPR_BANK[i]].pop_front();
	    }

	// ==================================================
	// =====[ PUSH_GPR ]=================================
	// ==================================================
	for (uint32_t i=0; i<_param->_nb_push; i++)
	  if (PORT_READ(in_PUSH_GPR_VAL[i]) and internal_PUSH_GPR_ACK [i])
            {
              log_printf(TRACE,Free_List_unit,FUNCTION,"  * PUSH_GPR[%d]",i);

              _gpr_list [internal_PUSH_GPR_BANK[i]].push_back(//_param->_mask_gpr &
                                                              PORT_READ(in_PUSH_GPR_NUM_REG [i]));
            }
	// ==================================================
	// =====[ PUSH_SPR ]=================================
	// ==================================================
	for (uint32_t i=0; i<_param->_nb_push; i++)
	  if (PORT_READ(in_PUSH_SPR_VAL[i]) and internal_PUSH_SPR_ACK [i])
            {
              log_printf(TRACE,Free_List_unit,FUNCTION,"  * PUSH_SPR[%d]",i);

              _spr_list [internal_PUSH_SPR_BANK[i]].push_back(//_param->_mask_spr &
                                                              PORT_READ(in_PUSH_SPR_NUM_REG [i]));
            }

	if (_param->_priority == PRIORITY_ROUND_ROBIN)
	  internal_BANK_PRIORITY = (internal_BANK_PRIORITY+1)%_param->_nb_bank_by_pop;

#if (DEBUG >= DEBUG_TRACE) and (DEBUG_Free_List_unit == true)
        log_printf(TRACE,Free_List_unit,FUNCTION,"  * Dump Free List");

        for (uint32_t i=0; i<_param->_nb_bank; ++i)
          {
            uint32_t j=0;
            for (std::list<Tgeneral_address_t>::iterator it=_gpr_list->begin();
                 it!=_gpr_list->end();
                 ++it)
              {
                log_printf(TRACE,Free_List_unit,FUNCTION,"    * GPR_LIST[%.5d][%.5d] : %.5d",i,j,*it);
                ++j;
              }
          }
        for (uint32_t i=0; i<_param->_nb_bank; ++i)
          {
            uint32_t j=0;
            for (std::list<Tspecial_address_t>::iterator it=_spr_list->begin();
                 it!=_spr_list->end();
                 ++it)
              {
                log_printf(TRACE,Free_List_unit,FUNCTION,"    * SPR_LIST[%.5d][%.5d] : %.5d",i,j,*it);
                ++j;
              }
          }

#endif
      }

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

    log_end(Free_List_unit,FUNCTION);
  };

}; // end namespace free_list_unit
}; // end namespace register_translation_unit
}; // end namespace rename_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

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