/*
 * $Id$
 *
 * [ Description ]
 * 
 * Test
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Dependency_checking_unit/SelfTest/include/test.h"
#include "Common/include/Test.h"
#include "Behavioural/include/Allocation.h"
#include <list>

#define NB_ITERATION  32
#define CYCLE_MAX     (128*NB_ITERATION)

#define LABEL(str...)							\
  {									\
    msg (_("{%d} "),static_cast<uint32_t>(sc_simulation_time()));	\
    msg (str);								\
    msg (_("\n"));							\
  } while(0)

#define SC_START(cycle_offset)                                                       \
  do									             \
    {									             \
      /*cout << "SC_START (begin)" << endl;*/				             \
									             \
      uint32_t cycle_current = static_cast<uint32_t>(sc_simulation_time());          \
      if (cycle_offset != 0)						             \
	{								             \
	  cout << "##########[ cycle "<< cycle_current+cycle_offset << " ]" << endl; \
	}								             \
									             \
      if (cycle_current > CYCLE_MAX)					             \
	{								             \
	  TEST_KO("Maximal cycles Reached");				             \
	}								             \
									             \
      sc_start(cycle_offset);						             \
									             \
      /*cout << "SC_START (end  )" << endl;*/				             \
    } while(0)

void test (string name,
	   morpheo::behavioural::core::multi_ooo_engine::ooo_engine::rename_unit::register_translation_unit::dependency_checking_unit::Parameters * _param)
{
  msg(_("<%s> : Simulation SystemC.\n"),name.c_str());

#ifdef STATISTICS
  morpheo::behavioural::Parameters_Statistics * _parameters_statistics = new morpheo::behavioural::Parameters_Statistics (5,50);
#endif

  Dependency_checking_unit * _Dependency_checking_unit = new Dependency_checking_unit (name.c_str(),
#ifdef STATISTICS
					     _parameters_statistics,
#endif
					     _param);
  
#ifdef SYSTEMC
  /*********************************************************************
   * Déclarations des signaux
   *********************************************************************/

  string rename;

  sc_clock              *  in_CLOCK  = new sc_clock ("clock", 1.0, 0.5);	 
  sc_signal<Tcontrol_t> *  in_NRESET = new sc_signal<Tcontrol_t> ("NRESET");

//   ALLOC1_SC_SIGNAL( in_RENAME_IN_VAL                ," in_RENAME_IN_VAL                ",Tcontrol_t        ,_param->_nb_inst_insert);
//   ALLOC1_SC_SIGNAL(out_RENAME_IN_ACK                ,"out_RENAME_IN_ACK                ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_FRONT_END_ID       ," in_RENAME_IN_FRONT_END_ID       ",Tcontext_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_CONTEXT_ID         ," in_RENAME_IN_CONTEXT_ID         ",Tcontext_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_READ_RA            ," in_RENAME_IN_READ_RA            ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RA_LOG     ," in_RENAME_IN_NUM_REG_RA_LOG     ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RA_PHY     ," in_RENAME_IN_NUM_REG_RA_PHY     ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_READ_RB            ," in_RENAME_IN_READ_RB            ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RB_LOG     ," in_RENAME_IN_NUM_REG_RB_LOG     ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RB_PHY     ," in_RENAME_IN_NUM_REG_RB_PHY     ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_READ_RC            ," in_RENAME_IN_READ_RC            ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RC_LOG     ," in_RENAME_IN_NUM_REG_RC_LOG     ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RC_PHY     ," in_RENAME_IN_NUM_REG_RC_PHY     ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_WRITE_RD           ," in_RENAME_IN_WRITE_RD           ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RD_LOG     ," in_RENAME_IN_NUM_REG_RD_LOG     ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RD_PHY_OLD ," in_RENAME_IN_NUM_REG_RD_PHY_OLD ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RD_PHY_NEW ," in_RENAME_IN_NUM_REG_RD_PHY_NEW ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_WRITE_RE           ," in_RENAME_IN_WRITE_RE           ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RE_LOG     ," in_RENAME_IN_NUM_REG_RE_LOG     ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RE_PHY_OLD ," in_RENAME_IN_NUM_REG_RE_PHY_OLD ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL( in_RENAME_IN_NUM_REG_RE_PHY_NEW ," in_RENAME_IN_NUM_REG_RE_PHY_NEW ",Tspecial_address_t,_param->_nb_inst_insert);
//   ALLOC1_SC_SIGNAL(out_RENAME_OUT_VAL               ,"out_RENAME_OUT_VAL               ",Tcontrol_t        ,_param->_nb_inst_insert);
//   ALLOC1_SC_SIGNAL( in_RENAME_OUT_ACK               ," in_RENAME_OUT_ACK               ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_FRONT_END_ID      ,"out_RENAME_OUT_FRONT_END_ID      ",Tcontext_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_CONTEXT_ID        ,"out_RENAME_OUT_CONTEXT_ID        ",Tcontext_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_READ_RA           ,"out_RENAME_OUT_READ_RA           ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RA_LOG    ,"out_RENAME_OUT_NUM_REG_RA_LOG    ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RA_PHY    ,"out_RENAME_OUT_NUM_REG_RA_PHY    ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_READ_RB           ,"out_RENAME_OUT_READ_RB           ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RB_LOG    ,"out_RENAME_OUT_NUM_REG_RB_LOG    ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RB_PHY    ,"out_RENAME_OUT_NUM_REG_RB_PHY    ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_READ_RC           ,"out_RENAME_OUT_READ_RC           ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RC_LOG    ,"out_RENAME_OUT_NUM_REG_RC_LOG    ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RC_PHY    ,"out_RENAME_OUT_NUM_REG_RC_PHY    ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_WRITE_RD          ,"out_RENAME_OUT_WRITE_RD          ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RD_LOG    ,"out_RENAME_OUT_NUM_REG_RD_LOG    ",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RD_PHY_OLD,"out_RENAME_OUT_NUM_REG_RD_PHY_OLD",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RD_PHY_NEW,"out_RENAME_OUT_NUM_REG_RD_PHY_NEW",Tgeneral_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_WRITE_RE          ,"out_RENAME_OUT_WRITE_RE          ",Tcontrol_t        ,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RE_LOG    ,"out_RENAME_OUT_NUM_REG_RE_LOG    ",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RE_PHY_OLD,"out_RENAME_OUT_NUM_REG_RE_PHY_OLD",Tspecial_address_t,_param->_nb_inst_insert);
  ALLOC1_SC_SIGNAL(out_RENAME_OUT_NUM_REG_RE_PHY_NEW,"out_RENAME_OUT_NUM_REG_RE_PHY_NEW",Tspecial_address_t,_param->_nb_inst_insert);
  
  /********************************************************
   * Instanciation
   ********************************************************/
  
  msg(_("<%s> : Instanciation of _Dependency_checking_unit.\n"),name.c_str());

  (*(_Dependency_checking_unit->in_CLOCK))        (*(in_CLOCK));
  (*(_Dependency_checking_unit->in_NRESET))       (*(in_NRESET));

//   INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_VAL                ,_param->_nb_inst_insert);
//   INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_IN_ACK                ,_param->_nb_inst_insert);
  if (_param->_have_port_front_end_id)
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_FRONT_END_ID       ,_param->_nb_inst_insert);
  if (_param->_have_port_context_id)
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_CONTEXT_ID         ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_READ_RA            ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RA_LOG     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RA_PHY     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_READ_RB            ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RB_LOG     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RB_PHY     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_READ_RC            ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RC_LOG     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RC_PHY     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_WRITE_RD           ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RD_LOG     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RD_PHY_OLD ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RD_PHY_NEW ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_WRITE_RE           ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RE_LOG     ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RE_PHY_OLD ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_IN_NUM_REG_RE_PHY_NEW ,_param->_nb_inst_insert);

