/*
 * $Id: test.cpp 119 2009-05-25 17:40:26Z rosiere $
 *
 * [ Description ]
 * 
 * Test
 */

#define NB_ITERATION  1
#define CYCLE_MAX     1000000

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/SelfTest/include/test.h"
#include "Common/include/Test.h"
#include "Behavioural/include/Allocation.h"

void test (string name,
	   morpheo::behavioural::core::multi_front_end::front_end::prediction_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

  Tusage_t _usage = USE_ALL;

//   _usage = usage_unset(_usage,USE_SYSTEMC              );
//   _usage = usage_unset(_usage,USE_VHDL                 );
//   _usage = usage_unset(_usage,USE_VHDL_TESTBENCH       );
//   _usage = usage_unset(_usage,USE_VHDL_TESTBENCH_ASSERT);
//   _usage = usage_unset(_usage,USE_POSITION             );
//   _usage = usage_unset(_usage,USE_STATISTICS           );
//   _usage = usage_unset(_usage,USE_INFORMATION          );
 
  Prediction_unit * _Prediction_unit = new Prediction_unit 
    (name.c_str(),
#ifdef STATISTICS
     _parameters_statistics,
#endif
     _param,
     _usage);
  
#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_PREDICT_VAL                        ," in_PREDICT_VAL                        ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_PREDICT_ACK                        ,"out_PREDICT_ACK                        ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_PREDICT_PC_PREVIOUS                ," in_PREDICT_PC_PREVIOUS                ",Taddress_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_PREDICT_PC_CURRENT                 ," in_PREDICT_PC_CURRENT                 ",Taddress_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_PREDICT_PC_CURRENT_IS_DS_TAKE      ," in_PREDICT_PC_CURRENT_IS_DS_TAKE      ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_PREDICT_PC_NEXT                    ,"out_PREDICT_PC_NEXT                    ",Taddress_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_PREDICT_PC_NEXT_IS_DS_TAKE         ,"out_PREDICT_PC_NEXT_IS_DS_TAKE         ",Tcontrol_t         ,_param->_nb_context);
  ALLOC2_SC_SIGNAL(out_PREDICT_INSTRUCTION_ENABLE         ,"out_PREDICT_INSTRUCTION_ENABLE         ",Tcontrol_t         ,_param->_nb_context,_param->_nb_instruction[it1]);
  ALLOC1_SC_SIGNAL(out_PREDICT_INST_IFETCH_PTR            ,"out_PREDICT_INST_IFETCH_PTR            ",Tinst_ifetch_ptr_t ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_PREDICT_BRANCH_STATE               ,"out_PREDICT_BRANCH_STATE               ",Tbranch_state_t    ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID,"out_PREDICT_BRANCH_UPDATE_PREDICTION_ID",Tprediction_ptr_t  ,_param->_nb_context);
												                         
  ALLOC2_SC_SIGNAL( in_DECOD_VAL                          ," in_DECOD_VAL                          ",Tcontrol_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL(out_DECOD_ACK                          ,"out_DECOD_ACK                          ",Tcontrol_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_CONTEXT_ID                   ," in_DECOD_CONTEXT_ID                   ",Tcontext_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_MATCH_INST_IFETCH_PTR        ," in_DECOD_MATCH_INST_IFETCH_PTR        ",Tcontrol_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_BRANCH_STATE                 ," in_DECOD_BRANCH_STATE                 ",Tbranch_state_t    ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_BRANCH_UPDATE_PREDICTION_ID  ," in_DECOD_BRANCH_UPDATE_PREDICTION_ID  ",Tprediction_ptr_t  ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_BRANCH_CONDITION             ," in_DECOD_BRANCH_CONDITION             ",Tbranch_condition_t,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_BRANCH_DIRECTION             ," in_DECOD_BRANCH_DIRECTION             ",Tcontrol_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_ADDRESS_SRC                  ," in_DECOD_ADDRESS_SRC                  ",Taddress_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL( in_DECOD_ADDRESS_DEST                 ," in_DECOD_ADDRESS_DEST                 ",Taddress_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  ALLOC2_SC_SIGNAL(out_DECOD_CAN_CONTINUE                 ," in_DECOD_CAN_CONTINUE                 ",Tcontrol_t         ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
												                         
  ALLOC1_SC_SIGNAL( in_BRANCH_COMPLETE_VAL                ," in_BRANCH_COMPLETE_VAL                ",Tcontrol_t         ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL(out_BRANCH_COMPLETE_ACK                ,"out_BRANCH_COMPLETE_ACK                ",Tcontrol_t         ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL( in_BRANCH_COMPLETE_CONTEXT_ID         ," in_BRANCH_COMPLETE_CONTEXT_ID         ",Tcontext_t         ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL( in_BRANCH_COMPLETE_DEPTH              ," in_BRANCH_COMPLETE_DEPTH              ",Tdepth_t           ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL( in_BRANCH_COMPLETE_ADDRESS            ," in_BRANCH_COMPLETE_ADDRESS            ",Taddress_t         ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL( in_BRANCH_COMPLETE_NO_SEQUENCE        ," in_BRANCH_COMPLETE_NO_SEQUENCE        ",Tcontrol_t         ,_param->_nb_inst_branch_complete);
  ALLOC1_SC_SIGNAL(out_BRANCH_COMPLETE_MISS_PREDICTION    ,"out_BRANCH_COMPLETE_MISS_PREDICTION    ",Tcontrol_t         ,_param->_nb_inst_branch_complete);
//   ALLOC1_SC_SIGNAL(out_BRANCH_COMPLETE_TAKE               ,"out_BRANCH_COMPLETE_TAKE               ",Tcontrol_t         ,_param->_nb_inst_branch_complete);
//   ALLOC1_SC_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_SRC        ,"out_BRANCH_COMPLETE_ADDRESS_SRC        ",Taddress_t         ,_param->_nb_inst_branch_complete);
//   ALLOC1_SC_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_DEST       ,"out_BRANCH_COMPLETE_ADDRESS_DEST       ",Taddress_t         ,_param->_nb_inst_branch_complete);
												                         
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_VAL                   ,"out_BRANCH_EVENT_VAL                   ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_BRANCH_EVENT_ACK                   ," in_BRANCH_EVENT_ACK                   ",Tcontrol_t         ,_param->_nb_context);
//ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_CONTEXT_ID            ,"out_BRANCH_EVENT_CONTEXT_ID            ",Tcontext_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_DEPTH                 ,"out_BRANCH_EVENT_DEPTH                 ",Tdepth_t           ,_param->_nb_context);
//ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_MISS_PREDICTION       ,"out_BRANCH_EVENT_MISS_PREDICTION       ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_SRC           ,"out_BRANCH_EVENT_ADDRESS_SRC           ",Taddress_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST_VAL      ,"out_BRANCH_EVENT_ADDRESS_DEST_VAL      ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST          ,"out_BRANCH_EVENT_ADDRESS_DEST          ",Taddress_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_BRANCH_EVENT_CAN_CONTINUE          ,"out_BRANCH_EVENT_CAN_CONTINUE          ",Tcontrol_t         ,_param->_nb_context);
												                         
  ALLOC1_SC_SIGNAL( in_EVENT_VAL                          ," in_EVENT_VAL                          ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_EVENT_ACK                          ,"out_EVENT_ACK                          ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_EVENT_TYPE                         ," in_EVENT_TYPE                         ",Tevent_type_t      ,_param->_nb_context);
  ALLOC1_SC_SIGNAL( in_EVENT_DEPTH                        ," in_EVENT_DEPTH                        ",Tdepth_t           ,_param->_nb_context);

  ALLOC1_SC_SIGNAL(out_DEPTH_VAL                          ,"out_DEPTH_VAL                          ",Tcontrol_t         ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_DEPTH_CURRENT                      ,"out_DEPTH_CURRENT                      ",Tdepth_t           ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_DEPTH_MIN                          ,"out_DEPTH_MIN                          ",Tdepth_t           ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_DEPTH_MAX                          ,"out_DEPTH_MAX                          ",Tdepth_t           ,_param->_nb_context);
  ALLOC1_SC_SIGNAL(out_DEPTH_FULL                         ,"out_DEPTH_FULL                         ",Tcontrol_t         ,_param->_nb_context);
  
  /********************************************************
   * Instanciation
   ********************************************************/
  
  msg(_("<%s> : Instanciation of _Prediction_unit.\n"),name.c_str());

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

  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_PREDICT_VAL                        ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_ACK                        ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_PREDICT_PC_PREVIOUS                ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_PREDICT_PC_CURRENT                 ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_PREDICT_PC_CURRENT_IS_DS_TAKE      ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_PC_NEXT                    ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_PC_NEXT_IS_DS_TAKE         ,_param->_nb_context);
  INSTANCE2_SC_SIGNAL(_Prediction_unit,out_PREDICT_INSTRUCTION_ENABLE         ,_param->_nb_context,_param->_nb_instruction[it1]);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_BRANCH_STATE               ,_param->_nb_context);
  if (_param->_have_port_inst_ifetch_ptr)
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_INST_IFETCH_PTR            ,_param->_nb_context);
  if (_param->_have_port_depth)
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_PREDICT_BRANCH_UPDATE_PREDICTION_ID,_param->_nb_context);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_VAL                          ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit,out_DECOD_ACK                          ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  if (_param->_have_port_context_id)
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_CONTEXT_ID                   ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_MATCH_INST_IFETCH_PTR        ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_BRANCH_STATE                 ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  if (_param->_have_port_depth)
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_BRANCH_UPDATE_PREDICTION_ID  ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_BRANCH_CONDITION             ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_BRANCH_DIRECTION             ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_ADDRESS_SRC                  ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit, in_DECOD_ADDRESS_DEST                 ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  INSTANCE2_SC_SIGNAL(_Prediction_unit,out_DECOD_CAN_CONTINUE                 ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);

  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_COMPLETE_VAL                ,_param->_nb_inst_branch_complete);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_COMPLETE_ACK                ,_param->_nb_inst_branch_complete);
  if (_param->_have_port_context_id)
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_COMPLETE_CONTEXT_ID         ,_param->_nb_inst_branch_complete);
  if (_param->_have_port_depth)
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_COMPLETE_DEPTH              ,_param->_nb_inst_branch_complete);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_COMPLETE_ADDRESS            ,_param->_nb_inst_branch_complete);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_COMPLETE_NO_SEQUENCE        ,_param->_nb_inst_branch_complete);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_COMPLETE_MISS_PREDICTION    ,_param->_nb_inst_branch_complete);
//   INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_COMPLETE_TAKE               ,_param->_nb_inst_branch_complete);
//   INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_COMPLETE_ADDRESS_SRC        ,_param->_nb_inst_branch_complete);
//   INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_COMPLETE_ADDRESS_DEST       ,_param->_nb_inst_branch_complete);

  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_VAL                   ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_BRANCH_EVENT_ACK                   ,_param->_nb_context);
