#ifdef SYSTEMC
//#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
/*
 * $Id: Reservation_station_genMoore.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Reservation_station/include/Reservation_station.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_read_unit {
namespace read_unit {
namespace reservation_station {


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

    // ~~~~~[ Interface "insert" ]~~~~~~~~~~~~~~~~~~~~~~~~
    
    // accept a new instructions when reservation_station is not full
#ifdef  SYSTEMC_VHDL_COMPATIBILITY
    for (internal_INSERT_SLOT=0; (internal_INSERT_SLOT<_param->_size_queue) and (_queue_valid[internal_INSERT_SLOT]==true); internal_INSERT_SLOT++);
    internal_INSERT_ACK = (internal_INSERT_SLOT<_param->_size_queue);
#else
    internal_INSERT_ACK = not _queue_control->full();
#endif    
    PORT_WRITE(out_INSERT_ACK, internal_INSERT_ACK);

    // ~~~~~[ Interface "retire" ]~~~~~~~~~~~~~~~~~~~~~~~

    uint32_t index_queue=0;
    const uint32_t nb_slot_scan = _param->_size_queue-_param->_nb_inst_retire+1;

    for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
      {
	bool     val        = false;
	uint32_t index_find = 0;;

	for (; (
#ifndef  SYSTEMC_VHDL_COMPATIBILITY
		(index_queue<_queue_control->nb_elt()) and
#endif
		(index_queue>=i) and 
		(index_queue<nb_slot_scan+i) and 
		(val==false));
	     index_queue++)
	  {
#ifdef  SYSTEMC_VHDL_COMPATIBILITY
	    index_find = index_queue;
#else
	    index_find = (*_queue_control)[index_queue];
#endif
	    internal_RETIRE_SLOT [i] = index_queue;

	    val   = 
	      (
#ifdef  SYSTEMC_VHDL_COMPATIBILITY
	       _queue_valid [index_queue]      and
#endif
	       _queue[index_find]._data_ra_val and 
	       _queue[index_find]._data_rb_val and 
	       _queue[index_find]._data_rc_val
	       );

// 	    cout << "========== Moore : " << endl
// 		 << " * i           : " << i << endl
// 		 << " * val         : " << val << endl
// 		 << " * index_queue : " << index_queue << endl
// 		 << " * index_find  : " << index_find << endl;
	  }

	internal_RETIRE_VAL [i] = val;
	PORT_WRITE(out_RETIRE_VAL [i], val);

	if (val)
	  {

// #ifdef  SYSTEMC_VHDL_COMPATIBILITY
// 	    index_find = internal_RETIRE_SLOT [i];
// #else
// 	    index_find = (*_queue_control)[internal_RETIRE_SLOT [i]];
// #endif
	    if (_param->_have_port_context_id)
	    PORT_WRITE(out_RETIRE_CONTEXT_ID    [i],_queue[index_find]._context_id);
	    if (_param->_have_port_front_end_id)
	    PORT_WRITE(out_RETIRE_FRONT_END_ID  [i],_queue[index_find]._front_end_id);
	    if (_param->_have_port_ooo_engine_id)
	    PORT_WRITE(out_RETIRE_OOO_ENGINE_ID [i],_queue[index_find]._ooo_engine_id);
	    if (_param->_have_port_rob_ptr)
	    PORT_WRITE(out_RETIRE_ROB_ID        [i],_queue[index_find]._rob_id);
	    PORT_WRITE(out_RETIRE_OPERATION     [i],_queue[index_find]._operation);
	    PORT_WRITE(out_RETIRE_TYPE          [i],_queue[index_find]._type);
	    PORT_WRITE(out_RETIRE_STORE_QUEUE_PTR_WRITE [i],_queue[index_find]._store_queue_ptr_write);
	    if (_param->_have_port_load_queue_ptr)
	    PORT_WRITE(out_RETIRE_LOAD_QUEUE_PTR_WRITE  [i],_queue[index_find]._load_queue_ptr_write );
	    PORT_WRITE(out_RETIRE_HAS_IMMEDIAT  [i],_queue[index_find]._has_immediat);
	    PORT_WRITE(out_RETIRE_IMMEDIAT      [i],_queue[index_find]._immediat);
	    PORT_WRITE(out_RETIRE_DATA_RA       [i],_queue[index_find]._data_ra);
	    PORT_WRITE(out_RETIRE_DATA_RB       [i],_queue[index_find]._data_rb);
	    PORT_WRITE(out_RETIRE_DATA_RC       [i],_queue[index_find]._data_rc);
	    PORT_WRITE(out_RETIRE_WRITE_RD      [i],_queue[index_find]._write_rd);
	    PORT_WRITE(out_RETIRE_NUM_REG_RD    [i],_queue[index_find]._num_reg_rd);
	    PORT_WRITE(out_RETIRE_WRITE_RE      [i],_queue[index_find]._write_re);
	    PORT_WRITE(out_RETIRE_NUM_REG_RE    [i],_queue[index_find]._num_reg_re);
	  }
      }

    log_end(Reservation_station,FUNCTION);
  };

}; // end namespace reservation_station
}; // end namespace read_unit
}; // end namespace multi_read_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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