//   INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_VAL               ,_param->_nb_inst_insert);
//   INSTANCE1_SC_SIGNAL(_Dependency_checking_unit, in_RENAME_OUT_ACK               ,_param->_nb_inst_insert);
  if (_param->_have_port_front_end_id)
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_FRONT_END_ID      ,_param->_nb_inst_insert);
  if (_param->_have_port_context_id)
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_CONTEXT_ID        ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_READ_RA           ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RA_LOG    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RA_PHY    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_READ_RB           ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RB_LOG    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RB_PHY    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_READ_RC           ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RC_LOG    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RC_PHY    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_WRITE_RD          ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RD_LOG    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RD_PHY_OLD,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RD_PHY_NEW,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_WRITE_RE          ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RE_LOG    ,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RE_PHY_OLD,_param->_nb_inst_insert);
  INSTANCE1_SC_SIGNAL(_Dependency_checking_unit,out_RENAME_OUT_NUM_REG_RE_PHY_NEW,_param->_nb_inst_insert);

  msg(_("<%s> : Start Simulation ............\n"),name.c_str());
    
  Time * _time = new Time();

  /********************************************************
   * Simulation - Begin
   ********************************************************/

  // Initialisation

  const uint32_t seed = 0;
//const uint32_t seed = static_cast<uint32_t>(time(NULL));

  srand(seed);

  int32_t percent_transaction_read  = 75;
  int32_t percent_transaction_write = 75;

  SC_START(0);
  LABEL("Initialisation");

  LABEL("Reset");
  in_NRESET->write(0);
  SC_START(5);
  in_NRESET->write(1);  

  LABEL("Loop of Test");

  for (uint32_t iteration=0; iteration<NB_ITERATION; iteration ++)
    {
      LABEL("Iteration %d",iteration);

      Tgeneral_address_t rat_gpr [_param->_nb_front_end][_param->_max_nb_context][_param->_nb_general_register_logic];
      Tspecial_address_t rat_spr [_param->_nb_front_end][_param->_max_nb_context][_param->_nb_special_register_logic];
      std::list<Tgeneral_address_t> free_list_gpr [_param->_nb_front_end][_param->_max_nb_context];
      std::list<Tspecial_address_t> free_list_spr [_param->_nb_front_end][_param->_max_nb_context];  
      
      for (uint32_t x=0; x< _param->_nb_front_end; x++)
	for (uint32_t y=0; y<_param->_max_nb_context; y++)
	  {
	    for (uint32_t i=0; i<_param->_nb_general_register_logic; i++)
	      rat_gpr [x][y][i] = i;
	    for (uint32_t i=_param->_nb_general_register_logic; i<_param->_nb_general_register; i++)
	      free_list_gpr[x][y].push_back(i);
	    for (uint32_t i=0; i<_param->_nb_special_register_logic; i++)
	      rat_spr [x][y][i] = i;
	    for (uint32_t i=_param->_nb_special_register_logic; i<_param->_nb_special_register; i++)
	      free_list_spr[x][y].push_back(i);
	  }

      int32_t nb_request = 32;

      while (nb_request >= 0)
	{
// 	  uint32_t nb_in_val  = rand()%_param->_nb_inst_insert;
// 	  uint32_t nb_out_ack = rand()%_param->_nb_inst_insert;

	  std::list<Tgeneral_address_t>::iterator it_gpr [_param->_nb_front_end][_param->_max_nb_context];
	  std::list<Tspecial_address_t>::iterator it_spr [_param->_nb_front_end][_param->_max_nb_context];
	  
	  for (uint32_t x=0; x< _param->_nb_front_end; x++)
	    for (uint32_t y=0; y<_param->_max_nb_context; y++)
	      {
		it_gpr [x][y] = free_list_gpr [x][y].begin();
		it_spr [x][y] = free_list_spr [x][y].begin();
	      }

	  for (uint32_t i=0; i<_param->_nb_inst_insert; i++)
	    {
	      Tcontext_t front_end_id= rand()%_param->_nb_front_end;
	      Tcontext_t context_id  = rand()%_param->_max_nb_context;

	      Tgeneral_address_t ra_log   = rand()%_param->_nb_general_register_logic;
	      Tgeneral_address_t rb_log   = rand()%_param->_nb_general_register_logic;
	      Tspecial_address_t rc_log   = rand()%_param->_nb_special_register_logic;
	      Tgeneral_address_t rd_log   = rand()%_param->_nb_general_register_logic;
	      Tspecial_address_t re_log   = rand()%_param->_nb_special_register_logic;
	      Tcontrol_t         read_ra  = ((rand()%100)<percent_transaction_read );
	      Tcontrol_t         read_rb  = ((rand()%100)<percent_transaction_read );
	      Tcontrol_t         read_rc  = ((rand()%100)<percent_transaction_read );
	      Tcontrol_t         write_rd = ((rand()%100)<percent_transaction_write)and (i < free_list_gpr [front_end_id][context_id].size());
	      Tcontrol_t         write_re = ((rand()%100)<percent_transaction_write)and (i < free_list_spr [front_end_id][context_id].size());

// 	      in_RENAME_IN_VAL                [i]->write(i<nb_in_val                              );
	      in_RENAME_IN_FRONT_END_ID       [i]->write(front_end_id                             );
	      in_RENAME_IN_CONTEXT_ID         [i]->write(context_id                               );
	      in_RENAME_IN_READ_RA            [i]->write(read_ra                                  );
	      in_RENAME_IN_NUM_REG_RA_LOG     [i]->write(ra_log                                   );
	      in_RENAME_IN_NUM_REG_RA_PHY     [i]->write(rat_gpr[front_end_id][context_id][ra_log]);
	      in_RENAME_IN_READ_RB            [i]->write(read_rb                                  );
	      in_RENAME_IN_NUM_REG_RB_LOG     [i]->write(rb_log                                   );
	      in_RENAME_IN_NUM_REG_RB_PHY     [i]->write(rat_gpr[front_end_id][context_id][rb_log]);
	      in_RENAME_IN_READ_RC            [i]->write(read_rc                                  );
	      in_RENAME_IN_NUM_REG_RC_LOG     [i]->write(rc_log                                   );
	      in_RENAME_IN_NUM_REG_RC_PHY     [i]->write(rat_spr[front_end_id][context_id][rc_log]);
	      in_RENAME_IN_WRITE_RD           [i]->write(write_rd                                 );
	      in_RENAME_IN_NUM_REG_RD_LOG     [i]->write(rd_log                                   );
	      in_RENAME_IN_NUM_REG_RD_PHY_OLD [i]->write(rat_gpr[front_end_id][context_id][rd_log]);
	      in_RENAME_IN_NUM_REG_RD_PHY_NEW [i]->write((write_rd)?*it_gpr[front_end_id][context_id]:0);
	      in_RENAME_IN_WRITE_RE           [i]->write(write_re                                 );
	      in_RENAME_IN_NUM_REG_RE_LOG     [i]->write(re_log                                   );
	      in_RENAME_IN_NUM_REG_RE_PHY_OLD [i]->write(rat_spr[front_end_id][context_id][re_log]);
	      in_RENAME_IN_NUM_REG_RE_PHY_NEW [i]->write((write_re)?*it_spr[front_end_id][context_id]:0);

// 	      in_RENAME_OUT_ACK               [i]->write(i<nb_out_ack                             );

	      LABEL("Rename_in  [%d]",i);
	      LABEL(" * FRONT_END_ID       : %d",front_end_id                             );
	      LABEL(" * CONTEXT_ID         : %d",context_id                               );
	      LABEL(" * READ_RA            : %d",read_ra                                  );
	      LABEL(" * NUM_REG_RA_LOG     : %d",ra_log                                   );
	      LABEL(" * NUM_REG_RA_PHY     : %d",rat_gpr[front_end_id][context_id][ra_log]);
	      LABEL(" * READ_RB            : %d",read_rb                                  );
	      LABEL(" * NUM_REG_RB_LOG     : %d",rb_log                                   );
	      LABEL(" * NUM_REG_RB_PHY     : %d",rat_gpr[front_end_id][context_id][rb_log]);
	      LABEL(" * READ_RC            : %d",read_rc                                  );
	      LABEL(" * NUM_REG_RC_LOG     : %d",rc_log                                   );
	      LABEL(" * NUM_REG_RC_PHY     : %d",rat_spr[front_end_id][context_id][rc_log]);
	      LABEL(" * WRITE_RD           : %d",write_rd                                 );
	      LABEL(" * NUM_REG_RD_LOG     : %d",rd_log                                   );
	      LABEL(" * NUM_REG_RD_PHY_OLD : %d",rat_gpr[front_end_id][context_id][rd_log]);
	      LABEL(" * NUM_REG_RD_PHY_NEW : %d",(write_rd)?*it_gpr[front_end_id][context_id]:0);
	      LABEL(" * WRITE_RE           : %d",write_re                                 );
	      LABEL(" * NUM_REG_RE_LOG     : %d",re_log                                   );
	      LABEL(" * NUM_REG_RE_PHY_OLD : %d",rat_spr[front_end_id][context_id][re_log]);
	      LABEL(" * NUM_REG_RE_PHY_NEW : %d",(write_re)?*it_spr[front_end_id][context_id]:0);
	      

	      if (write_rd)
		it_gpr[front_end_id][context_id] ++;
	      if (write_re)
		it_spr[front_end_id][context_id] ++;
	    }

	  SC_START(0);
	  
	  for (uint32_t i=0; i<_param->_nb_inst_insert; i++)
	    {
// 	      if ( in_RENAME_IN_VAL  [i]->read() == 
// 		  out_RENAME_IN_ACK  [i]->read() ==
// 		  out_RENAME_OUT_VAL [i]->read() ==
// 		   in_RENAME_OUT_ACK [i]->read() == 1)
		{
		  nb_request --;

		  LABEL("Rename_out [%d]",i);

		  Tcontext_t front_end_id= (_param->_have_port_front_end_id)?in_RENAME_IN_FRONT_END_ID [i]->read():0;
		  Tcontext_t context_id  = (_param->_have_port_context_id  )?in_RENAME_IN_CONTEXT_ID   [i]->read():0;
		  
		  if (_param->_have_port_front_end_id)
		  TEST(Tcontext_t        ,out_RENAME_OUT_FRONT_END_ID       [i]->read(), front_end_id);
		  if (_param->_have_port_context_id)
		  TEST(Tcontext_t        ,out_RENAME_OUT_CONTEXT_ID         [i]->read(), context_id);


		  Tcontrol_t         read_ra            = in_RENAME_IN_READ_RA            [i]->read();
		  Tgeneral_address_t num_reg_ra_log     = in_RENAME_IN_NUM_REG_RA_LOG     [i]->read();
		  Tcontrol_t         read_rb            = in_RENAME_IN_READ_RB            [i]->read();
		  Tgeneral_address_t num_reg_rb_log     = in_RENAME_IN_NUM_REG_RB_LOG     [i]->read();
		  Tcontrol_t         read_rc            = in_RENAME_IN_READ_RC            [i]->read();
		  Tspecial_address_t num_reg_rc_log     = in_RENAME_IN_NUM_REG_RC_LOG     [i]->read();
		  Tcontrol_t         write_rd           = in_RENAME_IN_WRITE_RD           [i]->read();
		  Tgeneral_address_t num_reg_rd_log     = in_RENAME_IN_NUM_REG_RD_LOG     [i]->read();
		  Tgeneral_address_t num_reg_rd_phy_old = in_RENAME_IN_NUM_REG_RD_PHY_OLD [i]->read();
		  Tgeneral_address_t num_reg_rd_phy_new = in_RENAME_IN_NUM_REG_RD_PHY_NEW [i]->read();
		  Tcontrol_t         write_re           = in_RENAME_IN_WRITE_RE           [i]->read();
		  Tspecial_address_t num_reg_re_log     = in_RENAME_IN_NUM_REG_RE_LOG     [i]->read();
		  Tspecial_address_t num_reg_re_phy_old = in_RENAME_IN_NUM_REG_RE_PHY_OLD [i]->read();
		  Tspecial_address_t num_reg_re_phy_new = in_RENAME_IN_NUM_REG_RE_PHY_NEW [i]->read();

		  TEST(Tcontrol_t        ,out_RENAME_OUT_READ_RA            [i]->read(), read_ra           );
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RA_LOG     [i]->read(), num_reg_ra_log    );
		  if (read_ra)
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RA_PHY     [i]->read(), rat_gpr[front_end_id][context_id][num_reg_ra_log]);
		  TEST(Tcontrol_t        ,out_RENAME_OUT_READ_RB            [i]->read(), read_rb           );
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RB_LOG     [i]->read(), num_reg_rb_log    );
		  if (read_rb)
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RB_PHY     [i]->read(), rat_gpr[front_end_id][context_id][num_reg_rb_log]);
		  TEST(Tcontrol_t        ,out_RENAME_OUT_READ_RC            [i]->read(), read_rc           );
		  TEST(Tspecial_address_t,out_RENAME_OUT_NUM_REG_RC_LOG     [i]->read(), num_reg_rc_log    );
		  if (read_rc)
		  TEST(Tspecial_address_t,out_RENAME_OUT_NUM_REG_RC_PHY     [i]->read(), rat_spr[front_end_id][context_id][num_reg_rc_log]);
		  TEST(Tcontrol_t        ,out_RENAME_OUT_WRITE_RD           [i]->read(), write_rd          );
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RD_LOG     [i]->read(), num_reg_rd_log    );
		  if (write_rd)
		    {
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RD_PHY_OLD [i]->read(), rat_gpr[front_end_id][context_id][num_reg_rd_log]);
		  TEST(Tgeneral_address_t,out_RENAME_OUT_NUM_REG_RD_PHY_NEW [i]->read(), free_list_gpr[front_end_id][context_id].front());
		    }
		  TEST(Tcontrol_t        ,out_RENAME_OUT_WRITE_RE           [i]->read(), write_re          );
		  TEST(Tspecial_address_t,out_RENAME_OUT_NUM_REG_RE_LOG     [i]->read(), num_reg_re_log    );
		  if (write_re)
		    {
		  TEST(Tspecial_address_t,out_RENAME_OUT_NUM_REG_RE_PHY_OLD [i]->read(), rat_spr[front_end_id][context_id][num_reg_re_log]);
		  TEST(Tspecial_address_t,out_RENAME_OUT_NUM_REG_RE_PHY_NEW [i]->read(), free_list_spr[front_end_id][context_id].front());
		    }

		  if (write_rd)
		    {
		      free_list_gpr[front_end_id][context_id].pop_front();
		      free_list_gpr[front_end_id][context_id].push_back(num_reg_rd_phy_old);
		      rat_gpr      [front_end_id][context_id][num_reg_rd_log] = num_reg_rd_phy_new;
		    }
		  if (write_re)
		    {
		      free_list_spr[front_end_id][context_id].pop_front();
		      free_list_spr[front_end_id][context_id].push_back(num_reg_re_phy_old);
		      rat_spr      [front_end_id][context_id][num_reg_re_log] = num_reg_re_phy_new;
		    }
		  
		}
	    }
	  SC_START(1);
	}
    }

  /********************************************************
   * Simulation - End
   ********************************************************/

  TEST_OK ("End of Simulation");
  delete _time;

  msg(_("<%s> : ............ Stop Simulation\n"),name.c_str());

  delete in_CLOCK;
  delete in_NRESET;