//if (_param->_have_port_context_id)
//INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_CONTEXT_ID            ,_param->_nb_context);
  if (_param->_have_port_depth)
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_DEPTH                 ,_param->_nb_context);
//INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_MISS_PREDICTION       ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_ADDRESS_SRC           ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_ADDRESS_DEST_VAL      ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_ADDRESS_DEST          ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_BRANCH_EVENT_CAN_CONTINUE          ,_param->_nb_context);

  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_EVENT_VAL                          ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_EVENT_ACK                          ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_EVENT_TYPE                         ,_param->_nb_context);
  if (_param->_have_port_depth)
    {
  INSTANCE1_SC_SIGNAL(_Prediction_unit, in_EVENT_DEPTH                        ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_DEPTH_CURRENT                      ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_DEPTH_MIN                          ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_DEPTH_MAX                          ,_param->_nb_context);
    }
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_DEPTH_VAL                          ,_param->_nb_context);
  INSTANCE1_SC_SIGNAL(_Prediction_unit,out_DEPTH_FULL                         ,_param->_nb_context);

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

  const  int32_t percent_transaction_predict         = 80;
  const  int32_t percent_transaction_decod           = 80;
  const  int32_t percent_transaction_branch_complete = 80;
  const  int32_t percent_transaction_branch_event    = 80;

  srand(seed);
  
  uint32_t test1 = 1024; // TEST 1 : instruction without branch
  uint32_t test2 = 1024; // TEST 2 : sequence : 1 branch, 1 delayed slot

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

  for (uint32_t i=0; i<_param->_nb_context; ++i)
    {
      in_PREDICT_VAL      [i]->write(0);
      in_BRANCH_EVENT_ACK [i]->write(0);
    }

  for (uint32_t i=0; i<_param->_nb_decod_unit;++i)
    for (uint32_t j=0; j<_param->_nb_inst_decod[i]; ++j)
      {
        in_DECOD_VAL [i][j]->write(0);
      }

  for (uint32_t i=0; i<_param->_nb_inst_branch_complete; ++i)
    {
      in_BRANCH_COMPLETE_VAL [i]->write(0);
    }

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

  for (uint32_t i=0; i<_param->_nb_context; ++i)
    {
//       TEST(Tcontrol_t,out_PREDICT_ACK      [i]->read(),1); // Accept new request
      TEST(Tcontrol_t,out_BRANCH_EVENT_VAL [i]->read(),0);
      TEST(Tdepth_t  ,out_DEPTH_CURRENT    [i]->read(),0);
      TEST(Tdepth_t  ,out_DEPTH_MIN        [i]->read(),0);
      TEST(Tdepth_t  ,out_DEPTH_MAX        [i]->read(),0);
    }

  for (uint32_t i=0; i<_param->_nb_decod_unit;++i)
    for (uint32_t j=0; j<_param->_nb_inst_decod[i]; ++j)
      {
        TEST(Tcontrol_t,out_DECOD_ACK [i][j]->read(),0); // No decod instruction
      }

  for (uint32_t i=0; i<_param->_nb_inst_branch_complete; ++i)
    {
      TEST(Tcontrol_t,out_BRANCH_COMPLETE_ACK [i]->read(),1); // Accept new branch_complete
    }

  LABEL("Loop of Test");

  Taddress_t PC_PREVIOUS           [_param->_nb_context];
  Taddress_t PC_CURRENT            [_param->_nb_context];
  Tcontrol_t PC_CURRENT_IS_DS_TAKE [_param->_nb_context];

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

      // TEST 1 : instruction without branch
      for (uint32_t test=0; test<test1; ++test)
        {
          for (uint32_t i=0; i<_param->_nb_context; ++i)
            {
              PC_CURRENT            [i] = (0x100000>>2);
              PC_CURRENT_IS_DS_TAKE [i] = 0;
              PC_PREVIOUS           [i] = PC_CURRENT[i]-1;
            }
          
          for (uint32_t i=0; i<_param->_nb_context; ++i)
            {
              in_PREDICT_VAL                   [i]->write((rand()%100)<percent_transaction_predict);
              in_PREDICT_PC_PREVIOUS           [i]->write(PC_PREVIOUS          [i]);
              in_PREDICT_PC_CURRENT            [i]->write(PC_CURRENT           [i]);
              in_PREDICT_PC_CURRENT_IS_DS_TAKE [i]->write(PC_CURRENT_IS_DS_TAKE[i]);
            }

          SC_START(1);

          for (uint32_t i=0; i<_param->_nb_context; ++i)
            // Test if transaction
            if (in_PREDICT_VAL [i]->read() and out_PREDICT_ACK [i]->read())
              {
                TEST(Taddress_t        ,out_PREDICT_PC_NEXT                     [i]->read(),PC_CURRENT[i]+_param->_nb_instruction[i]);
                TEST(Tcontrol_t        ,out_PREDICT_PC_NEXT_IS_DS_TAKE          [i]->read(),0);
                for (uint32_t j=0; j<_param->_nb_instruction[i]; ++j)
                TEST(Tcontrol_t        ,out_PREDICT_INSTRUCTION_ENABLE          [i][j]->read(),1);
                TEST(Tinst_ifetch_ptr_t,out_PREDICT_INST_IFETCH_PTR             [i]->read(),0);
                TEST(Tbranch_state_t   ,out_PREDICT_BRANCH_STATE                [i]->read(),BRANCH_STATE_NONE);
                TEST(Tprediction_ptr_t ,out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [i]->read(),0);

                PC_PREVIOUS           [i] = PC_CURRENT [i];
                PC_CURRENT            [i] = out_PREDICT_PC_NEXT            [i]->read();
                PC_CURRENT_IS_DS_TAKE [i] = out_PREDICT_PC_NEXT_IS_DS_TAKE [i]->read();
              }

          // Test another output
          for (uint32_t i=0; i<_param->_nb_context; ++i)
            {
              TEST(Tcontrol_t,out_BRANCH_EVENT_VAL [i]->read(),0);
              TEST(Tdepth_t  ,out_DEPTH_CURRENT    [i]->read(),0);
              TEST(Tdepth_t  ,out_DEPTH_MIN        [i]->read(),0);
              TEST(Tdepth_t  ,out_DEPTH_MAX        [i]->read(),0);
            }
          
          for (uint32_t i=0; i<_param->_nb_decod_unit;++i)
            for (uint32_t j=0; j<_param->_nb_inst_decod[i]; ++j)
              {
                TEST(Tcontrol_t,out_DECOD_ACK [i][j]->read(),0); // No decod instruction
              }
          
          for (uint32_t i=0; i<_param->_nb_inst_branch_complete; ++i)
            {
              TEST(Tcontrol_t,out_BRANCH_COMPLETE_ACK [i]->read(),1); // Accept new branch_complete
            }
        }

      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;

  DELETE1_SC_SIGNAL( in_PREDICT_VAL                        ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_ACK                        ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_PREDICT_PC_PREVIOUS                ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_PREDICT_PC_CURRENT                 ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_PREDICT_PC_CURRENT_IS_DS_TAKE      ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_PC_NEXT                    ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_PC_NEXT_IS_DS_TAKE         ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_INST_IFETCH_PTR            ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_BRANCH_STATE               ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID,_param->_nb_context);

  DELETE2_SC_SIGNAL(out_PREDICT_INSTRUCTION_ENABLE       ,_param->_nb_context,_param->_nb_instruction[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_VAL                        ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL(out_DECOD_ACK                        ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_CONTEXT_ID                 ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_MATCH_INST_IFETCH_PTR      ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_BRANCH_STATE               ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_BRANCH_UPDATE_PREDICTION_ID,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_BRANCH_CONDITION           ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_BRANCH_DIRECTION           ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_ADDRESS_SRC                ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL( in_DECOD_ADDRESS_DEST               ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
  DELETE2_SC_SIGNAL(out_DECOD_CAN_CONTINUE               ,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);

  DELETE1_SC_SIGNAL( in_BRANCH_COMPLETE_VAL            ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL(out_BRANCH_COMPLETE_ACK            ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL( in_BRANCH_COMPLETE_CONTEXT_ID     ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL( in_BRANCH_COMPLETE_DEPTH          ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL( in_BRANCH_COMPLETE_ADDRESS        ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL( in_BRANCH_COMPLETE_NO_SEQUENCE    ,_param->_nb_inst_branch_complete);
  DELETE1_SC_SIGNAL(out_BRANCH_COMPLETE_MISS_PREDICTION,_param->_nb_inst_branch_complete);
//   DELETE1_SC_SIGNAL(out_BRANCH_COMPLETE_TAKE           ,_param->_nb_inst_branch_complete);
//   DELETE1_SC_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_SRC    ,_param->_nb_inst_branch_complete);
//   DELETE1_SC_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_DEST   ,_param->_nb_inst_branch_complete);

  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_VAL              ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_BRANCH_EVENT_ACK              ,_param->_nb_context);
//DELETE1_SC_SIGNAL(out_BRANCH_EVENT_CONTEXT_ID       ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_DEPTH            ,_param->_nb_context);
//DELETE1_SC_SIGNAL(out_BRANCH_EVENT_MISS_PREDICTION  ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_SRC      ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST_VAL ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST     ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_BRANCH_EVENT_CAN_CONTINUE     ,_param->_nb_context);

  DELETE1_SC_SIGNAL( in_EVENT_VAL                      ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_EVENT_ACK                      ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_EVENT_TYPE                     ,_param->_nb_context);
  DELETE1_SC_SIGNAL( in_EVENT_DEPTH                    ,_param->_nb_context);

  DELETE1_SC_SIGNAL(out_DEPTH_VAL          ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_DEPTH_CURRENT      ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_DEPTH_MIN          ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_DEPTH_MAX          ,_param->_nb_context);
  DELETE1_SC_SIGNAL(out_DEPTH_FULL         ,_param->_nb_context);
#endif

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