#ifdef SYSTEMC
/*
 * $Id$
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Stage_1_Ifetch/Predictor/Meta_Predictor/Two_Level_Branch_Predictor/Branch_History_Table/include/Branch_History_Table.h"

namespace morpheo                    {
namespace behavioural {
namespace stage_1_ifetch {
namespace predictor {
namespace meta_predictor {
namespace two_level_branch_predictor {
namespace branch_history_table {


  void Branch_History_Table::allocation (void)
  {
    string rename;

     in_CLOCK           = new SC_CLOCK           ("in_CLOCK");

     in_PREDICT_VAL     = new SC_IN (Tcontrol_t) * [_param._nb_prediction];
    out_PREDICT_ACK     = new SC_OUT(Tcontrol_t) * [_param._nb_prediction];
     in_PREDICT_ADDRESS = new SC_IN (Taddress_t) * [_param._nb_prediction];
    out_PREDICT_HISTORY = new SC_OUT(Thistory_t) * [_param._nb_prediction];

    for (uint32_t i=0; i<_param._nb_prediction; i++)
      {
	rename = "in_PREDICT_VAL["     +toString(i)+"]";
	 in_PREDICT_VAL     [i] = new SC_IN (Tcontrol_t) (rename.c_str());

	rename = "out_PREDICT_ACK["    +toString(i)+"]";
	out_PREDICT_ACK     [i] = new SC_OUT(Tcontrol_t) (rename.c_str());

	rename = "in_PREDICT_ADDRESS["+toString(i)+"]";
	 in_PREDICT_ADDRESS [i] = new SC_IN (Taddress_t) (rename.c_str());

	rename = "out_PREDICT_HISTORY["+toString(i)+"]";
	out_PREDICT_HISTORY [i] = new SC_OUT(Thistory_t) (rename.c_str());
      }

        in_BRANCH_COMPLETE_VAL     = new SC_IN     (Tcontrol_t) * [_param._nb_branch_complete];
       out_BRANCH_COMPLETE_ACK     = new SC_OUT    (Tcontrol_t) * [_param._nb_branch_complete];
        in_BRANCH_COMPLETE_ADDRESS = new SC_IN     (Taddress_t) * [_param._nb_branch_complete];
        in_BRANCH_COMPLETE_HISTORY = new SC_IN     (Thistory_t) * [_param._nb_branch_complete];
        in_BRANCH_COMPLETE_DIRECTION= new SC_IN     (Tcontrol_t) * [_param._nb_branch_complete];
    signal_BRANCH_COMPLETE_HISTORY = new SC_SIGNAL (Thistory_t) * [_param._nb_branch_complete];

    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	 rename = "in_BRANCH_COMPLETE_VAL["    +toString(i)+"]";
	  in_BRANCH_COMPLETE_VAL     [i] = new SC_IN (Tcontrol_t) (rename.c_str());

	 rename = "out_BRANCH_COMPLETE_ACK["   +toString(i)+"]";
	 out_BRANCH_COMPLETE_ACK     [i] = new SC_OUT(Tcontrol_t) (rename.c_str());

	 rename = "in_BRANCH_COMPLETE_ADDRESS["+toString(i)+"]";
	  in_BRANCH_COMPLETE_ADDRESS [i] = new SC_IN (Taddress_t) (rename.c_str());

	 rename = "in_BRANCH_COMPLETE_HISTORY["+toString(i)+"]";
	  in_BRANCH_COMPLETE_HISTORY [i] = new SC_IN (Thistory_t) (rename.c_str());

	 rename = "in_BRANCH_COMPLETE_DIRECTION["    +toString(i)+"]";
	  in_BRANCH_COMPLETE_DIRECTION[i] = new SC_IN (Tcontrol_t) (rename.c_str());

	 rename = "signal_BRANCH_COMPLETE_HISTORY["+toString(i)+"]";
	 signal_BRANCH_COMPLETE_HISTORY [i] = new SC_SIGNAL (Thistory_t) (rename.c_str());

      }
    
    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    string name_component;
    // =====[ component_Shifter ]=========================================    
    
    name_component = _name+"_Shifter";

    component_Shifter = new morpheo::behavioural::generic::shifter::Shifter (name_component.c_str(),
#ifdef STATISTICS
									     _param_statistics             ,
#endif
									     *(_param._param_shifter)      );
    
    
    // Instantiation
#if (defined(STATISTICS) || defined (VHDL_TESTBENCH))
    (*(component_Shifter->in_CLOCK))        (*(in_CLOCK));
#endif

    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	(*(component_Shifter-> in_SHIFTER_DATA       [i]))    (*(    in_BRANCH_COMPLETE_HISTORY  [i]));
	(*(component_Shifter-> in_SHIFTER_CARRY_IN   [i]))    (*(    in_BRANCH_COMPLETE_DIRECTION[i]));
	(*(component_Shifter->out_SHIFTER_DATA       [i]))    (*(signal_BRANCH_COMPLETE_HISTORY  [i]));
      }
    
     // =====[ component_RegisterFile ]====================================    
    
    name_component = _name+"_RegisterFile";
    
    component_RegisterFile = new morpheo::behavioural::generic::registerfile::RegisterFile (name_component.c_str(),
#ifdef STATISTICS
											    _param_statistics            ,
#endif
											    *(_param._param_registerfile));
     
    // Instantiation
    (*(component_RegisterFile->in_CLOCK))        (*(in_CLOCK));
    
    for (uint32_t i=0; i<_param._nb_prediction; i++)
      {
	(*(component_RegisterFile-> in_READ_ENABLE   [i])) (*( in_PREDICT_VAL      [i]));
	(*(component_RegisterFile-> in_READ_ADDRESS  [i])) (*( in_PREDICT_ADDRESS  [i]));
	(*(component_RegisterFile->out_READ_DATA     [i])) (*(out_PREDICT_HISTORY  [i]));    
      }
    
    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	(*(component_RegisterFile-> in_WRITE_ENABLE  [i])) (*(    in_BRANCH_COMPLETE_VAL      [i]));
	(*(component_RegisterFile-> in_WRITE_ADDRESS [i])) (*(    in_BRANCH_COMPLETE_ADDRESS  [i]));
	(*(component_RegisterFile-> in_WRITE_DATA    [i])) (*(signal_BRANCH_COMPLETE_HISTORY  [i]));    
      }
  };

}; // end namespace branch_history_table
}; // end namespace two_level_branch_predictor
}; // end namespace meta_predictor
}; // end namespace predictor
}; // end namespace stage_1_ifetch
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
