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

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Meta_Predictor_Glue/include/Meta_Predictor_Glue.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace prediction_unit {
namespace direction {

namespace meta_predictor {
namespace meta_predictor_glue {


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

    log_printf(FUNC,Meta_Predictor_Glue,"allocation","Begin");

    _component   = new Component ();

    Entity * entity = _component->set_entity (_name                 
					     ,"Two_Level_Branch_Predictor_Glue"
#ifdef POSITION
					     ,COMBINATORY
#endif
					      );
    
    _interfaces = entity->set_interfaces();

    // ~~~~~[ Interface : "" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      Interface * interface = _interfaces->set_interface(""
#ifdef POSITION
							 , IN  
							 , SOUTH
							 , "Generalist interface"
#endif
							 );
      
      in_CLOCK              = interface->set_signal_clk              ("clock" ,1,CLOCK_VHDL_NO);
      in_NRESET             = interface->set_signal_in  <Tcontrol_t> ("nreset",1,RESET_VHDL_NO);
    }


    // ~~~~~[ Interface : "Predict" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    if (_param._have_meta_predictor)
      {
     in_PREDICT_PREDICTOR_0_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_prediction     ];
     in_PREDICT_PREDICTOR_1_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_prediction     ];
      }			           
     in_PREDICT_PREDICTOR_2_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_prediction     ];
    out_PREDICT_ACK                     = new SC_OUT(Tcontrol_t)     * [_param._nb_prediction     ];
    if (_param._have_meta_predictor)
      {
    if (_param._predictor_0_have_bht)
     in_PREDICT_PREDICTOR_0_BHT_HISTORY = new SC_IN (Tbht_history_t) * [_param._nb_prediction     ];
    if (_param._predictor_0_have_pht)
     in_PREDICT_PREDICTOR_0_PHT_HISTORY = new SC_IN (Tpht_history_t) * [_param._nb_prediction     ];
    if (_param._predictor_1_have_bht)
     in_PREDICT_PREDICTOR_1_BHT_HISTORY = new SC_IN (Tbht_history_t) * [_param._nb_prediction     ];
    if (_param._predictor_1_have_pht)
     in_PREDICT_PREDICTOR_1_PHT_HISTORY = new SC_IN (Tpht_history_t) * [_param._nb_prediction     ];
      }
    if (_param._predictor_2_have_bht)
     in_PREDICT_PREDICTOR_2_BHT_HISTORY = new SC_IN (Tbht_history_t) * [_param._nb_prediction     ];
    if (_param._predictor_2_have_pht)
     in_PREDICT_PREDICTOR_2_PHT_HISTORY = new SC_IN (Tpht_history_t) * [_param._nb_prediction     ];
    out_PREDICT_HISTORY                 = new SC_OUT(Thistory_t)     * [_param._nb_prediction     ];
    out_PREDICT_DIRECTION               = new SC_OUT(Tcontrol_t)     * [_param._nb_prediction     ];

    for (uint32_t i=0; i<_param._nb_prediction; i++)
      {
	Interface_fifo * interface = _interfaces->set_interface("predict_"+toString(i)
#ifdef POSITION
								, IN  
								, WEST
								, "Interface Predict"
#endif
								);

	if (_param._have_meta_predictor)
	  {
	 in_PREDICT_PREDICTOR_0_ACK                   [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_0_ack"        , 1);
	 in_PREDICT_PREDICTOR_1_ACK                   [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_1_ack"        , 1);
	  }
	 in_PREDICT_PREDICTOR_2_ACK                   [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_2_ack"        , 1);
	
	out_PREDICT_ACK                               [i] = interface->set_signal_out <Tcontrol_t>     ("ack"                    , 1);

	if (_param._have_meta_predictor)
	  {
	if (_param._predictor_0_have_bht)
	 in_PREDICT_PREDICTOR_0_BHT_HISTORY           [i] = interface->set_signal_in  <Tbht_history_t> ("predictor_0_bht_history", _param._predictor_0_bht_size_shifter);
	if (_param._predictor_0_have_pht)
	 in_PREDICT_PREDICTOR_0_PHT_HISTORY           [i] = interface->set_signal_in  <Tpht_history_t> ("predictor_0_pht_history", _param._predictor_0_pht_size_counter);
	if (_param._predictor_1_have_bht)
	 in_PREDICT_PREDICTOR_1_BHT_HISTORY           [i] = interface->set_signal_in  <Tbht_history_t> ("predictor_1_bht_history", _param._predictor_1_bht_size_shifter);
	if (_param._predictor_1_have_pht)
	 in_PREDICT_PREDICTOR_1_PHT_HISTORY           [i] = interface->set_signal_in  <Tpht_history_t> ("predictor_1_pht_history", _param._predictor_1_pht_size_counter);
	  }
	if (_param._predictor_2_have_bht)
	 in_PREDICT_PREDICTOR_2_BHT_HISTORY           [i] = interface->set_signal_in  <Tbht_history_t> ("predictor_2_bht_history", _param._predictor_2_bht_size_shifter);
	if (_param._predictor_2_have_pht)
	 in_PREDICT_PREDICTOR_2_PHT_HISTORY           [i] = interface->set_signal_in  <Tpht_history_t> ("predictor_2_pht_history", _param._predictor_2_pht_size_counter);
	out_PREDICT_HISTORY                           [i] = interface->set_signal_out <Thistory_t>     ("history"                , _param._size_history);
	out_PREDICT_DIRECTION                         [i] = interface->set_signal_out <Tcontrol_t>     ("direction"              , 1);
      }

    // ~~~~~[ Interface : "branch_complete" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    if (_param._have_meta_predictor)
      {
     in_BRANCH_COMPLETE_VAL                     = new SC_IN (Tcontrol_t)     * [_param._nb_branch_complete     ];
    out_BRANCH_COMPLETE_PREDICTOR_2_VAL         = new SC_OUT(Tcontrol_t)     * [_param._nb_branch_complete     ];

     in_BRANCH_COMPLETE_PREDICTOR_0_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_branch_complete     ];
     in_BRANCH_COMPLETE_PREDICTOR_1_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_branch_complete     ];
      }			           
     in_BRANCH_COMPLETE_PREDICTOR_2_ACK         = new SC_IN (Tcontrol_t)     * [_param._nb_branch_complete     ];
    out_BRANCH_COMPLETE_ACK                     = new SC_OUT(Tcontrol_t)     * [_param._nb_branch_complete     ];
    if (_param._have_meta_predictor)
      {
    if (_param._predictor_0_have_bht)
    out_BRANCH_COMPLETE_PREDICTOR_0_BHT_HISTORY = new SC_OUT(Tbht_history_t) * [_param._nb_branch_complete     ];
    if (_param._predictor_0_have_pht)
    out_BRANCH_COMPLETE_PREDICTOR_0_PHT_HISTORY = new SC_OUT(Tpht_history_t) * [_param._nb_branch_complete     ];
    if (_param._predictor_1_have_bht)
    out_BRANCH_COMPLETE_PREDICTOR_1_BHT_HISTORY = new SC_OUT(Tbht_history_t) * [_param._nb_branch_complete     ];
    if (_param._predictor_1_have_pht)
    out_BRANCH_COMPLETE_PREDICTOR_1_PHT_HISTORY = new SC_OUT(Tpht_history_t) * [_param._nb_branch_complete     ];
      }
    if (_param._predictor_2_have_bht)
    out_BRANCH_COMPLETE_PREDICTOR_2_BHT_HISTORY = new SC_OUT(Tbht_history_t) * [_param._nb_branch_complete     ];
    if (_param._predictor_2_have_pht)
    out_BRANCH_COMPLETE_PREDICTOR_2_PHT_HISTORY = new SC_OUT(Tpht_history_t) * [_param._nb_branch_complete     ];
     in_BRANCH_COMPLETE_HISTORY                 = new SC_IN (Thistory_t)     * [_param._nb_branch_complete     ];
    if (_param._have_meta_predictor)
      {
     in_BRANCH_COMPLETE_DIRECTION               = new SC_IN (Tcontrol_t)     * [_param._nb_branch_complete     ];
    out_BRANCH_COMPLETE_PREDICTOR_2_DIRECTION   = new SC_OUT(Tcontrol_t)     * [_param._nb_branch_complete     ];
      }
    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	Interface_fifo * interface = _interfaces->set_interface("branch_complete_"+toString(i)
#ifdef POSITION
								, IN  
								, EAST
								, "Interface branch complete"
#endif
								);

	if (_param._have_meta_predictor)
	  {
	 in_BRANCH_COMPLETE_VAL                      [i] = interface->set_signal_in  <Tcontrol_t>     ("val"            , 1);
	out_BRANCH_COMPLETE_PREDICTOR_2_VAL          [i] = interface->set_signal_out <Tcontrol_t>     ("predictor_2_val", 1);
	 in_BRANCH_COMPLETE_PREDICTOR_0_ACK          [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_0_ack", 1);
	 in_BRANCH_COMPLETE_PREDICTOR_1_ACK          [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_1_ack", 1);
	  }
	 in_BRANCH_COMPLETE_PREDICTOR_2_ACK          [i] = interface->set_signal_in  <Tcontrol_t>     ("predictor_2_ack" , 1);
	out_BRANCH_COMPLETE_ACK                      [i] = interface->set_signal_out <Tcontrol_t>     ("ack"             , 1);
	if (_param._have_meta_predictor)
	  {
	if (_param._predictor_0_have_bht)
	out_BRANCH_COMPLETE_PREDICTOR_0_BHT_HISTORY  [i] = interface->set_signal_out <Tbht_history_t> ("predictor_0_bht_history" , _param._predictor_0_bht_size_shifter );
	if (_param._predictor_0_have_pht)
	out_BRANCH_COMPLETE_PREDICTOR_0_PHT_HISTORY  [i] = interface->set_signal_out <Tpht_history_t> ("predictor_0_pht_history" , _param._predictor_0_pht_size_counter);
	if (_param._predictor_1_have_bht)
	out_BRANCH_COMPLETE_PREDICTOR_1_BHT_HISTORY  [i] = interface->set_signal_out <Tbht_history_t> ("predictor_1_bht_history" , _param._predictor_1_bht_size_shifter );
	if (_param._predictor_1_have_pht)
	out_BRANCH_COMPLETE_PREDICTOR_1_PHT_HISTORY  [i] = interface->set_signal_out <Tpht_history_t> ("predictor_1_pht_history" , _param._predictor_1_pht_size_counter );
	  }
	if (_param._predictor_2_have_bht)
	out_BRANCH_COMPLETE_PREDICTOR_2_BHT_HISTORY  [i] = interface->set_signal_out <Tbht_history_t> ("predictor_2_bht_history" , _param._predictor_2_bht_size_shifter);
	if (_param._predictor_2_have_pht)
	out_BRANCH_COMPLETE_PREDICTOR_2_PHT_HISTORY  [i] = interface->set_signal_out <Tpht_history_t> ("predictor_2_pht_history" , _param._predictor_2_pht_size_counter);
	 in_BRANCH_COMPLETE_HISTORY                  [i] = interface->set_signal_in  <Thistory_t>     ("history"                 , _param._size_history);
	if (_param._have_meta_predictor)
	  {
	 in_BRANCH_COMPLETE_DIRECTION                [i] = interface->set_signal_in  <Tcontrol_t>     ("direction"             , 1);
	out_BRANCH_COMPLETE_PREDICTOR_2_DIRECTION    [i] = interface->set_signal_out <Tcontrol_t>     ("predictor_2_direction" , 1);
	  }
      }
    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

#ifdef POSITION
    _component->generate_file();
#endif

    log_printf(FUNC,Meta_Predictor_Glue,"allocation","End");
  };

}; // end namespace meta_predictor_glue
}; // end namespace meta_predictor

}; // end namespace core
}; // end namespace multi_front_end
}; // end namespace front_end
}; // end namespace prediction_unit
}; // end namespace direction


}; // end namespace behavioural
}; // end namespace morpheo              
#endif