//   delete []  in_RENAME_IN_VAL                ;
//   delete [] out_RENAME_IN_ACK                ;
  if (_param->_have_port_front_end_id)
  delete []  in_RENAME_IN_FRONT_END_ID       ;
  if (_param->_have_port_context_id)
  delete []  in_RENAME_IN_CONTEXT_ID         ;
  delete []  in_RENAME_IN_READ_RA            ;
  delete []  in_RENAME_IN_NUM_REG_RA_LOG     ;
  delete []  in_RENAME_IN_NUM_REG_RA_PHY     ;
  delete []  in_RENAME_IN_READ_RB            ;
  delete []  in_RENAME_IN_NUM_REG_RB_LOG     ;
  delete []  in_RENAME_IN_NUM_REG_RB_PHY     ;
  delete []  in_RENAME_IN_READ_RC            ;
  delete []  in_RENAME_IN_NUM_REG_RC_LOG     ;
  delete []  in_RENAME_IN_NUM_REG_RC_PHY     ;
  delete []  in_RENAME_IN_WRITE_RD           ;
  delete []  in_RENAME_IN_NUM_REG_RD_LOG     ;
  delete []  in_RENAME_IN_NUM_REG_RD_PHY_OLD ;
  delete []  in_RENAME_IN_NUM_REG_RD_PHY_NEW ;
  delete []  in_RENAME_IN_WRITE_RE           ;
  delete []  in_RENAME_IN_NUM_REG_RE_LOG     ;
  delete []  in_RENAME_IN_NUM_REG_RE_PHY_OLD ;
  delete []  in_RENAME_IN_NUM_REG_RE_PHY_NEW ;
