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

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Reservation_station/SelfTest/include/test.h"
#include "Common/include/Test.h"

#define NB_ITERATION  2
#define CYCLE_MAX     (2048*NB_ITERATION)

#define LABEL(str)                                                                       \
{                                                                                        \
  cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} " << str << endl; \
} while(0)

static uint32_t cycle = 0;

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

void test (string name,
	   morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_read_unit::read_unit::reservation_station::Parameters * _param)
{
  cout << "<" << name << "> : Simulation SystemC" << endl;

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

  Reservation_station * _Reservation_station = new Reservation_station (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");

  sc_signal<Tcontrol_t        > *  in_INSERT_VAL            = new sc_signal<Tcontrol_t        >;
  sc_signal<Tcontrol_t        > * out_INSERT_ACK            = new sc_signal<Tcontrol_t        >;
  sc_signal<Tcontext_t        > *  in_INSERT_CONTEXT_ID     = new sc_signal<Tcontext_t        >; 
  sc_signal<Tcontext_t        > *  in_INSERT_FRONT_END_ID   = new sc_signal<Tcontext_t        >;
  sc_signal<Tcontext_t        > *  in_INSERT_OOO_ENGINE_ID  = new sc_signal<Tcontext_t        >;
  sc_signal<Tpacket_t         > *  in_INSERT_ROB_ID         = new sc_signal<Tpacket_t         >;
  sc_signal<Toperation_t      > *  in_INSERT_OPERATION      = new sc_signal<Toperation_t      >;
  sc_signal<Ttype_t           > *  in_INSERT_TYPE           = new sc_signal<Ttype_t           >;
  sc_signal<Tcontrol_t        > *  in_INSERT_HAS_IMMEDIAT   = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_data_t   > *  in_INSERT_IMMEDIAT       = new sc_signal<Tgeneral_data_t   >;
//sc_signal<Tcontrol_t        > *  in_INSERT_READ_RA        = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_address_t> *  in_INSERT_NUM_REG_RA     = new sc_signal<Tgeneral_address_t>;
  sc_signal<Tcontrol_t        > *  in_INSERT_DATA_RA_VAL    = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_data_t   > *  in_INSERT_DATA_RA        = new sc_signal<Tgeneral_data_t   >;
//sc_signal<Tcontrol_t        > *  in_INSERT_READ_RB        = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_address_t> *  in_INSERT_NUM_REG_RB     = new sc_signal<Tgeneral_address_t>;
  sc_signal<Tcontrol_t        > *  in_INSERT_DATA_RB_VAL    = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_data_t   > *  in_INSERT_DATA_RB        = new sc_signal<Tgeneral_data_t   >;
//sc_signal<Tcontrol_t        > *  in_INSERT_READ_RC        = new sc_signal<Tcontrol_t        >;
  sc_signal<Tspecial_address_t> *  in_INSERT_NUM_REG_RC     = new sc_signal<Tspecial_address_t>;
  sc_signal<Tcontrol_t        > *  in_INSERT_DATA_RC_VAL    = new sc_signal<Tcontrol_t        >;
  sc_signal<Tspecial_data_t   > *  in_INSERT_DATA_RC        = new sc_signal<Tspecial_data_t   >;
  sc_signal<Tcontrol_t        > *  in_INSERT_WRITE_RD       = new sc_signal<Tcontrol_t        >;
  sc_signal<Tgeneral_address_t> *  in_INSERT_NUM_REG_RD     = new sc_signal<Tgeneral_address_t>;
  sc_signal<Tcontrol_t        > *  in_INSERT_WRITE_RE       = new sc_signal<Tcontrol_t        >;
  sc_signal<Tspecial_address_t> *  in_INSERT_NUM_REG_RE     = new sc_signal<Tspecial_address_t>;

  sc_signal<Tcontrol_t        > ** out_RETIRE_VAL            = new sc_signal<Tcontrol_t        > * [_param->_nb_inst_retire];
  sc_signal<Tcontrol_t        > **  in_RETIRE_ACK            = new sc_signal<Tcontrol_t        > * [_param->_nb_inst_retire];
  sc_signal<Tcontext_t        > ** out_RETIRE_CONTEXT_ID     = new sc_signal<Tcontext_t        > * [_param->_nb_inst_retire];
  sc_signal<Tcontext_t        > ** out_RETIRE_FRONT_END_ID   = new sc_signal<Tcontext_t        > * [_param->_nb_inst_retire];
  sc_signal<Tcontext_t        > ** out_RETIRE_OOO_ENGINE_ID  = new sc_signal<Tcontext_t        > * [_param->_nb_inst_retire];
  sc_signal<Tpacket_t         > ** out_RETIRE_ROB_ID         = new sc_signal<Tpacket_t         > * [_param->_nb_inst_retire];
  sc_signal<Toperation_t      > ** out_RETIRE_OPERATION      = new sc_signal<Toperation_t      > * [_param->_nb_inst_retire];
  sc_signal<Ttype_t           > ** out_RETIRE_TYPE           = new sc_signal<Ttype_t           > * [_param->_nb_inst_retire];
  sc_signal<Tcontrol_t        > ** out_RETIRE_HAS_IMMEDIAT   = new sc_signal<Tcontrol_t        > * [_param->_nb_inst_retire];
  sc_signal<Tgeneral_data_t   > ** out_RETIRE_IMMEDIAT       = new sc_signal<Tgeneral_data_t   > * [_param->_nb_inst_retire];
  sc_signal<Tgeneral_data_t   > ** out_RETIRE_DATA_RA        = new sc_signal<Tgeneral_data_t   > * [_param->_nb_inst_retire];
  sc_signal<Tgeneral_data_t   > ** out_RETIRE_DATA_RB        = new sc_signal<Tgeneral_data_t   > * [_param->_nb_inst_retire];
  sc_signal<Tspecial_data_t   > ** out_RETIRE_DATA_RC        = new sc_signal<Tspecial_data_t   > * [_param->_nb_inst_retire];
  sc_signal<Tcontrol_t        > ** out_RETIRE_WRITE_RD       = new sc_signal<Tcontrol_t        > * [_param->_nb_inst_retire];
  sc_signal<Tgeneral_address_t> ** out_RETIRE_NUM_REG_RD     = new sc_signal<Tgeneral_address_t> * [_param->_nb_inst_retire];
  sc_signal<Tcontrol_t        > ** out_RETIRE_WRITE_RE       = new sc_signal<Tcontrol_t        > * [_param->_nb_inst_retire];
  sc_signal<Tspecial_address_t> ** out_RETIRE_NUM_REG_RE     = new sc_signal<Tspecial_address_t> * [_param->_nb_inst_retire];
    
  for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
    {
      out_RETIRE_VAL             [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
       in_RETIRE_ACK             [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      out_RETIRE_CONTEXT_ID      [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      out_RETIRE_FRONT_END_ID    [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      out_RETIRE_OOO_ENGINE_ID   [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      out_RETIRE_ROB_ID          [i] = new sc_signal<Tpacket_t         > (rename.c_str());
      out_RETIRE_OPERATION       [i] = new sc_signal<Toperation_t      > (rename.c_str());
      out_RETIRE_TYPE            [i] = new sc_signal<Ttype_t           > (rename.c_str());
      out_RETIRE_HAS_IMMEDIAT    [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      out_RETIRE_IMMEDIAT        [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
      out_RETIRE_DATA_RA         [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
      out_RETIRE_DATA_RB         [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
      out_RETIRE_DATA_RC         [i] = new sc_signal<Tspecial_data_t   > (rename.c_str());
      out_RETIRE_WRITE_RD        [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      out_RETIRE_NUM_REG_RD      [i] = new sc_signal<Tgeneral_address_t> (rename.c_str());
      out_RETIRE_WRITE_RE        [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      out_RETIRE_NUM_REG_RE      [i] = new sc_signal<Tspecial_address_t> (rename.c_str());
    }

  sc_signal<Tcontrol_t        > ** in_GPR_WRITE_VAL           = new sc_signal<Tcontrol_t        > * [_param->_nb_gpr_write];
  sc_signal<Tcontext_t        > ** in_GPR_WRITE_OOO_ENGINE_ID = new sc_signal<Tcontext_t        > * [_param->_nb_gpr_write];
  sc_signal<Tgeneral_address_t> ** in_GPR_WRITE_NUM_REG       = new sc_signal<Tgeneral_address_t> * [_param->_nb_gpr_write];
  sc_signal<Tgeneral_data_t   > ** in_GPR_WRITE_DATA          = new sc_signal<Tgeneral_data_t   > * [_param->_nb_gpr_write];
   
  for (uint32_t i=0; i<_param->_nb_gpr_write; i++)
    {
      in_GPR_WRITE_VAL           [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      in_GPR_WRITE_OOO_ENGINE_ID [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      in_GPR_WRITE_NUM_REG       [i] = new sc_signal<Tgeneral_address_t> (rename.c_str());
      in_GPR_WRITE_DATA          [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
    }
  
  sc_signal<Tcontrol_t        > ** in_SPR_WRITE_VAL          = new sc_signal<Tcontrol_t        > * [_param->_nb_spr_write];
  sc_signal<Tcontext_t        > ** in_SPR_WRITE_OOO_ENGINE_ID= new sc_signal<Tcontext_t        > * [_param->_nb_spr_write];
  sc_signal<Tspecial_address_t> ** in_SPR_WRITE_NUM_REG      = new sc_signal<Tspecial_address_t> * [_param->_nb_spr_write];
  sc_signal<Tspecial_data_t   > ** in_SPR_WRITE_DATA         = new sc_signal<Tspecial_data_t   > * [_param->_nb_spr_write];
   
  for (uint32_t i=0; i<_param->_nb_spr_write; i++)
    {
      in_SPR_WRITE_VAL           [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      in_SPR_WRITE_OOO_ENGINE_ID [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      in_SPR_WRITE_NUM_REG       [i] = new sc_signal<Tspecial_address_t> (rename.c_str());
      in_SPR_WRITE_DATA          [i] = new sc_signal<Tspecial_data_t   > (rename.c_str());
    }

  sc_signal<Tcontext_t        > ** in_BYPASS_WRITE_OOO_ENGINE_ID  = new sc_signal<Tcontext_t        > * [_param->_nb_bypass_write];
  sc_signal<Tcontrol_t        > ** in_BYPASS_WRITE_GPR_VAL        = new sc_signal<Tcontrol_t        > * [_param->_nb_bypass_write];
  sc_signal<Tgeneral_address_t> ** in_BYPASS_WRITE_GPR_NUM_REG    = new sc_signal<Tgeneral_address_t> * [_param->_nb_bypass_write];
  sc_signal<Tgeneral_data_t   > ** in_BYPASS_WRITE_GPR_DATA       = new sc_signal<Tgeneral_data_t   > * [_param->_nb_bypass_write];
  sc_signal<Tcontrol_t        > ** in_BYPASS_WRITE_SPR_VAL        = new sc_signal<Tcontrol_t        > * [_param->_nb_bypass_write];
  sc_signal<Tspecial_address_t> ** in_BYPASS_WRITE_SPR_NUM_REG    = new sc_signal<Tspecial_address_t> * [_param->_nb_bypass_write];
  sc_signal<Tspecial_data_t   > ** in_BYPASS_WRITE_SPR_DATA       = new sc_signal<Tspecial_data_t   > * [_param->_nb_bypass_write];

  for (uint32_t i=0; i<_param->_nb_bypass_write; i++)
    {
      in_BYPASS_WRITE_OOO_ENGINE_ID [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      in_BYPASS_WRITE_GPR_VAL       [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      in_BYPASS_WRITE_GPR_NUM_REG   [i] = new sc_signal<Tgeneral_address_t> (rename.c_str());
      in_BYPASS_WRITE_GPR_DATA      [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
      in_BYPASS_WRITE_SPR_VAL       [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      in_BYPASS_WRITE_SPR_NUM_REG   [i] = new sc_signal<Tspecial_address_t> (rename.c_str());
      in_BYPASS_WRITE_SPR_DATA      [i] = new sc_signal<Tspecial_data_t   > (rename.c_str());
    }
  sc_signal<Tcontrol_t        > ** in_BYPASS_MEMORY_VAL            = new sc_signal<Tcontrol_t        > * [_param->_nb_bypass_memory];
  sc_signal<Tcontext_t        > ** in_BYPASS_MEMORY_OOO_ENGINE_ID  = new sc_signal<Tcontext_t        > * [_param->_nb_bypass_memory];
  sc_signal<Tgeneral_address_t> ** in_BYPASS_MEMORY_NUM_REG        = new sc_signal<Tgeneral_address_t> * [_param->_nb_bypass_memory];
  sc_signal<Tgeneral_data_t   > ** in_BYPASS_MEMORY_DATA           = new sc_signal<Tgeneral_data_t   > * [_param->_nb_bypass_memory];

  for (uint32_t i=0; i<_param->_nb_bypass_memory; i++)
    {
      in_BYPASS_MEMORY_VAL           [i] = new sc_signal<Tcontrol_t        > (rename.c_str());
      in_BYPASS_MEMORY_OOO_ENGINE_ID [i] = new sc_signal<Tcontext_t        > (rename.c_str());
      in_BYPASS_MEMORY_NUM_REG       [i] = new sc_signal<Tgeneral_address_t> (rename.c_str());
      in_BYPASS_MEMORY_DATA          [i] = new sc_signal<Tgeneral_data_t   > (rename.c_str());
    }
    
  /********************************************************
   * Instanciation
   ********************************************************/
  
  cout << "<" << name << "> Instanciation of _Reservation_station" << endl;
  
  (*(_Reservation_station->in_CLOCK))        (*(in_CLOCK));
  (*(_Reservation_station->in_NRESET))       (*(in_NRESET));

  (*(_Reservation_station-> in_INSERT_VAL              )) (*( in_INSERT_VAL              ));
  (*(_Reservation_station->out_INSERT_ACK              )) (*(out_INSERT_ACK              ));
  if (_param->_have_port_context_id)
  (*(_Reservation_station-> in_INSERT_CONTEXT_ID       )) (*( in_INSERT_CONTEXT_ID       ));
  if (_param->_have_port_front_end_id)
  (*(_Reservation_station-> in_INSERT_FRONT_END_ID     )) (*( in_INSERT_FRONT_END_ID     ));
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station-> in_INSERT_OOO_ENGINE_ID    )) (*( in_INSERT_OOO_ENGINE_ID    ));
  if (_param->_have_port_rob_id)
  (*(_Reservation_station-> in_INSERT_ROB_ID           )) (*( in_INSERT_ROB_ID           ));
  (*(_Reservation_station-> in_INSERT_OPERATION        )) (*( in_INSERT_OPERATION        ));
  (*(_Reservation_station-> in_INSERT_TYPE             )) (*( in_INSERT_TYPE             ));
  (*(_Reservation_station-> in_INSERT_HAS_IMMEDIAT     )) (*( in_INSERT_HAS_IMMEDIAT     ));
  (*(_Reservation_station-> in_INSERT_IMMEDIAT         )) (*( in_INSERT_IMMEDIAT         ));
//   (*(_Reservation_station-> in_INSERT_READ_RA          )) (*( in_INSERT_READ_RA          ));
  (*(_Reservation_station-> in_INSERT_NUM_REG_RA       )) (*( in_INSERT_NUM_REG_RA       ));
  (*(_Reservation_station-> in_INSERT_DATA_RA_VAL      )) (*( in_INSERT_DATA_RA_VAL      ));
  (*(_Reservation_station-> in_INSERT_DATA_RA          )) (*( in_INSERT_DATA_RA          ));
//   (*(_Reservation_station-> in_INSERT_READ_RB          )) (*( in_INSERT_READ_RB          ));
  (*(_Reservation_station-> in_INSERT_NUM_REG_RB       )) (*( in_INSERT_NUM_REG_RB       ));
  (*(_Reservation_station-> in_INSERT_DATA_RB_VAL      )) (*( in_INSERT_DATA_RB_VAL      ));
  (*(_Reservation_station-> in_INSERT_DATA_RB          )) (*( in_INSERT_DATA_RB          ));
//   (*(_Reservation_station-> in_INSERT_READ_RC          )) (*( in_INSERT_READ_RC          ));
  (*(_Reservation_station-> in_INSERT_NUM_REG_RC       )) (*( in_INSERT_NUM_REG_RC       ));
  (*(_Reservation_station-> in_INSERT_DATA_RC_VAL      )) (*( in_INSERT_DATA_RC_VAL      ));
  (*(_Reservation_station-> in_INSERT_DATA_RC          )) (*( in_INSERT_DATA_RC          ));
  (*(_Reservation_station-> in_INSERT_WRITE_RD         )) (*( in_INSERT_WRITE_RD         ));
  (*(_Reservation_station-> in_INSERT_NUM_REG_RD       )) (*( in_INSERT_NUM_REG_RD       ));
  (*(_Reservation_station-> in_INSERT_WRITE_RE         )) (*( in_INSERT_WRITE_RE         ));
  (*(_Reservation_station-> in_INSERT_NUM_REG_RE       )) (*( in_INSERT_NUM_REG_RE       ));

    for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
      {
  (*(_Reservation_station->out_RETIRE_VAL            [i])) (*(out_RETIRE_VAL            [i]));
  (*(_Reservation_station-> in_RETIRE_ACK            [i])) (*( in_RETIRE_ACK            [i]));
  if (_param->_have_port_context_id)
  (*(_Reservation_station->out_RETIRE_CONTEXT_ID     [i])) (*(out_RETIRE_CONTEXT_ID     [i]));
  if (_param->_have_port_front_end_id)
  (*(_Reservation_station->out_RETIRE_FRONT_END_ID   [i])) (*(out_RETIRE_FRONT_END_ID   [i]));
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station->out_RETIRE_OOO_ENGINE_ID  [i])) (*(out_RETIRE_OOO_ENGINE_ID  [i]));
  if (_param->_have_port_rob_id)
  (*(_Reservation_station->out_RETIRE_ROB_ID         [i])) (*(out_RETIRE_ROB_ID         [i]));
  (*(_Reservation_station->out_RETIRE_OPERATION      [i])) (*(out_RETIRE_OPERATION      [i]));
  (*(_Reservation_station->out_RETIRE_TYPE           [i])) (*(out_RETIRE_TYPE           [i]));
  (*(_Reservation_station->out_RETIRE_HAS_IMMEDIAT   [i])) (*(out_RETIRE_HAS_IMMEDIAT   [i]));
  (*(_Reservation_station->out_RETIRE_IMMEDIAT       [i])) (*(out_RETIRE_IMMEDIAT       [i]));
  (*(_Reservation_station->out_RETIRE_DATA_RA        [i])) (*(out_RETIRE_DATA_RA        [i]));
  (*(_Reservation_station->out_RETIRE_DATA_RB        [i])) (*(out_RETIRE_DATA_RB        [i]));
  (*(_Reservation_station->out_RETIRE_DATA_RC        [i])) (*(out_RETIRE_DATA_RC        [i]));
  (*(_Reservation_station->out_RETIRE_WRITE_RD       [i])) (*(out_RETIRE_WRITE_RD       [i]));
  (*(_Reservation_station->out_RETIRE_NUM_REG_RD     [i])) (*(out_RETIRE_NUM_REG_RD     [i]));
  (*(_Reservation_station->out_RETIRE_WRITE_RE       [i])) (*(out_RETIRE_WRITE_RE       [i]));
  (*(_Reservation_station->out_RETIRE_NUM_REG_RE     [i])) (*(out_RETIRE_NUM_REG_RE     [i]));
      }
    for (uint32_t i=0; i<_param->_nb_gpr_write; i++)
      {
  (*(_Reservation_station-> in_GPR_WRITE_VAL                        [i])) (*( in_GPR_WRITE_VAL                        [i]));
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station-> in_GPR_WRITE_OOO_ENGINE_ID              [i])) (*( in_GPR_WRITE_OOO_ENGINE_ID              [i]));
  (*(_Reservation_station-> in_GPR_WRITE_NUM_REG                    [i])) (*( in_GPR_WRITE_NUM_REG                    [i]));
  (*(_Reservation_station-> in_GPR_WRITE_DATA                       [i])) (*( in_GPR_WRITE_DATA                       [i]));
      }
    for (uint32_t i=0; i<_param->_nb_spr_write; i++)
      {
  (*(_Reservation_station-> in_SPR_WRITE_VAL                        [i])) (*( in_SPR_WRITE_VAL                        [i]));
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station-> in_SPR_WRITE_OOO_ENGINE_ID              [i])) (*( in_SPR_WRITE_OOO_ENGINE_ID              [i]));
  (*(_Reservation_station-> in_SPR_WRITE_NUM_REG                    [i])) (*( in_SPR_WRITE_NUM_REG                    [i]));
  (*(_Reservation_station-> in_SPR_WRITE_DATA                       [i])) (*( in_SPR_WRITE_DATA                       [i]));
      }
    for (uint32_t i=0; i<_param->_nb_bypass_write; i++)
      {
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station-> in_BYPASS_WRITE_OOO_ENGINE_ID           [i])) (*( in_BYPASS_WRITE_OOO_ENGINE_ID           [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_GPR_VAL                 [i])) (*( in_BYPASS_WRITE_GPR_VAL                 [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_GPR_NUM_REG             [i])) (*( in_BYPASS_WRITE_GPR_NUM_REG             [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_GPR_DATA                [i])) (*( in_BYPASS_WRITE_GPR_DATA                [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_SPR_VAL                 [i])) (*( in_BYPASS_WRITE_SPR_VAL                 [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_SPR_NUM_REG             [i])) (*( in_BYPASS_WRITE_SPR_NUM_REG             [i]));
  (*(_Reservation_station-> in_BYPASS_WRITE_SPR_DATA                [i])) (*( in_BYPASS_WRITE_SPR_DATA                [i]));
      }
    for (uint32_t i=0; i<_param->_nb_bypass_memory; i++)
      {
  (*(_Reservation_station-> in_BYPASS_MEMORY_VAL                    [i])) (*( in_BYPASS_MEMORY_VAL                    [i]));
  if (_param->_have_port_ooo_engine_id)
  (*(_Reservation_station-> in_BYPASS_MEMORY_OOO_ENGINE_ID          [i])) (*( in_BYPASS_MEMORY_OOO_ENGINE_ID          [i]));
  (*(_Reservation_station-> in_BYPASS_MEMORY_NUM_REG                [i])) (*( in_BYPASS_MEMORY_NUM_REG                [i]));
  (*(_Reservation_station-> in_BYPASS_MEMORY_DATA                   [i])) (*( in_BYPASS_MEMORY_DATA                   [i]));
      }

  cout << "<" << name << "> Start Simulation ............" << endl;
  Time * _time = new Time();

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

  // Initialisation

  const uint32_t nb_request = _param->_nb_packet;
  const uint32_t seed = 0;
//const uint32_t seed = static_cast<uint32_t>(time(NULL));
  srand(seed);

  Tcontext_t         _ooo_engine_id [nb_request];
  Tcontrol_t         _read_ra    [nb_request];
  Tgeneral_address_t _num_reg_ra [nb_request];
  Tcontrol_t         _read_rb    [nb_request];
  Tgeneral_address_t _num_reg_rb [nb_request];
  Tcontrol_t         _read_rc    [nb_request];
  Tspecial_address_t _num_reg_rc [nb_request];

  // emulation of registerFile
  Tcontrol_t         _gpr_val    [_param->_nb_general_register][_param->_nb_ooo_engine];
  Tgeneral_data_t    _gpr        [_param->_nb_general_register][_param->_nb_ooo_engine];
  Tcontrol_t         _spr_val    [_param->_nb_special_register][_param->_nb_ooo_engine];
  Tspecial_data_t    _spr        [_param->_nb_special_register][_param->_nb_ooo_engine];

  SC_START(0);

  LABEL("Initialisation");
  in_INSERT_VAL ->write(0);
  for (uint32_t i=0; i<_param->_nb_inst_retire  ; i++)
    in_RETIRE_ACK [i]->write(0);
  for (uint32_t i=0; i<_param->_nb_gpr_write    ; i++)
    in_GPR_WRITE_VAL               [i]->write(0);
  for (uint32_t i=0; i<_param->_nb_spr_write    ; i++)
    in_SPR_WRITE_VAL               [i]->write(0);
  for (uint32_t i=0; i<_param->_nb_bypass_write ; i++)
    {
      in_BYPASS_WRITE_GPR_VAL      [i]->write(0);
      in_BYPASS_WRITE_SPR_VAL      [i]->write(0);
    }
  for (uint32_t i=0; i<_param->_nb_bypass_memory; i++)
    in_BYPASS_MEMORY_VAL           [i]->write(0);

  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 "+toString(iteration));

      int32_t percent_transaction_queue_in     = (rand()%50)+25;
      int32_t percent_transaction_queue_out    = (rand()%50)+25;
      int32_t percent_registerfile_valid       = (rand()%50)+25;
      int32_t percent_transaction_registerfile = (rand()%50)+25;
      int32_t percent_transaction_bypass       = (rand()%50)+25;
      
      LABEL("Initialisation");

      for (uint32_t i=0; i<nb_request; i++)
	{
	  _ooo_engine_id   [i] = rand()% _param->_nb_ooo_engine            ;
	  _read_ra      [i] = rand()% 2                              ;
	  _num_reg_ra   [i] = rand()% _param->_nb_general_register   ;
	  _read_rb      [i] = rand()% 2                              ;
	  _num_reg_rb   [i] = rand()% _param->_nb_general_register   ;
	  _read_rc      [i] = rand()% 2                              ;
	  _num_reg_rc   [i] = rand()% _param->_nb_special_register   ;
	}
      
      // emulation of registerFile
      for (uint32_t j=0; j<_param->_nb_ooo_engine; j++)
	{
	  for (uint32_t i=0; i<_param->_nb_general_register; i++)
	    {
	      _gpr_val      [i][j] = ((rand()%100) < percent_registerfile_valid);
	      _gpr          [i][j] = rand()%((1<<_param->_size_general_data)-1);
	    }
	  for (uint32_t i=0; i<_param->_nb_special_register; i++)
	    {
	      _spr_val      [i][j] = ((rand()%100) < percent_registerfile_valid);
	      _spr          [i][j] = rand()%(1<<_param->_size_special_data);
	    }
	}
      // End initialisation .......

      uint32_t request_in  = 0;
      uint32_t request_out = 0;
      bool     request_out_wait [nb_request];

      for (uint32_t i=0; i<nb_request; i++)
	request_out_wait [i] = true;
      
      bool can_gpr_use [_param->_nb_ooo_engine][_param->_nb_general_register];
      bool can_spr_use [_param->_nb_ooo_engine][_param->_nb_special_register];
      bool need_gpr    [_param->_nb_ooo_engine][_param->_nb_general_register];
      bool need_spr    [_param->_nb_ooo_engine][_param->_nb_special_register];

      
      for (uint32_t j=0; j<_param->_nb_ooo_engine; j++)
	{
	  for (uint32_t i=0; i<_param->_nb_general_register; i++)
	    need_gpr [j][i] = false;
	  for (uint32_t i=0; i<_param->_nb_special_register; i++)
	    need_spr [j][i] = false;
	}

      while (request_out < nb_request)
	{
	  for (uint32_t j=0; j<_param->_nb_ooo_engine; j++)
	    {
	      for (uint32_t i=0; i<_param->_nb_general_register; i++)
		can_gpr_use [j][i] = true;
	      for (uint32_t i=0; i<_param->_nb_special_register; i++)
		can_spr_use [j][i] = true;
	    }

	  Tcontrol_t         insert_val = (request_in < nb_request) and ((rand()%100) < percent_transaction_queue_in);
	  Tcontext_t         insert_ooo_engine_id;
	  Tgeneral_address_t insert_num_reg_ra;
	  Tgeneral_address_t insert_num_reg_rb;
	  Tspecial_address_t insert_num_reg_rc;

	  in_INSERT_VAL         ->write(insert_val);
	  if (insert_val)
	    {
	      bool               data_val;
	      insert_ooo_engine_id = _ooo_engine_id [request_in];
	      insert_num_reg_ra    = _num_reg_ra [request_in];
	      insert_num_reg_rb    = _num_reg_rb [request_in];
	      insert_num_reg_rc    = _num_reg_rc [request_in];

	      if (_param->_have_port_context_id)
              in_INSERT_CONTEXT_ID     ->write((2*insert_ooo_engine_id)%_param->_nb_context  );
	      if (_param->_have_port_front_end_id)
              in_INSERT_FRONT_END_ID   ->write((3*insert_ooo_engine_id)%_param->_nb_front_end);
   	      if (_param->_have_port_ooo_engine_id)
              in_INSERT_OOO_ENGINE_ID  ->write(insert_ooo_engine_id);
   	      if (_param->_have_port_rob_id)
              in_INSERT_ROB_ID      ->write(request_in);
   	      in_INSERT_OPERATION   ->write(0);
   	      in_INSERT_TYPE        ->write(0);
   	      in_INSERT_HAS_IMMEDIAT->write(0);
   	      in_INSERT_IMMEDIAT    ->write(0);
// 	      in_INSERT_READ_RA     ->write(_read_ra[request_in]);
	      data_val = not(_read_ra[request_in]) or _gpr_val[insert_num_reg_ra][insert_ooo_engine_id];

	      need_gpr [insert_ooo_engine_id][insert_num_reg_ra] |= not data_val;

	      in_INSERT_NUM_REG_RA  ->write(insert_num_reg_ra);
   	      in_INSERT_DATA_RA_VAL ->write(data_val);
   	      in_INSERT_DATA_RA     ->write((data_val)?_gpr[insert_num_reg_ra][insert_ooo_engine_id]:0);
// 	      in_INSERT_READ_RB     ->write(_read_rb[request_in]);
	      data_val = not(_read_rb[request_in]) or _gpr_val[insert_num_reg_rb][insert_ooo_engine_id];

	      need_gpr [insert_ooo_engine_id][insert_num_reg_rb] |= not data_val;

   	      in_INSERT_NUM_REG_RB  ->write(insert_num_reg_rb);			       
   	      in_INSERT_DATA_RB_VAL ->write(data_val);			       
   	      in_INSERT_DATA_RB     ->write((data_val)?_gpr[insert_num_reg_rb][insert_ooo_engine_id]:0);
// 	      in_INSERT_READ_RC     ->write(_read_rc[request_in]);
	      data_val = not(_read_rc[request_in]) or _spr_val[insert_num_reg_rc][insert_ooo_engine_id];

	      need_spr [insert_ooo_engine_id][insert_num_reg_rc] |= not data_val;

   	      in_INSERT_NUM_REG_RC  ->write(insert_num_reg_rc);			       
   	      in_INSERT_DATA_RC_VAL ->write(data_val);			       
   	      in_INSERT_DATA_RC     ->write((data_val)?_spr[insert_num_reg_rc][insert_ooo_engine_id]:0);
   	      in_INSERT_WRITE_RD    ->write(0);
   	      in_INSERT_NUM_REG_RD  ->write(0);
   	      in_INSERT_WRITE_RE    ->write(0);
   	      in_INSERT_NUM_REG_RE  ->write(0);

	      can_gpr_use [insert_ooo_engine_id][insert_num_reg_ra] = false;
	      can_gpr_use [insert_ooo_engine_id][insert_num_reg_rb] = false;
	      can_spr_use [insert_ooo_engine_id][insert_num_reg_rc] = false;
	    }
	  	  
	  for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
	    in_RETIRE_ACK[i]->write((rand()%100)<percent_transaction_queue_out);

	  LABEL("Bypass Network :");
	  for (uint32_t i=0; i<_param->_nb_gpr_write; i++)
	    {
	      Tgeneral_address_t num_reg = rand()% _param->_nb_general_register;
	      Tcontext_t         ooo_engine = rand()% _param->_nb_ooo_engine;
	      Tcontrol_t         val     = (_gpr_val [num_reg][ooo_engine]== 0)?((rand()%100) < percent_transaction_registerfile):0;
	      Tgeneral_data_t    data    = rand()%((1<<_param->_size_general_data)-1);
	    
	      val = (val and can_gpr_use [ooo_engine][num_reg] and need_gpr [ooo_engine][num_reg]);

	      in_GPR_WRITE_VAL            [i]->write(val);	      
	      if (_param->_have_port_ooo_engine_id)
              in_GPR_WRITE_OOO_ENGINE_ID  [i]->write(ooo_engine);
	      in_GPR_WRITE_NUM_REG        [i]->write(num_reg);
	      in_GPR_WRITE_DATA           [i]->write(data);

	      if (val)
		{
		  LABEL(" * GPR_WRITE     ["+toString(i)+"] - gpr["+toString(num_reg)+"]["+toString(ooo_engine)+"] <- "+toString(data));
		  can_gpr_use [ooo_engine][num_reg] = false;
		  need_gpr [ooo_engine][num_reg]    = false;


		  _gpr     [num_reg][ooo_engine] = data;
		  _gpr_val [num_reg][ooo_engine] = 1;
		}
	    }
	  for (uint32_t i=0; i<_param->_nb_spr_write; i++)
	    {
	      Tspecial_address_t num_reg = rand()% _param->_nb_special_register;
	      Tcontext_t         ooo_engine = rand()% _param->_nb_ooo_engine;
	      Tcontrol_t         val     = (_spr_val [num_reg][ooo_engine]== 0)?((rand()%100) < percent_transaction_registerfile):0;
	      Tspecial_data_t    data    = rand()%(1<<_param->_size_special_data);

	      val = (val and can_spr_use [ooo_engine][num_reg] and need_spr[ooo_engine][num_reg]);

	      in_SPR_WRITE_VAL            [i]->write(val);	      
	      if (_param->_have_port_ooo_engine_id)
              in_SPR_WRITE_OOO_ENGINE_ID  [i]->write(ooo_engine);
	      in_SPR_WRITE_NUM_REG        [i]->write(num_reg);
	      in_SPR_WRITE_DATA           [i]->write(data);

	      if (val == 1)
		{
		  LABEL(" * SPR_WRITE     ["+toString(i)+"] - spr["+toString(num_reg)+"]["+toString(ooo_engine)+"] <- "+toString(data));
		  can_spr_use [ooo_engine][num_reg] = false;
		  need_spr[ooo_engine][num_reg]     = false;

		  _spr     [num_reg][ooo_engine] = data;
		  _spr_val [num_reg][ooo_engine] = 1;
		}
	    }

	  for (uint32_t i=0; i<_param->_nb_bypass_write; i++)
	    {
	      Tcontext_t         ooo_engine     = rand()% _param->_nb_ooo_engine;
	      if (_param->_have_port_ooo_engine_id)
              in_BYPASS_WRITE_OOO_ENGINE_ID [i]->write(ooo_engine);

	      Tgeneral_address_t gpr_num_reg = rand()% _param->_nb_general_register;
	      Tcontrol_t         gpr_val     = (_gpr_val [gpr_num_reg][ooo_engine]== 0)?((rand()%100) < percent_transaction_bypass):0;
	      Tgeneral_data_t    gpr_data    = rand()%((1<<_param->_size_general_data)-1);
	      
	      gpr_val = (gpr_val and can_gpr_use [ooo_engine][gpr_num_reg] and need_gpr[ooo_engine][gpr_num_reg]);

	      in_BYPASS_WRITE_GPR_VAL    [i]->write(gpr_val);	      
	      in_BYPASS_WRITE_GPR_NUM_REG[i]->write(gpr_num_reg);
	      in_BYPASS_WRITE_GPR_DATA   [i]->write(gpr_data);

	      if (gpr_val)
		{
		  LABEL(" * BYPASS_WRITE  ["+toString(i)+"] - gpr["+toString(gpr_num_reg)+"]["+toString(ooo_engine)+"] <- "+toString(gpr_data));
		  can_gpr_use [ooo_engine][gpr_num_reg] = false;
		  need_gpr[ooo_engine][gpr_num_reg]     = false;

		  _gpr     [gpr_num_reg][ooo_engine] = gpr_data;
		  _gpr_val [gpr_num_reg][ooo_engine] = 1;
		}

	      Tspecial_address_t spr_num_reg = rand()% _param->_nb_special_register;
	      Tcontrol_t         spr_val     = (_spr_val [spr_num_reg][ooo_engine]== 0)?((rand()%100) < percent_transaction_bypass):0;
	      Tspecial_data_t    spr_data    = rand()%(1<<_param->_size_special_data);
	      
	      spr_val = (spr_val and can_spr_use [ooo_engine][spr_num_reg] and need_spr[ooo_engine][spr_num_reg]);

	      in_BYPASS_WRITE_SPR_VAL    [i]->write(spr_val);	      
	      in_BYPASS_WRITE_SPR_NUM_REG[i]->write(spr_num_reg);
	      in_BYPASS_WRITE_SPR_DATA   [i]->write(spr_data);

	      if (spr_val)
		{
		  LABEL(" * BYPASS_WRITE  ["+toString(i)+"] - spr["+toString(spr_num_reg)+"]["+toString(ooo_engine)+"] <- "+toString(spr_data));
		  can_spr_use [ooo_engine][spr_num_reg] = false;
		  need_spr[ooo_engine][spr_num_reg]     = false;

		  _spr     [spr_num_reg][ooo_engine] = spr_data;
		  _spr_val [spr_num_reg][ooo_engine] = 1;
		}

	    }

	  for (uint32_t i=0; i<_param->_nb_bypass_memory; i++)
	    {
	      Tcontext_t         ooo_engine     = rand()% _param->_nb_ooo_engine;
	      if (_param->_have_port_ooo_engine_id)
              in_BYPASS_MEMORY_OOO_ENGINE_ID [i]->write(ooo_engine);

	      Tgeneral_address_t num_reg = rand()% _param->_nb_general_register;
	      Tcontrol_t         val     = (_gpr_val [num_reg][ooo_engine]== 0)?((rand()%100) < percent_transaction_bypass):0;
	      Tgeneral_data_t    data    = rand()%((1<<_param->_size_general_data)-1);
	      
	      val = (val and can_gpr_use [ooo_engine][num_reg] and need_gpr [ooo_engine][num_reg]);

	      in_BYPASS_MEMORY_VAL    [i]->write(val);	      
	      in_BYPASS_MEMORY_NUM_REG[i]->write(num_reg);
	      in_BYPASS_MEMORY_DATA   [i]->write(data);

	      if (val)
		{
		  LABEL(" * BYPASS_MEMORY ["+toString(i)+"] - gpr["+toString(num_reg)+"]["+toString(ooo_engine)+"] <- "+toString(data));
		  can_gpr_use [ooo_engine][num_reg] = false;
		  need_gpr [ooo_engine][num_reg] = false;

		  _gpr     [num_reg][ooo_engine] = data;
		  _gpr_val [num_reg][ooo_engine] = 1;
		}
	    }
	  SC_START(0); // to mealy function
	  
// 	  LABEL("Test     INSERT  : "+toString(in_INSERT_VAL->read())+","+toString(out_INSERT_ACK->read()));
	  if (( in_INSERT_VAL->read() == 1) and
	      (out_INSERT_ACK->read() == 1))
	    {
	      LABEL("Accepted INSERT  number : "+toString(request_in));
	      request_in  ++;
	    }

	  for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
	    {
 	      LABEL("Test     RETIRE "+toString(i)+" : "+toString(out_RETIRE_VAL[i]->read())+","+toString(in_RETIRE_ACK[i]->read()));
	      if ((out_RETIRE_VAL [i]->read() == 1) and
		  ( in_RETIRE_ACK [i]->read() == 1))
		{
		  Tpacket_t  rob_id;
		  if (_param->_have_port_rob_id)
		    rob_id = out_RETIRE_ROB_ID [i]->read();
		  else
		    rob_id = 0;
		  LABEL("Accepted RETIRE ["+toString(i)+"] number : "+toString(rob_id)+", request number : "+toString(request_out));
		  TEST(bool, request_out_wait [rob_id] , true);

		  request_out ++;
		  request_out_wait [rob_id] = false;

		  Tcontext_t ooo_engine_id = _ooo_engine_id [rob_id];
		  
		  if (_param->_have_port_context_id)
		  TEST(Tcontext_t        ,out_RETIRE_CONTEXT_ID   [i]->read(),(2*ooo_engine_id)%_param->_nb_context  );
		  if (_param->_have_port_front_end_id)
		  TEST(Tcontext_t        ,out_RETIRE_FRONT_END_ID [i]->read(),(3*ooo_engine_id)%_param->_nb_front_end);
		  if (_param->_have_port_ooo_engine_id)
		  TEST(Tcontext_t        ,out_RETIRE_OOO_ENGINE_ID[i]->read(),ooo_engine_id);

		  if (_read_ra [rob_id])
		  TEST(Tgeneral_data_t   ,out_RETIRE_DATA_RA   [i]->read(),_gpr[_num_reg_ra[rob_id]][ooo_engine_id]);
		  
		  if (_read_rb [rob_id])
		  TEST(Tgeneral_data_t   ,out_RETIRE_DATA_RB   [i]->read(),_gpr[_num_reg_rb[rob_id]][ooo_engine_id]);
		  
		  if (_read_rc [rob_id])
		  TEST(Tspecial_data_t   ,out_RETIRE_DATA_RC   [i]->read(),_spr[_num_reg_rc[rob_id]][ooo_engine_id]);

// 		  need_gpr [ooo_engine_id][_num_reg_ra[rob_id]]= true;
// 		  need_gpr [ooo_engine_id][_num_reg_rb[rob_id]]= true;
// 		  need_spr [ooo_engine_id][_num_reg_rc[rob_id]]= true;
		}
	    }
	  
	  SC_START(1);	  
	}
    }

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

  TEST_OK ("End of Simulation");
  delete _time;
  cout << "<" << name << "> ............ Stop Simulation" << endl;

  delete     in_CLOCK ;
  delete     in_NRESET;

  delete     in_INSERT_VAL         ;
  delete    out_INSERT_ACK         ;
  if (_param->_have_port_context_id)  
  delete     in_INSERT_CONTEXT_ID  ;
  if (_param->_have_port_front_end_id)  
  delete     in_INSERT_FRONT_END_ID   ;
  if (_param->_have_port_ooo_engine_id)  
  delete     in_INSERT_OOO_ENGINE_ID  ;
  if (_param->_have_port_rob_id)  
  delete     in_INSERT_ROB_ID      ;
  delete     in_INSERT_OPERATION   ;
  delete     in_INSERT_TYPE        ;
  delete     in_INSERT_HAS_IMMEDIAT;
  delete     in_INSERT_IMMEDIAT    ;
//delete     in_INSERT_READ_RA     ;
  delete     in_INSERT_NUM_REG_RA  ;
  delete     in_INSERT_DATA_RA_VAL ;
  delete     in_INSERT_DATA_RA     ;
//delete     in_INSERT_READ_RB     ;
  delete     in_INSERT_NUM_REG_RB  ;
  delete     in_INSERT_DATA_RB_VAL ;
  delete     in_INSERT_DATA_RB     ;
//delete     in_INSERT_READ_RC     ;
  delete     in_INSERT_NUM_REG_RC  ;
  delete     in_INSERT_DATA_RC_VAL ;
  delete     in_INSERT_DATA_RC     ;
  delete     in_INSERT_WRITE_RD    ;
  delete     in_INSERT_NUM_REG_RD  ;
  delete     in_INSERT_WRITE_RE    ;
  delete     in_INSERT_NUM_REG_RE  ;
  
  delete [] out_RETIRE_VAL         ;
  delete []  in_RETIRE_ACK         ;
  if (_param->_have_port_context_id)  
  delete [] out_RETIRE_CONTEXT_ID  ;
  if (_param->_have_port_front_end_id)  
  delete [] out_RETIRE_FRONT_END_ID;
  if (_param->_have_port_ooo_engine_id)  
  delete [] out_RETIRE_OOO_ENGINE_ID  ;
  if (_param->_have_port_rob_id)  
  delete [] out_RETIRE_ROB_ID   ;
  delete [] out_RETIRE_OPERATION   ;
  delete [] out_RETIRE_TYPE        ;
  delete [] out_RETIRE_HAS_IMMEDIAT;
  delete [] out_RETIRE_IMMEDIAT    ;
  delete [] out_RETIRE_DATA_RA     ;
  delete [] out_RETIRE_DATA_RB     ;
  delete [] out_RETIRE_DATA_RC     ;
  delete [] out_RETIRE_WRITE_RD    ;
  delete [] out_RETIRE_NUM_REG_RD  ;
  delete [] out_RETIRE_WRITE_RE    ;
  delete [] out_RETIRE_NUM_REG_RE  ;
  
  delete []  in_GPR_WRITE_VAL       ;
  if (_param->_have_port_ooo_engine_id)  
  delete []  in_GPR_WRITE_OOO_ENGINE_ID;
  delete []  in_GPR_WRITE_NUM_REG   ;
  delete []  in_GPR_WRITE_DATA      ;
  
  delete []  in_SPR_WRITE_VAL       ;
  if (_param->_have_port_ooo_engine_id)  
  delete []  in_SPR_WRITE_OOO_ENGINE_ID;
  delete []  in_SPR_WRITE_NUM_REG   ;
  delete []  in_SPR_WRITE_DATA      ;
  
  if (_param->_have_port_ooo_engine_id)  
  delete []  in_BYPASS_WRITE_OOO_ENGINE_ID ;
  delete []  in_BYPASS_WRITE_GPR_VAL    ;
  delete []  in_BYPASS_WRITE_GPR_NUM_REG;
  delete []  in_BYPASS_WRITE_GPR_DATA   ;
  delete []  in_BYPASS_WRITE_SPR_VAL    ;
  delete []  in_BYPASS_WRITE_SPR_NUM_REG;
  delete []  in_BYPASS_WRITE_SPR_DATA   ;
  
  delete []  in_BYPASS_MEMORY_VAL       ;
  if (_param->_have_port_ooo_engine_id)  
  delete []  in_BYPASS_MEMORY_OOO_ENGINE_ID;
  delete []  in_BYPASS_MEMORY_NUM_REG   ;
  delete []  in_BYPASS_MEMORY_DATA      ;
#endif

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