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

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Register_unit/Register_unit_Glue/SelfTest/include/test.h"
#include "Common/include/Test.h"

#define NB_ITERATION  128
#define CYCLE_MAX     (128*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()); \
  if (cycle_current != cycle)                                           \
    {                                                                   \
      cycle = cycle_current;                                            \
      cout << "##########[ cycle "<< cycle << " ]" << 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_execute_loop::execute_loop::register_unit::register_unit_glue::Parameters * _param)
{
  cout << "<" << name << "> : Simulation SystemC" << endl;

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

  Register_unit_Glue * _Register_unit_Glue = new Register_unit_Glue (name.c_str(),
#ifdef STATISTICS
					     _parameters_statistics,
#endif
					     _param);
  
#ifdef SYSTEMC
  /*********************************************************************
   * Déclarations des signaux
   *********************************************************************/
  sc_clock                         *  in_CLOCK;
  sc_signal<Tcontrol_t>            *  in_NRESET;
  sc_signal<Tcontrol_t>            * out_CONST_0;
  sc_signal<Tcontrol_t>            * out_CONST_1;

  sc_signal<Tcontrol_t        >   **  in_GPR_READ_VAL              ;
  sc_signal<Tcontrol_t        >   ** out_GPR_READ_ACK              ;
  sc_signal<Tcontext_t        >   **  in_GPR_READ_OOO_ENGINE_ID    ;
  sc_signal<Tgeneral_data_t   >   ** out_GPR_READ_DATA             ;
  sc_signal<Tcontrol_t        >   ** out_GPR_READ_DATA_VAL         ;
  sc_signal<Tcontrol_t        >  *** out_GPR_READ_REGISTERFILE_VAL ;
  sc_signal<Tcontrol_t        >  ***  in_GPR_READ_REGISTERFILE_ACK ;
  sc_signal<Tgeneral_data_t   >  ***  in_GPR_READ_REGISTERFILE_DATA;
  sc_signal<Tcontrol_t        >  *** out_GPR_READ_STATUS_VAL       ;
  sc_signal<Tcontrol_t        >  ***  in_GPR_READ_STATUS_ACK       ;
  sc_signal<Tcontrol_t        >  ***  in_GPR_READ_STATUS_DATA_VAL  ;

  sc_signal<Tcontrol_t        >   **  in_SPR_READ_VAL              ;
  sc_signal<Tcontrol_t        >   ** out_SPR_READ_ACK              ;
  sc_signal<Tcontext_t        >   **  in_SPR_READ_OOO_ENGINE_ID    ;
  sc_signal<Tspecial_data_t   >   ** out_SPR_READ_DATA             ;
  sc_signal<Tcontrol_t        >   ** out_SPR_READ_DATA_VAL         ;
  sc_signal<Tcontrol_t        >  *** out_SPR_READ_REGISTERFILE_VAL ;
  sc_signal<Tcontrol_t        >  ***  in_SPR_READ_REGISTERFILE_ACK ;
  sc_signal<Tspecial_data_t   >  ***  in_SPR_READ_REGISTERFILE_DATA;
  sc_signal<Tcontrol_t        >  *** out_SPR_READ_STATUS_VAL       ;
  sc_signal<Tcontrol_t        >  ***  in_SPR_READ_STATUS_ACK       ;
  sc_signal<Tcontrol_t        >  ***  in_SPR_READ_STATUS_DATA_VAL  ;

  sc_signal<Tcontrol_t        >   **  in_GPR_WRITE_VAL             ;
  sc_signal<Tcontrol_t        >   ** out_GPR_WRITE_ACK             ;
  sc_signal<Tcontext_t        >   **  in_GPR_WRITE_OOO_ENGINE_ID   ;
  sc_signal<Tcontrol_t        >  *** out_GPR_WRITE_REGISTERFILE_VAL;
  sc_signal<Tcontrol_t        >  ***  in_GPR_WRITE_REGISTERFILE_ACK;
  sc_signal<Tcontrol_t        >  *** out_GPR_WRITE_STATUS_VAL      ;
  sc_signal<Tcontrol_t        >  ***  in_GPR_WRITE_STATUS_ACK      ;
  
  sc_signal<Tcontrol_t        >   **  in_SPR_WRITE_VAL             ;
  sc_signal<Tcontrol_t        >   ** out_SPR_WRITE_ACK             ;
  sc_signal<Tcontext_t        >   **  in_SPR_WRITE_OOO_ENGINE_ID   ;
  sc_signal<Tcontrol_t        >  *** out_SPR_WRITE_REGISTERFILE_VAL;
  sc_signal<Tcontrol_t        >  ***  in_SPR_WRITE_REGISTERFILE_ACK;
  sc_signal<Tcontrol_t        >  *** out_SPR_WRITE_STATUS_VAL      ;
  sc_signal<Tcontrol_t        >  ***  in_SPR_WRITE_STATUS_ACK      ;

  sc_signal<Tcontrol_t        >  ***  in_INSERT_ROB_VAL                       ;
  sc_signal<Tcontrol_t        >  *** out_INSERT_ROB_ACK                       ;
  sc_signal<Tcontrol_t        >  ***  in_INSERT_ROB_RD_USE                    ;
  sc_signal<Tcontrol_t        >  ***  in_INSERT_ROB_RE_USE                    ;
  sc_signal<Tcontrol_t        >  *** out_INSERT_ROB_GPR_STATUS_VAL            ;
  sc_signal<Tcontrol_t        >  ***  in_INSERT_ROB_GPR_STATUS_ACK            ;
  sc_signal<Tcontrol_t        >  *** out_INSERT_ROB_SPR_STATUS_VAL            ;
  sc_signal<Tcontrol_t        >  ***  in_INSERT_ROB_SPR_STATUS_ACK            ;

  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_VAL                       ;
  sc_signal<Tcontrol_t        >  *** out_RETIRE_ROB_ACK                       ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_RD_OLD_USE                ; 
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_RD_NEW_USE                ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_RE_OLD_USE                ; 
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_RE_NEW_USE                ;
  sc_signal<Tcontrol_t        >  *** out_RETIRE_ROB_GPR_STATUS_NEW_VAL        ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_GPR_STATUS_NEW_ACK        ;
  sc_signal<Tcontrol_t        >  *** out_RETIRE_ROB_GPR_STATUS_OLD_VAL        ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_GPR_STATUS_OLD_ACK        ;
  sc_signal<Tcontrol_t        >  *** out_RETIRE_ROB_SPR_STATUS_NEW_VAL        ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_SPR_STATUS_NEW_ACK        ;
  sc_signal<Tcontrol_t        >  *** out_RETIRE_ROB_SPR_STATUS_OLD_VAL        ;
  sc_signal<Tcontrol_t        >  ***  in_RETIRE_ROB_SPR_STATUS_OLD_ACK        ;

  string rename;

   in_CLOCK                               = new sc_clock ("clock", 1.0, 0.5);
   in_NRESET                              = new sc_signal<Tcontrol_t> ("NRESET");
  out_CONST_0                             = new sc_signal<Tcontrol_t> ("CONST_0");
  out_CONST_1                             = new sc_signal<Tcontrol_t> ("CONST_1");

    // ~~~~~[ Interface "gpr_read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   in_GPR_READ_VAL               = new sc_signal<Tcontrol_t     >   * [_param->_nb_gpr_read];
  out_GPR_READ_ACK               = new sc_signal<Tcontrol_t     >   * [_param->_nb_gpr_read];
   in_GPR_READ_OOO_ENGINE_ID     = new sc_signal<Tcontext_t     >   * [_param->_nb_gpr_read];
  out_GPR_READ_DATA              = new sc_signal<Tgeneral_data_t>   * [_param->_nb_gpr_read];
  out_GPR_READ_DATA_VAL          = new sc_signal<Tcontrol_t     >   * [_param->_nb_gpr_read];
  out_GPR_READ_REGISTERFILE_VAL  = new sc_signal<Tcontrol_t     >  ** [_param->_nb_ooo_engine];
   in_GPR_READ_REGISTERFILE_ACK  = new sc_signal<Tcontrol_t     >  ** [_param->_nb_ooo_engine];
   in_GPR_READ_REGISTERFILE_DATA = new sc_signal<Tgeneral_data_t>  ** [_param->_nb_ooo_engine];
  out_GPR_READ_STATUS_VAL        = new sc_signal<Tcontrol_t     >  ** [_param->_nb_ooo_engine];
   in_GPR_READ_STATUS_ACK        = new sc_signal<Tcontrol_t     >  ** [_param->_nb_ooo_engine];
   in_GPR_READ_STATUS_DATA_VAL   = new sc_signal<Tcontrol_t     >  ** [_param->_nb_ooo_engine];

   for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
     {
       out_GPR_READ_REGISTERFILE_VAL  [i] = new sc_signal<Tcontrol_t     >  * [_param->_nb_gpr_read];
        in_GPR_READ_REGISTERFILE_ACK  [i] = new sc_signal<Tcontrol_t     >  * [_param->_nb_gpr_read];
        in_GPR_READ_REGISTERFILE_DATA [i] = new sc_signal<Tgeneral_data_t>  * [_param->_nb_gpr_read];
       out_GPR_READ_STATUS_VAL        [i] = new sc_signal<Tcontrol_t     >  * [_param->_nb_gpr_read];
        in_GPR_READ_STATUS_ACK        [i] = new sc_signal<Tcontrol_t     >  * [_param->_nb_gpr_read];
        in_GPR_READ_STATUS_DATA_VAL   [i] = new sc_signal<Tcontrol_t     >  * [_param->_nb_gpr_read];
     }

   for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
     {
        in_GPR_READ_VAL           [j] =  new sc_signal<Tcontrol_t     > (rename.c_str());
       out_GPR_READ_ACK           [j] =  new sc_signal<Tcontrol_t     > (rename.c_str());
        in_GPR_READ_OOO_ENGINE_ID [j] =  new sc_signal<Tcontext_t     > (rename.c_str());
       out_GPR_READ_DATA          [j] =  new sc_signal<Tgeneral_data_t> (rename.c_str());
       out_GPR_READ_DATA_VAL      [j] =  new sc_signal<Tcontrol_t     > (rename.c_str());

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	     out_GPR_READ_REGISTERFILE_VAL  [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_GPR_READ_REGISTERFILE_ACK  [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_GPR_READ_REGISTERFILE_DATA [i][j] = new sc_signal<Tgeneral_data_t> (rename.c_str());
	     out_GPR_READ_STATUS_VAL        [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_GPR_READ_STATUS_ACK        [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_GPR_READ_STATUS_DATA_VAL   [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	 }
     }

    // ~~~~~[ Interface "spr_read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   in_SPR_READ_VAL               = new sc_signal<Tcontrol_t     >  * [_param->_nb_spr_read];
  out_SPR_READ_ACK               = new sc_signal<Tcontrol_t     >  * [_param->_nb_spr_read];
   in_SPR_READ_OOO_ENGINE_ID     = new sc_signal<Tcontext_t     >  * [_param->_nb_spr_read];
  out_SPR_READ_DATA              = new sc_signal<Tspecial_data_t>  * [_param->_nb_spr_read];
  out_SPR_READ_DATA_VAL          = new sc_signal<Tcontrol_t     >  * [_param->_nb_spr_read];
  out_SPR_READ_REGISTERFILE_VAL  = new sc_signal<Tcontrol_t     > ** [_param->_nb_ooo_engine];
   in_SPR_READ_REGISTERFILE_ACK  = new sc_signal<Tcontrol_t     > ** [_param->_nb_ooo_engine];
   in_SPR_READ_REGISTERFILE_DATA = new sc_signal<Tspecial_data_t> ** [_param->_nb_ooo_engine];
  out_SPR_READ_STATUS_VAL        = new sc_signal<Tcontrol_t     > ** [_param->_nb_ooo_engine];
   in_SPR_READ_STATUS_ACK        = new sc_signal<Tcontrol_t     > ** [_param->_nb_ooo_engine];
   in_SPR_READ_STATUS_DATA_VAL   = new sc_signal<Tcontrol_t     > ** [_param->_nb_ooo_engine];

   for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
     {
       out_SPR_READ_REGISTERFILE_VAL  [i] = new sc_signal<Tcontrol_t     > * [_param->_nb_spr_read];
        in_SPR_READ_REGISTERFILE_ACK  [i] = new sc_signal<Tcontrol_t     > * [_param->_nb_spr_read];
        in_SPR_READ_REGISTERFILE_DATA [i] = new sc_signal<Tspecial_data_t> * [_param->_nb_spr_read];
       out_SPR_READ_STATUS_VAL        [i] = new sc_signal<Tcontrol_t     > * [_param->_nb_spr_read];
        in_SPR_READ_STATUS_ACK        [i] = new sc_signal<Tcontrol_t     > * [_param->_nb_spr_read];
        in_SPR_READ_STATUS_DATA_VAL   [i] = new sc_signal<Tcontrol_t     > * [_param->_nb_spr_read];
     }

   for (uint32_t j=0; j<_param->_nb_spr_read; j++)
     {
        in_SPR_READ_VAL           [j] = new sc_signal<Tcontrol_t     > (rename.c_str());
       out_SPR_READ_ACK           [j] = new sc_signal<Tcontrol_t     > (rename.c_str());
        in_SPR_READ_OOO_ENGINE_ID [j] = new sc_signal<Tcontext_t     > (rename.c_str());
       out_SPR_READ_DATA          [j] = new sc_signal<Tspecial_data_t> (rename.c_str());
       out_SPR_READ_DATA_VAL      [j] = new sc_signal<Tcontrol_t     > (rename.c_str());

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	     out_SPR_READ_REGISTERFILE_VAL  [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_SPR_READ_REGISTERFILE_ACK  [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_SPR_READ_REGISTERFILE_DATA [i][j] = new sc_signal<Tspecial_data_t> (rename.c_str());
	     out_SPR_READ_STATUS_VAL        [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_SPR_READ_STATUS_ACK        [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	      in_SPR_READ_STATUS_DATA_VAL   [i][j] = new sc_signal<Tcontrol_t     > (rename.c_str());
	 }
     }

    // ~~~~~[ Interface "gpr_write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   in_GPR_WRITE_VAL               = new sc_signal<Tcontrol_t>  * [_param->_nb_gpr_write];
  out_GPR_WRITE_ACK               = new sc_signal<Tcontrol_t>  * [_param->_nb_gpr_write];
   in_GPR_WRITE_OOO_ENGINE_ID     = new sc_signal<Tcontext_t>  * [_param->_nb_gpr_write];
  out_GPR_WRITE_REGISTERFILE_VAL  = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   in_GPR_WRITE_REGISTERFILE_ACK  = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
  out_GPR_WRITE_STATUS_VAL        = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   in_GPR_WRITE_STATUS_ACK        = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];

   for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
     {
       out_GPR_WRITE_REGISTERFILE_VAL  [i] = new sc_signal<Tcontrol_t> * [_param->_nb_gpr_write];
        in_GPR_WRITE_REGISTERFILE_ACK  [i] = new sc_signal<Tcontrol_t> * [_param->_nb_gpr_write];
       out_GPR_WRITE_STATUS_VAL        [i] = new sc_signal<Tcontrol_t> * [_param->_nb_gpr_write];
        in_GPR_WRITE_STATUS_ACK        [i] = new sc_signal<Tcontrol_t> * [_param->_nb_gpr_write];
     }

   for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
     {
        in_GPR_WRITE_VAL           [j] = new sc_signal<Tcontrol_t> (rename.c_str());
       out_GPR_WRITE_ACK           [j] = new sc_signal<Tcontrol_t> (rename.c_str());
        in_GPR_WRITE_OOO_ENGINE_ID [j] = new sc_signal<Tcontext_t> (rename.c_str());

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	     out_GPR_WRITE_REGISTERFILE_VAL  [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());;
	      in_GPR_WRITE_REGISTERFILE_ACK  [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());;
	     out_GPR_WRITE_STATUS_VAL        [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());;
	      in_GPR_WRITE_STATUS_ACK        [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());;
	 }
     }

    // ~~~~~[ Interface "spr_write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   in_SPR_WRITE_VAL               = new sc_signal<Tcontrol_t>   * [_param->_nb_spr_write];
  out_SPR_WRITE_ACK               = new sc_signal<Tcontrol_t>   * [_param->_nb_spr_write];
   in_SPR_WRITE_OOO_ENGINE_ID     = new sc_signal<Tcontext_t>   * [_param->_nb_spr_write];
  out_SPR_WRITE_REGISTERFILE_VAL  = new sc_signal<Tcontrol_t>  ** [_param->_nb_ooo_engine];
   in_SPR_WRITE_REGISTERFILE_ACK  = new sc_signal<Tcontrol_t>  ** [_param->_nb_ooo_engine];
  out_SPR_WRITE_STATUS_VAL        = new sc_signal<Tcontrol_t>  ** [_param->_nb_ooo_engine];
   in_SPR_WRITE_STATUS_ACK        = new sc_signal<Tcontrol_t>  ** [_param->_nb_ooo_engine];

   for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
     {
       out_SPR_WRITE_REGISTERFILE_VAL  [i] = new sc_signal<Tcontrol_t> * [_param->_nb_spr_write];
        in_SPR_WRITE_REGISTERFILE_ACK  [i] = new sc_signal<Tcontrol_t> * [_param->_nb_spr_write];
       out_SPR_WRITE_STATUS_VAL        [i] = new sc_signal<Tcontrol_t> * [_param->_nb_spr_write];
        in_SPR_WRITE_STATUS_ACK        [i] = new sc_signal<Tcontrol_t> * [_param->_nb_spr_write];
     }

   for (uint32_t j=0; j<_param->_nb_spr_write; j++)
     {
        in_SPR_WRITE_VAL           [j] = new sc_signal<Tcontrol_t> (rename.c_str());
       out_SPR_WRITE_ACK           [j] = new sc_signal<Tcontrol_t> (rename.c_str());
        in_SPR_WRITE_OOO_ENGINE_ID [j] = new sc_signal<Tcontext_t> (rename.c_str());

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	     out_SPR_WRITE_REGISTERFILE_VAL  [i][j] = new sc_signal<Tcontrol_t>  (rename.c_str());
	      in_SPR_WRITE_REGISTERFILE_ACK  [i][j] = new sc_signal<Tcontrol_t>  (rename.c_str());
	     out_SPR_WRITE_STATUS_VAL        [i][j] = new sc_signal<Tcontrol_t>  (rename.c_str());
	      in_SPR_WRITE_STATUS_ACK        [i][j] = new sc_signal<Tcontrol_t>  (rename.c_str());
	 }
     }

   // ~~~~~[ Interface "insert_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    in_INSERT_ROB_VAL                  = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_INSERT_ROB_ACK                  = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_INSERT_ROB_RD_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_INSERT_ROB_RE_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_INSERT_ROB_GPR_STATUS_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_INSERT_ROB_GPR_STATUS_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_INSERT_ROB_SPR_STATUS_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_INSERT_ROB_SPR_STATUS_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];

    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	uint32_t x=_param->_nb_inst_insert_rob [i];

	in_INSERT_ROB_VAL                  [i] = new sc_signal<Tcontrol_t> * [x];
       out_INSERT_ROB_ACK                  [i] = new sc_signal<Tcontrol_t> * [x];
	in_INSERT_ROB_RD_USE               [i] = new sc_signal<Tcontrol_t> * [x];
	in_INSERT_ROB_RE_USE               [i] = new sc_signal<Tcontrol_t> * [x];
       out_INSERT_ROB_GPR_STATUS_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	in_INSERT_ROB_GPR_STATUS_ACK       [i] = new sc_signal<Tcontrol_t> * [x];
       out_INSERT_ROB_SPR_STATUS_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	in_INSERT_ROB_SPR_STATUS_ACK       [i] = new sc_signal<Tcontrol_t> * [x];

	for (uint32_t j=0; j<x; j++)
	  {
	       in_INSERT_ROB_VAL                  [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_INSERT_ROB_ACK                  [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_INSERT_ROB_RD_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_INSERT_ROB_RE_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_INSERT_ROB_GPR_STATUS_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_INSERT_ROB_GPR_STATUS_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_INSERT_ROB_SPR_STATUS_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_INSERT_ROB_SPR_STATUS_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	  }
      }

    // ~~~~~[ Interface "retire_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    in_RETIRE_ROB_VAL                      = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_RETIRE_ROB_ACK                      = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_RD_OLD_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_RD_NEW_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_RE_OLD_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_RE_NEW_USE               = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_RETIRE_ROB_GPR_STATUS_OLD_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_RETIRE_ROB_GPR_STATUS_NEW_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_GPR_STATUS_OLD_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_GPR_STATUS_NEW_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_RETIRE_ROB_SPR_STATUS_OLD_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
   out_RETIRE_ROB_SPR_STATUS_NEW_VAL       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_SPR_STATUS_OLD_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];
    in_RETIRE_ROB_SPR_STATUS_NEW_ACK       = new sc_signal<Tcontrol_t> ** [_param->_nb_ooo_engine];

    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	uint32_t x=_param->_nb_inst_retire_rob [i];

	 in_RETIRE_ROB_VAL                      [i] = new sc_signal<Tcontrol_t> * [x];
	out_RETIRE_ROB_ACK                      [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_RD_OLD_USE               [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_RD_NEW_USE               [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_RE_OLD_USE               [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_RE_NEW_USE               [i] = new sc_signal<Tcontrol_t> * [x];
	out_RETIRE_ROB_GPR_STATUS_OLD_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	out_RETIRE_ROB_GPR_STATUS_NEW_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_GPR_STATUS_OLD_ACK       [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_GPR_STATUS_NEW_ACK       [i] = new sc_signal<Tcontrol_t> * [x];
	out_RETIRE_ROB_SPR_STATUS_OLD_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	out_RETIRE_ROB_SPR_STATUS_NEW_VAL       [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_SPR_STATUS_OLD_ACK       [i] = new sc_signal<Tcontrol_t> * [x];
	 in_RETIRE_ROB_SPR_STATUS_NEW_ACK       [i] = new sc_signal<Tcontrol_t> * [x];
    
	for (uint32_t j=0; j<x; j++)
	  {
	       in_RETIRE_ROB_VAL                      [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_RETIRE_ROB_ACK                      [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_RD_OLD_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_RD_NEW_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_RE_OLD_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_RE_NEW_USE               [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_RETIRE_ROB_GPR_STATUS_OLD_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_GPR_STATUS_OLD_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_RETIRE_ROB_GPR_STATUS_NEW_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_GPR_STATUS_NEW_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_RETIRE_ROB_SPR_STATUS_OLD_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_SPR_STATUS_OLD_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	      out_RETIRE_ROB_SPR_STATUS_NEW_VAL       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	       in_RETIRE_ROB_SPR_STATUS_NEW_ACK       [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	    }
      }
   

  
  /********************************************************
   * Instanciation
   ********************************************************/
  
  cout << "<" << name << "> Instanciation of _Register_unit_Glue" << endl;
  
  (*(_Register_unit_Glue-> in_CLOCK  ))       (*( in_CLOCK  ));
  (*(_Register_unit_Glue-> in_NRESET ))       (*( in_NRESET ));
  (*(_Register_unit_Glue->out_CONST_0))       (*(out_CONST_0));
  (*(_Register_unit_Glue->out_CONST_1))       (*(out_CONST_1));

   for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
     {
       (*(_Register_unit_Glue-> in_GPR_READ_VAL           [j]))(*( in_GPR_READ_VAL           [j]));
       (*(_Register_unit_Glue->out_GPR_READ_ACK           [j]))(*(out_GPR_READ_ACK           [j]));
       if (_param->_have_port_ooo_engine_id == true)
       (*(_Register_unit_Glue-> in_GPR_READ_OOO_ENGINE_ID [j]))(*( in_GPR_READ_OOO_ENGINE_ID [j]));
       (*(_Register_unit_Glue->out_GPR_READ_DATA          [j]))(*(out_GPR_READ_DATA          [j]));
       (*(_Register_unit_Glue->out_GPR_READ_DATA_VAL      [j]))(*(out_GPR_READ_DATA_VAL      [j]));

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	   (*(_Register_unit_Glue->out_GPR_READ_REGISTERFILE_VAL  [i][j]))(*(out_GPR_READ_REGISTERFILE_VAL  [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_READ_REGISTERFILE_ACK  [i][j]))(*( in_GPR_READ_REGISTERFILE_ACK  [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_READ_REGISTERFILE_DATA [i][j]))(*( in_GPR_READ_REGISTERFILE_DATA [i][j]));
	   (*(_Register_unit_Glue->out_GPR_READ_STATUS_VAL        [i][j]))(*(out_GPR_READ_STATUS_VAL        [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_READ_STATUS_ACK        [i][j]))(*( in_GPR_READ_STATUS_ACK        [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_READ_STATUS_DATA_VAL   [i][j]))(*( in_GPR_READ_STATUS_DATA_VAL   [i][j]));
	 }
     }

   for (uint32_t j=0; j<_param->_nb_spr_read; j++)
     {
       (*(_Register_unit_Glue-> in_SPR_READ_VAL           [j]))(*( in_SPR_READ_VAL           [j]));
       (*(_Register_unit_Glue->out_SPR_READ_ACK           [j]))(*(out_SPR_READ_ACK           [j]));
       if (_param->_have_port_ooo_engine_id == true)
       (*(_Register_unit_Glue-> in_SPR_READ_OOO_ENGINE_ID [j]))(*( in_SPR_READ_OOO_ENGINE_ID [j]));
       (*(_Register_unit_Glue->out_SPR_READ_DATA          [j]))(*(out_SPR_READ_DATA          [j]));
       (*(_Register_unit_Glue->out_SPR_READ_DATA_VAL      [j]))(*(out_SPR_READ_DATA_VAL      [j]));

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	   (*(_Register_unit_Glue->out_SPR_READ_REGISTERFILE_VAL  [i][j]))(*(out_SPR_READ_REGISTERFILE_VAL  [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_READ_REGISTERFILE_ACK  [i][j]))(*( in_SPR_READ_REGISTERFILE_ACK  [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_READ_REGISTERFILE_DATA [i][j]))(*( in_SPR_READ_REGISTERFILE_DATA [i][j]));
	   (*(_Register_unit_Glue->out_SPR_READ_STATUS_VAL        [i][j]))(*(out_SPR_READ_STATUS_VAL        [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_READ_STATUS_ACK        [i][j]))(*( in_SPR_READ_STATUS_ACK        [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_READ_STATUS_DATA_VAL   [i][j]))(*( in_SPR_READ_STATUS_DATA_VAL   [i][j]));
	 }
     }

   for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
     {
       (*(_Register_unit_Glue-> in_GPR_WRITE_VAL           [j]))(*( in_GPR_WRITE_VAL           [j]));
       (*(_Register_unit_Glue->out_GPR_WRITE_ACK           [j]))(*(out_GPR_WRITE_ACK           [j]));
       if (_param->_have_port_ooo_engine_id == true)
       (*(_Register_unit_Glue-> in_GPR_WRITE_OOO_ENGINE_ID [j]))(*( in_GPR_WRITE_OOO_ENGINE_ID [j]));

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	   (*(_Register_unit_Glue->out_GPR_WRITE_REGISTERFILE_VAL  [i][j]))(*(out_GPR_WRITE_REGISTERFILE_VAL  [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_WRITE_REGISTERFILE_ACK  [i][j]))(*( in_GPR_WRITE_REGISTERFILE_ACK  [i][j]));
	   (*(_Register_unit_Glue->out_GPR_WRITE_STATUS_VAL        [i][j]))(*(out_GPR_WRITE_STATUS_VAL        [i][j]));
	   (*(_Register_unit_Glue-> in_GPR_WRITE_STATUS_ACK        [i][j]))(*( in_GPR_WRITE_STATUS_ACK        [i][j]));
	 }
     }

   for (uint32_t j=0; j<_param->_nb_spr_write; j++)
     {
       (*(_Register_unit_Glue-> in_SPR_WRITE_VAL           [j]))(*( in_SPR_WRITE_VAL           [j]));
       (*(_Register_unit_Glue->out_SPR_WRITE_ACK           [j]))(*(out_SPR_WRITE_ACK           [j]));
       if (_param->_have_port_ooo_engine_id == true)
       (*(_Register_unit_Glue-> in_SPR_WRITE_OOO_ENGINE_ID [j]))(*( in_SPR_WRITE_OOO_ENGINE_ID [j]));

       for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	 {
	   (*(_Register_unit_Glue->out_SPR_WRITE_REGISTERFILE_VAL  [i][j]))(*(out_SPR_WRITE_REGISTERFILE_VAL  [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_WRITE_REGISTERFILE_ACK  [i][j]))(*( in_SPR_WRITE_REGISTERFILE_ACK  [i][j]));
	   (*(_Register_unit_Glue->out_SPR_WRITE_STATUS_VAL        [i][j]))(*(out_SPR_WRITE_STATUS_VAL        [i][j]));
	   (*(_Register_unit_Glue-> in_SPR_WRITE_STATUS_ACK        [i][j]))(*( in_SPR_WRITE_STATUS_ACK        [i][j]));
	 }
     }

   // ~~~~~[ Interface "insert_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	uint32_t x=_param->_nb_inst_insert_rob [i];

	for (uint32_t j=0; j<x; j++)
	  {
	    (*(_Register_unit_Glue-> in_INSERT_ROB_VAL            [i][j]))  (*( in_INSERT_ROB_VAL            [i][j]));
	    (*(_Register_unit_Glue->out_INSERT_ROB_ACK            [i][j]))  (*(out_INSERT_ROB_ACK            [i][j]));
	    (*(_Register_unit_Glue-> in_INSERT_ROB_RD_USE         [i][j]))  (*( in_INSERT_ROB_RD_USE         [i][j]));
	    (*(_Register_unit_Glue-> in_INSERT_ROB_RE_USE         [i][j]))  (*( in_INSERT_ROB_RE_USE         [i][j]));
	    (*(_Register_unit_Glue->out_INSERT_ROB_GPR_STATUS_VAL [i][j]))  (*(out_INSERT_ROB_GPR_STATUS_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_INSERT_ROB_GPR_STATUS_ACK [i][j]))  (*( in_INSERT_ROB_GPR_STATUS_ACK [i][j]));
	    (*(_Register_unit_Glue->out_INSERT_ROB_SPR_STATUS_VAL [i][j]))  (*(out_INSERT_ROB_SPR_STATUS_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_INSERT_ROB_SPR_STATUS_ACK [i][j]))  (*( in_INSERT_ROB_SPR_STATUS_ACK [i][j]));
	  }
      }

    // ~~~~~[ Interface "retire_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	uint32_t x=_param->_nb_inst_retire_rob [i];

	for (uint32_t j=0; j<x; j++)
	  {
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_VAL                [i][j]))(*( in_RETIRE_ROB_VAL                [i][j]));
	    (*(_Register_unit_Glue->out_RETIRE_ROB_ACK                [i][j]))(*(out_RETIRE_ROB_ACK                [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_RD_OLD_USE         [i][j]))(*( in_RETIRE_ROB_RD_OLD_USE         [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_RD_NEW_USE         [i][j]))(*( in_RETIRE_ROB_RD_NEW_USE         [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_RE_OLD_USE         [i][j]))(*( in_RETIRE_ROB_RE_OLD_USE         [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_RE_NEW_USE         [i][j]))(*( in_RETIRE_ROB_RE_NEW_USE         [i][j]));
	    (*(_Register_unit_Glue->out_RETIRE_ROB_GPR_STATUS_OLD_VAL [i][j]))(*(out_RETIRE_ROB_GPR_STATUS_OLD_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_GPR_STATUS_OLD_ACK [i][j]))(*( in_RETIRE_ROB_GPR_STATUS_OLD_ACK [i][j]));
	    (*(_Register_unit_Glue->out_RETIRE_ROB_GPR_STATUS_NEW_VAL [i][j]))(*(out_RETIRE_ROB_GPR_STATUS_NEW_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_GPR_STATUS_NEW_ACK [i][j]))(*( in_RETIRE_ROB_GPR_STATUS_NEW_ACK [i][j]));
	    (*(_Register_unit_Glue->out_RETIRE_ROB_SPR_STATUS_OLD_VAL [i][j]))(*(out_RETIRE_ROB_SPR_STATUS_OLD_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_SPR_STATUS_OLD_ACK [i][j]))(*( in_RETIRE_ROB_SPR_STATUS_OLD_ACK [i][j]));
	    (*(_Register_unit_Glue->out_RETIRE_ROB_SPR_STATUS_NEW_VAL [i][j]))(*(out_RETIRE_ROB_SPR_STATUS_NEW_VAL [i][j]));
	    (*(_Register_unit_Glue-> in_RETIRE_ROB_SPR_STATUS_NEW_ACK [i][j]))(*( in_RETIRE_ROB_SPR_STATUS_NEW_ACK [i][j]));
	    }
      }
   
  cout << "<" << name << "> Start Simulation ............" << endl;
  Time * _time = new Time();

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

  // Initialisation
  const bool     test_read   = true;
  const bool     test_write  = true;
  const bool     test_insert = true;
  const bool     test_retire = true;

  const  int32_t percent_transaction = 75;

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

  srand(seed);

  Tcontext_t      context;
  Tcontrol_t      gpr_read_ack              [_param->_nb_gpr_read];
  Tgeneral_data_t gpr_read_data             [_param->_nb_gpr_read];
  Tcontrol_t      gpr_read_data_val         [_param->_nb_gpr_read];
  Tcontrol_t      gpr_read_registerfile_val [_param->_nb_ooo_engine][_param->_nb_gpr_read];
  Tcontrol_t      gpr_read_status_val       [_param->_nb_ooo_engine][_param->_nb_gpr_read];

  Tcontrol_t      gpr_write_ack              [_param->_nb_gpr_write];
  Tcontrol_t      gpr_write_registerfile_val [_param->_nb_ooo_engine][_param->_nb_gpr_write];
  Tcontrol_t      gpr_write_status_val       [_param->_nb_ooo_engine][_param->_nb_gpr_write];

  Tcontrol_t      spr_read_ack              [_param->_nb_spr_read];
  Tspecial_data_t spr_read_data             [_param->_nb_spr_read];
  Tcontrol_t      spr_read_data_val         [_param->_nb_spr_read];
  Tcontrol_t      spr_read_registerfile_val [_param->_nb_ooo_engine][_param->_nb_spr_read];
  Tcontrol_t      spr_read_status_val       [_param->_nb_ooo_engine][_param->_nb_spr_read];

  Tcontrol_t      spr_write_ack              [_param->_nb_spr_write];
  Tcontrol_t      spr_write_registerfile_val [_param->_nb_ooo_engine][_param->_nb_spr_write];
  Tcontrol_t      spr_write_status_val       [_param->_nb_ooo_engine][_param->_nb_spr_write];

  uint32_t        max_nb_inst_retire_rob = 0;

  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
    if (_param->_nb_inst_retire_rob [i] > max_nb_inst_retire_rob)
      max_nb_inst_retire_rob = _param->_nb_inst_retire_rob [i];

  Tcontrol_t      retire_rob_ack                [_param->_nb_ooo_engine][max_nb_inst_retire_rob];
  Tcontrol_t      retire_rob_gpr_status_new_val [_param->_nb_ooo_engine][max_nb_inst_retire_rob];
  Tcontrol_t      retire_rob_gpr_status_old_val [_param->_nb_ooo_engine][max_nb_inst_retire_rob];
  Tcontrol_t      retire_rob_spr_status_new_val [_param->_nb_ooo_engine][max_nb_inst_retire_rob];
  Tcontrol_t      retire_rob_spr_status_old_val [_param->_nb_ooo_engine][max_nb_inst_retire_rob];

  uint32_t        max_nb_inst_insert_rob = 0;

  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
    if (_param->_nb_inst_insert_rob [i] > max_nb_inst_insert_rob)
      max_nb_inst_insert_rob = _param->_nb_inst_insert_rob [i];

  Tcontrol_t      insert_rob_ack            [_param->_nb_ooo_engine][max_nb_inst_insert_rob];
  Tcontrol_t      insert_rob_gpr_status_val [_param->_nb_ooo_engine][max_nb_inst_insert_rob];
  Tcontrol_t      insert_rob_spr_status_val [_param->_nb_ooo_engine][max_nb_inst_insert_rob];

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

  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));

      if (test_read == true)
	{
	  for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	    {
	      context = (rand())%_param->_nb_ooo_engine;
	      Tcontrol_t      val = (rand()%100)<=percent_transaction;
	      
	      LABEL("GPR_READ  ["+toString(j)+"] : "+toString(val)+" - " +toString(static_cast<uint32_t>(context)));
	      
	      in_GPR_READ_VAL           [j] ->write(val);
	      in_GPR_READ_OOO_ENGINE_ID [j] ->write(context);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  Tcontrol_t      registerfile_ack  = (rand()%100)<=percent_transaction  ;
		  Tgeneral_data_t registerfile_data = (rand()%_param->_size_general_data);
		  Tcontrol_t      status_ack        = (rand()%100)<=percent_transaction  ;
		  Tcontrol_t      status_data_val   = (rand()%100)<=percent_transaction  ;
		  
		  in_GPR_READ_REGISTERFILE_ACK  [i][j]->write(registerfile_ack );
		  in_GPR_READ_REGISTERFILE_DATA [i][j]->write(registerfile_data);
		  in_GPR_READ_STATUS_ACK        [i][j]->write(status_ack       );
		  in_GPR_READ_STATUS_DATA_VAL   [i][j]->write(status_data_val  );
		  
		  if (i == context)
		    {
		      gpr_read_registerfile_val [i][j] = val and status_ack      ;
		      gpr_read_status_val       [i][j] = val and registerfile_ack;
		      
		      gpr_read_ack      [j] = registerfile_ack and status_ack;
		      gpr_read_data     [j] = registerfile_data;
		      gpr_read_data_val [j] = status_data_val;
		    }
		  else
		    {
		      gpr_read_registerfile_val [i][j] = 0;
		      gpr_read_status_val       [i][j] = 0;
		    }
		}
	    }

	  for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	    {
	      context = (rand())%_param->_nb_ooo_engine;
	      Tcontrol_t      val = (rand()%100)<=percent_transaction;
	      
	      LABEL("SPR_READ  ["+toString(j)+"] : "+toString(val)+" - " +toString(static_cast<uint32_t>(context)));
	      
	      in_SPR_READ_VAL           [j] ->write(val);
	      in_SPR_READ_OOO_ENGINE_ID [j] ->write(context);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  Tcontrol_t      registerfile_ack  = (rand()%100)<=percent_transaction  ;
		  Tspecial_data_t registerfile_data = (rand()%_param->_size_special_data);
		  Tcontrol_t      status_ack        = (rand()%100)<=percent_transaction  ;
		  Tcontrol_t      status_data_val   = (rand()%100)<=percent_transaction  ;
		  
		  in_SPR_READ_REGISTERFILE_ACK  [i][j]->write(registerfile_ack );
		  in_SPR_READ_REGISTERFILE_DATA [i][j]->write(registerfile_data);
		  in_SPR_READ_STATUS_ACK        [i][j]->write(status_ack       );
		  in_SPR_READ_STATUS_DATA_VAL   [i][j]->write(status_data_val  );
		  
		  if (i == context)
		    {
		      spr_read_registerfile_val [i][j] = val and status_ack      ;
		      spr_read_status_val       [i][j] = val and registerfile_ack;
		      
		      spr_read_ack      [j] = registerfile_ack and status_ack;
		      spr_read_data     [j] = registerfile_data;
		      spr_read_data_val [j] = status_data_val;
		    }
		  else
		    {
		      spr_read_registerfile_val [i][j] = 0;
		      spr_read_status_val       [i][j] = 0;
		    }
		  
		}
	    }
	}

      if (test_write == true)
	{
	  for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	    {
	      context = (rand())%_param->_nb_ooo_engine;
	      Tcontrol_t      val = (rand()%100)<=percent_transaction;
	      
	      LABEL("GPR_WRITE ["+toString(j)+"] : "+toString(val)+" - " +toString(static_cast<uint32_t>(context)));
	      
	      in_GPR_WRITE_VAL           [j] ->write(val);
	      in_GPR_WRITE_OOO_ENGINE_ID [j] ->write(context);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  Tcontrol_t      registerfile_ack  = (rand()%100)<=percent_transaction  ;
		  Tcontrol_t      status_ack        = (rand()%100)<=percent_transaction  ;
		  
		  in_GPR_WRITE_REGISTERFILE_ACK  [i][j]->write(registerfile_ack );
		  in_GPR_WRITE_STATUS_ACK        [i][j]->write(status_ack       );
		  
		  
		  if (i == context)
		    {
		      gpr_write_registerfile_val [i][j] = val and status_ack      ;
		      gpr_write_status_val       [i][j] = val and registerfile_ack;
		      
		      gpr_write_ack      [j] = registerfile_ack and status_ack;
		    }
		  else
		    {
		      gpr_write_registerfile_val [i][j] = 0;
		      gpr_write_status_val       [i][j] = 0;
		    }
		  
		}
	    }
	  
	  for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	    {
	      context = (rand())%_param->_nb_ooo_engine;
	      Tcontrol_t      val = (rand()%100)<=percent_transaction;
	      
	      LABEL("SPR_WRITE ["+toString(j)+"] : "+toString(val)+" - " +toString(static_cast<uint32_t>(context)));
	      
	      in_SPR_WRITE_VAL           [j] ->write(val);
	      in_SPR_WRITE_OOO_ENGINE_ID [j] ->write(context);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  Tcontrol_t      registerfile_ack  = (rand()%100)<=percent_transaction  ;
		  Tcontrol_t      status_ack        = (rand()%100)<=percent_transaction  ;
		  
		  in_SPR_WRITE_REGISTERFILE_ACK  [i][j]->write(registerfile_ack );
		  in_SPR_WRITE_STATUS_ACK        [i][j]->write(status_ack       );
		  
		  
		  if (i == context)
		    {
		      spr_write_registerfile_val [i][j] = val and status_ack      ;
		      spr_write_status_val       [i][j] = val and registerfile_ack;
		      
		      spr_write_ack      [j] = registerfile_ack and status_ack;
		    }
		  else
		    {
		      spr_write_registerfile_val [i][j] = 0;
		      spr_write_status_val       [i][j] = 0;
		    }
		}
	    }
	}
      
      if (test_retire == true)
	{
	  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	    {
	      uint32_t x = _param->_nb_inst_retire_rob [i];

	      for (uint32_t j=0; j<x; j++)
		{
		Tcontrol_t val                = (rand()%100)<=percent_transaction;
		Tcontrol_t rd_old_use         = (rand()%100)<=percent_transaction; 
		Tcontrol_t rd_new_use         = (rand()%100)<=percent_transaction;
		Tcontrol_t re_old_use         = (rand()%100)<=percent_transaction; 
		Tcontrol_t re_new_use         = (rand()%100)<=percent_transaction;
		Tcontrol_t gpr_status_old_ack = (rand()%100)<=percent_transaction;
		Tcontrol_t gpr_status_new_ack = (rand()%100)<=percent_transaction;
		Tcontrol_t spr_status_old_ack = (rand()%100)<=percent_transaction;
		Tcontrol_t spr_status_new_ack = (rand()%100)<=percent_transaction;
		  
		in_RETIRE_ROB_VAL                [i][j]->write(val               );
		in_RETIRE_ROB_RD_OLD_USE         [i][j]->write(rd_old_use        ); 
		in_RETIRE_ROB_RD_NEW_USE         [i][j]->write(rd_new_use        );
		in_RETIRE_ROB_RE_OLD_USE         [i][j]->write(re_old_use        ); 
		in_RETIRE_ROB_RE_NEW_USE         [i][j]->write(re_new_use        );
		in_RETIRE_ROB_GPR_STATUS_OLD_ACK [i][j]->write(gpr_status_old_ack);
		in_RETIRE_ROB_GPR_STATUS_NEW_ACK [i][j]->write(gpr_status_new_ack);
		in_RETIRE_ROB_SPR_STATUS_OLD_ACK [i][j]->write(spr_status_old_ack);
		in_RETIRE_ROB_SPR_STATUS_NEW_ACK [i][j]->write(spr_status_new_ack);
		
		retire_rob_ack                [i][j] = (gpr_status_new_ack and
							gpr_status_old_ack and
							spr_status_new_ack and
							spr_status_old_ack);


		retire_rob_gpr_status_old_val [i][j] = val and rd_old_use                        and gpr_status_new_ack and spr_status_old_ack and spr_status_new_ack;
		retire_rob_gpr_status_new_val [i][j] = val and rd_new_use and gpr_status_old_ack                        and spr_status_old_ack and spr_status_new_ack;
		retire_rob_spr_status_old_val [i][j] = val and re_old_use and gpr_status_old_ack and gpr_status_new_ack                        and spr_status_new_ack;
		retire_rob_spr_status_new_val [i][j] = val and re_new_use and gpr_status_old_ack and gpr_status_new_ack and spr_status_old_ack                       ;
		}
	    }
	}

      if (test_insert == true)
	{
	  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	    {
	      uint32_t x = _param->_nb_inst_insert_rob [i];

	      for (uint32_t j=0; j<x; j++)
		{
		Tcontrol_t val            = (rand()%100)<=percent_transaction;
		Tcontrol_t rd_use         = (rand()%100)<=percent_transaction; 
		Tcontrol_t re_use         = (rand()%100)<=percent_transaction; 
		Tcontrol_t gpr_status_ack = (rand()%100)<=percent_transaction;
		Tcontrol_t spr_status_ack = (rand()%100)<=percent_transaction;
		  
		in_INSERT_ROB_VAL            [i][j]->write(val               );
		in_INSERT_ROB_RD_USE         [i][j]->write(rd_use        ); 
		in_INSERT_ROB_RE_USE         [i][j]->write(re_use        ); 
		in_INSERT_ROB_GPR_STATUS_ACK [i][j]->write(gpr_status_ack);
		in_INSERT_ROB_SPR_STATUS_ACK [i][j]->write(spr_status_ack);
		
		insert_rob_ack                [i][j] = (gpr_status_ack and
							spr_status_ack);


		insert_rob_gpr_status_val [i][j] = val and rd_use                    and spr_status_ack;
		insert_rob_spr_status_val [i][j] = val and re_use and gpr_status_ack                   ;
		}
	    }
	}

      SC_START(0);

      // Test
      TEST(Tcontrol_t, out_CONST_0->read() , 0);
      TEST(Tcontrol_t, out_CONST_1->read() , 1);
      
      if (test_read == true)
	{
	  for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	    {
	      TEST(Tcontrol_t     , out_GPR_READ_ACK           [j]->read(), gpr_read_ack     [j]);
	      TEST(Tgeneral_data_t, out_GPR_READ_DATA          [j]->read(), gpr_read_data    [j]);
	      TEST(Tcontrol_t     , out_GPR_READ_DATA_VAL      [j]->read(), gpr_read_data_val[j]);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  TEST(Tcontrol_t, out_GPR_READ_REGISTERFILE_VAL  [i][j]->read(), gpr_read_registerfile_val [i][j]);
		  TEST(Tcontrol_t, out_GPR_READ_STATUS_VAL        [i][j]->read(), gpr_read_status_val       [i][j]);
		}
	    }
	  for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	    {
	      TEST(Tcontrol_t     , out_SPR_READ_ACK           [j]->read(), spr_read_ack     [j]);
	      TEST(Tspecial_data_t, out_SPR_READ_DATA          [j]->read(), spr_read_data    [j]);
	      TEST(Tcontrol_t     , out_SPR_READ_DATA_VAL      [j]->read(), spr_read_data_val[j]);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  TEST(Tcontrol_t, out_SPR_READ_REGISTERFILE_VAL  [i][j]->read(), spr_read_registerfile_val [i][j]);
		  TEST(Tcontrol_t, out_SPR_READ_STATUS_VAL        [i][j]->read(), spr_read_status_val       [i][j]);
		}
	    }
	}
      
      if (test_write == true)
	{
	  for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	    {
	      TEST(Tcontrol_t     , out_GPR_WRITE_ACK           [j]->read(), gpr_write_ack     [j]);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  TEST(Tcontrol_t, out_GPR_WRITE_REGISTERFILE_VAL  [i][j]->read(), gpr_write_registerfile_val [i][j]);
		  TEST(Tcontrol_t, out_GPR_WRITE_STATUS_VAL        [i][j]->read(), gpr_write_status_val       [i][j]);
		}
	    }
	  for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	    {
	      TEST(Tcontrol_t     , out_SPR_WRITE_ACK           [j]->read(), spr_write_ack     [j]);
	      
	      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
		{
		  TEST(Tcontrol_t, out_SPR_WRITE_REGISTERFILE_VAL  [i][j]->read(), spr_write_registerfile_val [i][j]);
		  TEST(Tcontrol_t, out_SPR_WRITE_STATUS_VAL        [i][j]->read(), spr_write_status_val       [i][j]);
		}
	    }
	}


      if (test_retire == true)
	{
	  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	    {
	      uint32_t x = _param->_nb_inst_retire_rob [i];

	      for (uint32_t j=0; j<x; j++)
		{
		  TEST(Tcontrol_t, out_RETIRE_ROB_ACK                [i][j]->read(), retire_rob_ack                [i][j]);
		  TEST(Tcontrol_t, out_RETIRE_ROB_GPR_STATUS_OLD_VAL [i][j]->read(), retire_rob_gpr_status_old_val [i][j]);
		  TEST(Tcontrol_t, out_RETIRE_ROB_GPR_STATUS_NEW_VAL [i][j]->read(), retire_rob_gpr_status_new_val [i][j]);
		  TEST(Tcontrol_t, out_RETIRE_ROB_SPR_STATUS_OLD_VAL [i][j]->read(), retire_rob_spr_status_old_val [i][j]);
		  TEST(Tcontrol_t, out_RETIRE_ROB_SPR_STATUS_NEW_VAL [i][j]->read(), retire_rob_spr_status_new_val [i][j]);
		}
	    }
	}

      if (test_insert == true)
	{
	  for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	    {
	      uint32_t x = _param->_nb_inst_insert_rob [i];

	      for (uint32_t j=0; j<x; j++)
		{
		  TEST(Tcontrol_t, out_INSERT_ROB_ACK            [i][j]->read(), insert_rob_ack            [i][j]);
		  TEST(Tcontrol_t, out_INSERT_ROB_GPR_STATUS_VAL [i][j]->read(), insert_rob_gpr_status_val [i][j]);
		  TEST(Tcontrol_t, out_INSERT_ROB_SPR_STATUS_VAL [i][j]->read(), insert_rob_spr_status_val [i][j]);
		}
	    }
	}


      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_GPR_READ_VAL               ;
  delete [] out_GPR_READ_ACK               ;
  delete []  in_GPR_READ_OOO_ENGINE_ID     ;
  delete [] out_GPR_READ_DATA              ;
  delete [] out_GPR_READ_DATA_VAL          ;
  delete [] out_GPR_READ_REGISTERFILE_VAL  ;
  delete []  in_GPR_READ_REGISTERFILE_ACK  ;
  delete []  in_GPR_READ_REGISTERFILE_DATA ;
  delete [] out_GPR_READ_STATUS_VAL        ;
  delete []  in_GPR_READ_STATUS_ACK        ;
  delete []  in_GPR_READ_STATUS_DATA_VAL   ;
  delete []  in_SPR_READ_VAL               ;
  delete [] out_SPR_READ_ACK               ;
  delete []  in_SPR_READ_OOO_ENGINE_ID     ;
  delete [] out_SPR_READ_DATA              ;
  delete [] out_SPR_READ_DATA_VAL          ;
  delete [] out_SPR_READ_REGISTERFILE_VAL  ;
  delete []  in_SPR_READ_REGISTERFILE_ACK  ;
  delete []  in_SPR_READ_REGISTERFILE_DATA ;
  delete [] out_SPR_READ_STATUS_VAL        ;
  delete []  in_SPR_READ_STATUS_ACK        ;
  delete []  in_SPR_READ_STATUS_DATA_VAL   ;
  delete []  in_GPR_WRITE_VAL               ;
  delete [] out_GPR_WRITE_ACK               ;
  delete []  in_GPR_WRITE_OOO_ENGINE_ID     ;
  delete [] out_GPR_WRITE_REGISTERFILE_VAL  ;
  delete []  in_GPR_WRITE_REGISTERFILE_ACK  ;
  delete [] out_GPR_WRITE_STATUS_VAL        ;
  delete []  in_GPR_WRITE_STATUS_ACK        ;
  delete []  in_SPR_WRITE_VAL               ;
  delete [] out_SPR_WRITE_ACK               ;
  delete []  in_SPR_WRITE_OOO_ENGINE_ID     ;
  delete [] out_SPR_WRITE_REGISTERFILE_VAL  ;
  delete []  in_SPR_WRITE_REGISTERFILE_ACK  ;
  delete [] out_SPR_WRITE_STATUS_VAL        ;
  delete []  in_SPR_WRITE_STATUS_ACK        ;
  delete []  in_INSERT_ROB_VAL                  ;
  delete [] out_INSERT_ROB_ACK                  ;
  delete []  in_INSERT_ROB_RD_USE               ;
  delete []  in_INSERT_ROB_RE_USE               ;
  delete [] out_INSERT_ROB_GPR_STATUS_VAL       ;
  delete []  in_INSERT_ROB_GPR_STATUS_ACK       ;
  delete [] out_INSERT_ROB_SPR_STATUS_VAL       ;
  delete []  in_INSERT_ROB_SPR_STATUS_ACK       ;
  delete []  in_RETIRE_ROB_VAL                      ;
  delete [] out_RETIRE_ROB_ACK                      ;
  delete []  in_RETIRE_ROB_RD_OLD_USE               ;
  delete []  in_RETIRE_ROB_RD_NEW_USE               ;
  delete []  in_RETIRE_ROB_RE_OLD_USE               ;
  delete []  in_RETIRE_ROB_RE_NEW_USE               ;
  delete [] out_RETIRE_ROB_GPR_STATUS_OLD_VAL       ;
  delete [] out_RETIRE_ROB_GPR_STATUS_NEW_VAL       ;
  delete []  in_RETIRE_ROB_GPR_STATUS_OLD_ACK       ;
  delete []  in_RETIRE_ROB_GPR_STATUS_NEW_ACK       ;
  delete [] out_RETIRE_ROB_SPR_STATUS_OLD_VAL       ;
  delete [] out_RETIRE_ROB_SPR_STATUS_NEW_VAL       ;
  delete []  in_RETIRE_ROB_SPR_STATUS_OLD_ACK       ;
  delete []  in_RETIRE_ROB_SPR_STATUS_NEW_ACK       ;

#endif

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