//   delete [] out_RENAME_OUT_VAL               ;
//   delete []  in_RENAME_OUT_ACK               ;
  if (_param->_have_port_front_end_id)
  delete [] out_RENAME_OUT_FRONT_END_ID      ;
  if (_param->_have_port_context_id)
  delete [] out_RENAME_OUT_CONTEXT_ID        ;
  delete [] out_RENAME_OUT_READ_RA           ;
  delete [] out_RENAME_OUT_NUM_REG_RA_LOG    ;
  delete [] out_RENAME_OUT_NUM_REG_RA_PHY    ;
  delete [] out_RENAME_OUT_READ_RB           ;
  delete [] out_RENAME_OUT_NUM_REG_RB_LOG    ;
  delete [] out_RENAME_OUT_NUM_REG_RB_PHY    ;
  delete [] out_RENAME_OUT_READ_RC           ;
  delete [] out_RENAME_OUT_NUM_REG_RC_LOG    ;
  delete [] out_RENAME_OUT_NUM_REG_RC_PHY    ;
  delete [] out_RENAME_OUT_WRITE_RD          ;
  delete [] out_RENAME_OUT_NUM_REG_RD_LOG    ;
  delete [] out_RENAME_OUT_NUM_REG_RD_PHY_OLD;
  delete [] out_RENAME_OUT_NUM_REG_RD_PHY_NEW;
  delete [] out_RENAME_OUT_WRITE_RE          ;
  delete [] out_RENAME_OUT_NUM_REG_RE_LOG    ;
  delete [] out_RENAME_OUT_NUM_REG_RE_PHY_OLD;
  delete [] out_RENAME_OUT_NUM_REG_RE_PHY_NEW;

#endif

  delete _Dependency_checking_unit;
#ifdef STATISTICS
  delete _parameters_statistics;
#endif
}
