/*
 * $Id: Branch_Target_Buffer_allocation.cpp 112 2009-03-18 22:36:26Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Branch_Target_Buffer/include/Branch_Target_Buffer.h"
#include "Behavioural/include/Allocation.h"

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



#undef  FUNCTION
#define FUNCTION "Branch_Target_Buffer::allocation"
  void Branch_Target_Buffer::allocation 
  (
#ifdef STATISTICS
   morpheo::behavioural::Parameters_Statistics * param_statistics
#else
   void
#endif
   )
  {
    log_printf(FUNC,Branch_Target_Buffer,FUNCTION,"Begin");

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Branch_Target_Buffer"
#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_YES);
      in_NRESET       = interface->set_signal_in  <Tcontrol_t> ("nreset",1, RESET_VHDL_YES);
    }
    
    // ~~~~~[ Interface : "predict" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("predict", IN, SOUTH, _("Predict (next pc) interface"), _param->_nb_inst_predict);

      ALLOC1_VALACK_IN ( in_PREDICT_VAL         ,VAL);
      ALLOC1_VALACK_OUT(out_PREDICT_ACK         ,ACK);
      ALLOC1_SIGNAL_IN ( in_PREDICT_CONTEXT_ID  ,"context_id"  ,Tcontext_t         ,_param->_size_context_id);
      ALLOC1_SIGNAL_IN ( in_PREDICT_ADDRESS     ,"address"     ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT(out_PREDICT_HIT         ,"hit"         ,Tcontrol_t         ,1);
      ALLOC1_SIGNAL_OUT(out_PREDICT_ADDRESS_SRC ,"address_src" ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT(out_PREDICT_ADDRESS_DEST,"address_dest",Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT(out_PREDICT_CONDITION   ,"condition"   ,Tbranch_condition_t,_param->_size_branch_condition);
      ALLOC1_SIGNAL_OUT(out_PREDICT_LAST_TAKE   ,"last_take"   ,Tcontrol_t         ,1);
      ALLOC1_SIGNAL_OUT(out_PREDICT_IS_ACCURATE ,"is_accurate" ,Tcontrol_t         ,1);

      ALLOC1_INTERFACE_END(param->_nb_inst_predict);
    }

    // ~~~~~[ Interface : "decod" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("decod", IN, SOUTH, _("Decod Interface"), _param->_nb_inst_decod);
    
      ALLOC1_VALACK_IN ( in_DECOD_VAL            ,VAL);
      ALLOC1_VALACK_OUT(out_DECOD_ACK            ,ACK);
      ALLOC1_SIGNAL_IN ( in_DECOD_CONTEXT_ID     ,"context_id"     ,Tcontext_t         ,_param->_size_context_id);
      ALLOC1_SIGNAL_IN ( in_DECOD_ADDRESS_SRC    ,"address_src"    ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN ( in_DECOD_ADDRESS_DEST   ,"address_dest"   ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN ( in_DECOD_CONDITION      ,"condition"      ,Tbranch_condition_t,_param->_size_branch_condition);
      ALLOC1_SIGNAL_IN ( in_DECOD_LAST_TAKE      ,"last_take"      ,Tcontrol_t         ,1);
      ALLOC1_SIGNAL_IN ( in_DECOD_MISS_PREDICTION,"miss_prediction",Tcontrol_t         ,1);
      ALLOC1_SIGNAL_IN ( in_DECOD_IS_ACCURATE    ,"is_accurate"    ,Tcontrol_t         ,1);

      ALLOC1_INTERFACE_END(_param->_nb_inst_decod);
    }

    // ~~~~~[ Interface : "update" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("update", IN, SOUTH, _("Update interface"), _param->_nb_inst_update);
    
      ALLOC1_VALACK_IN ( in_UPDATE_VAL            ,VAL);
      ALLOC1_VALACK_OUT(out_UPDATE_ACK            ,ACK);
      ALLOC1_SIGNAL_IN ( in_UPDATE_CONTEXT_ID     ,"context_id"     ,Tcontext_t         ,_param->_size_context_id);
      ALLOC1_SIGNAL_IN ( in_UPDATE_ADDRESS_SRC    ,"address_src"    ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN ( in_UPDATE_ADDRESS_DEST   ,"address_dest"   ,Tgeneral_data_t    ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN ( in_UPDATE_CONDITION      ,"condition"      ,Tbranch_condition_t,_param->_size_branch_condition);
      ALLOC1_SIGNAL_IN ( in_UPDATE_LAST_TAKE      ,"last_take"      ,Tcontrol_t         ,1);
      ALLOC1_SIGNAL_IN ( in_UPDATE_MISS_PREDICTION,"miss_prediction",Tcontrol_t         ,1);

      ALLOC1_INTERFACE_END(_param->_nb_inst_update);
    }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    std::string name;

    if (_param->_have_component_victim)
      {
	_component_sort = new morpheo::behavioural::generic::sort::Sort * [_param->_nb_inst_predict];

	for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
	  {
	    name = _name+"_sort_"+toString(i);
	    log_printf(INFO,Prediction_unit,FUNCTION,_("Create   : %s"),name.c_str());
	    
	    _component_sort [i] = new morpheo::behavioural::generic::sort::Sort
	      (name.c_str()
#ifdef STATISTICS
	       ,param_statistics
#endif
	       ,_param->_param_sort
	       ,_usage);
	    
	    _component->set_component (_component_sort [i] ->_component
#ifdef POSITION
				       , 50, 50, 10, 10
#endif
				       );
	  }

	{
	  name = _name+"_victim";
	  log_printf(INFO,Prediction_unit,FUNCTION,_("Create   : %s"),name.c_str());
	  
	  _component_victim = new morpheo::behavioural::generic::victim::Victim
	    (name.c_str()
#ifdef STATISTICS
	     ,param_statistics
#endif
	     ,_param->_param_victim
	     ,_usage);
	  
	  _component->set_component (_component_victim->_component
#ifdef POSITION
				     , 50, 50, 10, 10
#endif
				     );
	}
      }
    
    {
      name = _name+"_glue";
      log_printf(INFO,Prediction_unit,FUNCTION,_("Create   : %s"),name.c_str());
      
      _component_branch_target_buffer_glue = new morpheo::behavioural::core::multi_front_end::front_end::prediction_unit::branch_target_buffer::branch_target_buffer_glue::Branch_Target_Buffer_Glue
	(name.c_str()
#ifdef STATISTICS
	 ,param_statistics
#endif
	 ,_param->_param_branch_target_buffer_glue
	 ,_usage);
      
      _component->set_component (_component_branch_target_buffer_glue->_component
#ifdef POSITION
				 , 50, 50, 10, 10
#endif
				 );
    }
    
    {
      name = _name+"_register";
      log_printf(INFO,Prediction_unit,FUNCTION,_("Create   : %s"),name.c_str());
      
      _component_branch_target_buffer_register = new morpheo::behavioural::core::multi_front_end::front_end::prediction_unit::branch_target_buffer::branch_target_buffer_register::Branch_Target_Buffer_Register
	(name.c_str()
#ifdef STATISTICS
	 ,param_statistics
#endif
	 ,_param->_param_branch_target_buffer_register
	 ,_usage);
      
      _component->set_component (_component_branch_target_buffer_register->_component
#ifdef POSITION
				 , 50, 50, 10, 10
#endif
				 );
    }

    // ~~~~~[ Instanciation ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    std::string src,dest;

    if (_param->_have_component_victim)
      {
	//================================================================
	//=====[ Sort ]===================================================
	//================================================================
	
	for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
	{
	  src = _name+"_sort_"+toString(i);
	  log_printf(INFO,Prediction_unit,FUNCTION,_("Instance : %s"),src.c_str());
	  
	  {
	    dest = _name;
#ifdef POSITION
	    _component->interface_map (src ,"",
				       dest,"");
#endif
	    PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
	    PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
	  }

	  for (uint32_t j=0; j<_param->_associativity; j++)
	    {
	      dest = _name+"_register";
#ifdef POSITION
	      _component->interface_map (src ,"input_"  +toString(i),
					 dest,"predict_"+toString(i));
#endif
	      
	      COMPONENT_MAP(_component,src , "in_INPUT_"+toString(j)+"_VAL" ,
			               dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+"_HIT"        );
	      COMPONENT_MAP(_component,src , "in_INPUT_"+toString(j)+"_DATA",
		                       dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+"_ADDRESS_SRC");

	    }

          // 1 output
          // out_OUTPUT_VAL     -> glue
          // out_OUTPUT_INDEX   -> glue
          // out_OUTPUT_ADDRESS -> no exist
        }

	//================================================================
	//=====[ Victim ]=================================================
	//================================================================
	{
	  src = _name+"_victim";
	  log_printf(INFO,Prediction_unit,FUNCTION,_("Instance : %s"),src.c_str());
	  
	  {
	    dest = _name;
#ifdef POSITION
	    _component->interface_map (src ,"",
				       dest,"");
#endif
	    PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
	    PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");

	    // in_ACCESS_VAL     -> glue, register
	    //out_ACCESS_ACK     -> glue, register
	    // in_ACCESS_ADDRESS -> glue, register
	    // in_ACCESS_HIT     -> glue, register
	    // in_ACCESS_ENTITY  -> glue, register
	    //out_ACCESS_VICTIM  -> glue, register
	  }
	}
      }

    //====================================================================
    //=====[ Glue ]=======================================================
    //====================================================================
    {
      src = _name+"_glue";
      log_printf(INFO,Prediction_unit,FUNCTION,_("Instance : %s"),src.c_str());
      
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"",
				   dest,"");
#endif
	PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
	PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
      }

      for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"predict_"+toString(i),
				   dest,"predict_"+toString(i));
#endif

	PORT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_VAL"         ,
		            dest, "in_PREDICT_"+toString(i)+"_VAL"         );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_ACK"         ,
		            dest,"out_PREDICT_"+toString(i)+"_ACK"         );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_HIT"         ,
		            dest,"out_PREDICT_"+toString(i)+"_HIT"         );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_ADDRESS_SRC" ,
		            dest,"out_PREDICT_"+toString(i)+"_ADDRESS_SRC" );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_ADDRESS_DEST",
		            dest,"out_PREDICT_"+toString(i)+"_ADDRESS_DEST");
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_CONDITION"   ,
		            dest,"out_PREDICT_"+toString(i)+"_CONDITION"   );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_LAST_TAKE"   ,
		            dest,"out_PREDICT_"+toString(i)+"_LAST_TAKE"   );
	PORT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_IS_ACCURATE" ,
		            dest,"out_PREDICT_"+toString(i)+"_IS_ACCURATE" );

	dest = _name+"_register";
#ifdef POSITION
	_component->interface_map (src ,"predict_"+toString(i),
				   dest,"predict_"+toString(i));
#endif

	COMPONENT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_REGISTER_VAL",
		            dest, "in_PREDICT_"+toString(i)+"_VAL");
	COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_REGISTER_ACK",
		            dest,"out_PREDICT_"+toString(i)+"_ACK");

	for (uint32_t j=0; j<_param->_associativity; j++)
	  {
#ifdef POSITION
	    _component->interface_map (src ,"predict_"+toString(i)+"_"+toString(j),
				       dest,"predict_"+toString(i)+"_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_HIT"         ,
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_HIT"         );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_ADDRESS_SRC" ,
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_ADDRESS_SRC" );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_ADDRESS_DEST",
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_ADDRESS_DEST");
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_CONDITION"   ,
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_CONDITION"   );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_LAST_TAKE"   ,
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_LAST_TAKE"   );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_"+toString(j)+"_REGISTER_IS_ACCURATE" ,
			             dest,"out_PREDICT_"+toString(i)+"_"+toString(j)+         "_IS_ACCURATE" );
	  }

	if (_param->_have_component_victim)
	  {
	    dest = _name+"_sort_"+toString(i);
#ifdef POSITION
	    _component->interface_map (src ,"predict_"+toString(i),
				       dest,"output_0");
#endif

	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_SORT_VAL"  ,
			             dest,"out_OUTPUT_0_VAL"  );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_SORT_INDEX",
			             dest,"out_OUTPUT_0_INDEX");

	    dest = _name+"_victim";
#ifdef POSITION
	    _component->interface_map (src ,"predict_"+toString(i),
				       dest,"access_"+toString(i));
#endif
	    
	    COMPONENT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_VICTIM_VAL"    ,
			             dest, "in_ACCESS_"+toString(i)+"_VAL"    );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_VICTIM_ACK"    ,
			             dest,"out_ACCESS_"+toString(i)+"_ACK"    );
	    COMPONENT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_VICTIM_HIT"    ,
			             dest, "in_ACCESS_"+toString(i)+"_HIT"    );
	    if (not _param->_is_full_associative)
	    COMPONENT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_VICTIM_ADDRESS",
			             dest, "in_ACCESS_"+toString(i)+"_ADDRESS");
	    COMPONENT_MAP(_component,src ,"out_PREDICT_"+toString(i)+"_VICTIM_INDEX"  ,
		                     dest, "in_ACCESS_"+toString(i)+"_ENTITY" );
	    COMPONENT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_VICTIM_VICTIM" ,
		                     dest,"out_ACCESS_"+toString(i)+"_VICTIM" );
	  }
      }

      for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"decod_"+toString(i),
				   dest,"decod_"+toString(i));
#endif
	
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_VAL"        ,
		            dest, "in_DECOD_"+toString(i)+"_VAL"        );
	PORT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_ACK"        ,
		            dest,"out_DECOD_"+toString(i)+"_ACK"        );
	if (not _param->_is_full_associative)
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_ADDRESS_SRC",
		            dest, "in_DECOD_"+toString(i)+"_ADDRESS_SRC");

	dest = _name+"_register";
#ifdef POSITION
	_component->interface_map (src ,"decod_"+toString(i),
				   dest,"decod_"+toString(i));
#endif

	COMPONENT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_REGISTER_VAL",
		            dest, "in_DECOD_"+toString(i)+"_VAL");
	COMPONENT_MAP(_component,src , "in_DECOD_"+toString(i)+"_REGISTER_ACK",
		            dest,"out_DECOD_"+toString(i)+"_ACK");

	if (_param->_have_component_victim)
	  {
	    uint32_t j = _param->_nb_inst_predict+i;

	dest = _name+"_victim";
#ifdef POSITION
	_component->interface_map (src ,"predict_"+toString(i),
				   dest,"access_"+toString(j));
#endif

	COMPONENT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_VICTIM_VAL"    ,
		            dest, "in_ACCESS_"+toString(j)+"_VAL"    );
	COMPONENT_MAP(_component,src , "in_DECOD_"+toString(i)+"_VICTIM_ACK"    ,
		            dest,"out_ACCESS_"+toString(j)+"_ACK"    );
	if (not _param->_is_full_associative)
	COMPONENT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_VICTIM_ADDRESS",
		            dest, "in_ACCESS_"+toString(j)+"_ADDRESS");
	  }
      }

      for (uint32_t i=0; i<_param->_nb_inst_update; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"update_"+toString(i),
				   dest,"update_"+toString(i));
#endif
	
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_VAL"        ,
		            dest, "in_UPDATE_"+toString(i)+"_VAL"        );
	PORT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_ACK"        ,
		            dest,"out_UPDATE_"+toString(i)+"_ACK"        );
	if (not _param->_is_full_associative)
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_ADDRESS_SRC",
		            dest, "in_UPDATE_"+toString(i)+"_ADDRESS_SRC");

	dest = _name+"_register";
#ifdef POSITION
	_component->interface_map (src ,"update_"+toString(i),
				   dest,"update_"+toString(i));
#endif

	COMPONENT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_REGISTER_VAL",
		            dest, "in_UPDATE_"+toString(i)+"_VAL");
	COMPONENT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_REGISTER_ACK",
		            dest,"out_UPDATE_"+toString(i)+"_ACK");

	if (_param->_have_component_victim)
	  {
	    uint32_t j = _param->_nb_inst_predict+_param->_nb_inst_decod+i;

	dest = _name+"_victim";
#ifdef POSITION
	_component->interface_map (src ,"predict_"+toString(i),
				   dest,"access_"+toString(j));
#endif

	COMPONENT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_VICTIM_VAL"    ,
		            dest, "in_ACCESS_"+toString(j)+"_VAL"    );
	COMPONENT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_VICTIM_ACK"    ,
		            dest,"out_ACCESS_"+toString(j)+"_ACK"    );
	if (not _param->_is_full_associative)
	COMPONENT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_VICTIM_ADDRESS",
		            dest, "in_ACCESS_"+toString(j)+"_ADDRESS");
	  }
      }
    }
    
    //====================================================================
    //=====[ Register ]===================================================
    //====================================================================
    {
      src = _name+"_register";
      log_printf(INFO,Prediction_unit,FUNCTION,_("Instance : %s"),src.c_str());
      
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"",
				   dest,"");
#endif
	PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
	PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
      }

      for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"predict_"+toString(i),
				   dest,"predict_"+toString(i));
#endif

	if (_param->_have_port_context_id)
	PORT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_CONTEXT_ID",
		            dest, "in_PREDICT_"+toString(i)+"_CONTEXT_ID");
	PORT_MAP(_component,src , "in_PREDICT_"+toString(i)+"_ADDRESS"   ,
		            dest, "in_PREDICT_"+toString(i)+"_ADDRESS"   );

	// in_PREDICT_VAL          -> glue
	//out_PREDICT_ACK	   -> glue
	//out_PREDICT_HIT	   -> glue, sort
	//out_PREDICT_ADDRESS_SRC  -> glue, sort
	//out_PREDICT_ADDRESS_DEST -> glue
	//out_PREDICT_CONDITION	   -> glue
	//out_PREDICT_LAST_TAKE	   -> glue
	//out_PREDICT_IS_ACCURATE  -> glue
      }

      for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"decod_"+toString(i),
				   dest,"decod_"+toString(i));
#endif

	// in_DECOD_VAL    -> glue
	//out_DECOD_ACK	   -> glue
	if (_param->_have_port_context_id)
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_CONTEXT_ID"     ,
		            dest, "in_DECOD_"+toString(i)+"_CONTEXT_ID"     );
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_ADDRESS_SRC"    ,
		            dest, "in_DECOD_"+toString(i)+"_ADDRESS_SRC"    );
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_ADDRESS_DEST"   ,
		            dest, "in_DECOD_"+toString(i)+"_ADDRESS_DEST"   );
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_CONDITION"      ,
		            dest, "in_DECOD_"+toString(i)+"_CONDITION"      );
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_LAST_TAKE"      ,
		            dest, "in_DECOD_"+toString(i)+"_LAST_TAKE"      );
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_MISS_PREDICTION",
		            dest, "in_DECOD_"+toString(i)+"_MISS_PREDICTION");
	PORT_MAP(_component,src , "in_DECOD_"+toString(i)+"_IS_ACCURATE",
		            dest, "in_DECOD_"+toString(i)+"_IS_ACCURATE");

	if (_param->_have_component_victim)
	  {
	    uint32_t j = _param->_nb_inst_predict+i;

	    dest = _name+"_victim";
#ifdef POSITION
	    _component->interface_map (src ,"decod_"+toString(i),
				       dest,"access_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_HIT"      ,
			             dest, "in_ACCESS_"+toString(j)+"_HIT"   );
	    COMPONENT_MAP(_component,src ,"out_DECOD_"+toString(i)+"_HIT_INDEX",
			             dest, "in_ACCESS_"+toString(j)+"_ENTITY");
	    COMPONENT_MAP(_component,src , "in_DECOD_"+toString(i)+"_VICTIM"   ,
			             dest,"out_ACCESS_"+toString(j)+"_VICTIM");
	  }
      }

      for (uint32_t i=0; i<_param->_nb_inst_update; i++)
      {
	dest = _name;
#ifdef POSITION
	_component->interface_map (src ,"update_"+toString(i),
				   dest,"update_"+toString(i));
#endif

	// in_UPDATE_VAL    -> glue
	//out_UPDATE_ACK	   -> glue
	if (_param->_have_port_context_id)
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_CONTEXT_ID"     ,
		            dest, "in_UPDATE_"+toString(i)+"_CONTEXT_ID"     );
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_ADDRESS_SRC"    ,
		            dest, "in_UPDATE_"+toString(i)+"_ADDRESS_SRC"    );
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_ADDRESS_DEST"   ,
		            dest, "in_UPDATE_"+toString(i)+"_ADDRESS_DEST"   );
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_CONDITION"      ,
		            dest, "in_UPDATE_"+toString(i)+"_CONDITION"      );
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_LAST_TAKE"      ,
		            dest, "in_UPDATE_"+toString(i)+"_LAST_TAKE"      );
	PORT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_MISS_PREDICTION",
		            dest, "in_UPDATE_"+toString(i)+"_MISS_PREDICTION");

	if (_param->_have_component_victim)
	  {
	    uint32_t j = _param->_nb_inst_predict+_param->_nb_inst_decod+i;

	    dest = _name+"_victim";
#ifdef POSITION
	    _component->interface_map (src ,"update_"+toString(i),
				       dest,"access_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_HIT"      ,
			             dest, "in_ACCESS_"+toString(j)+"_HIT"   );
	    COMPONENT_MAP(_component,src ,"out_UPDATE_"+toString(i)+"_HIT_INDEX",
			             dest, "in_ACCESS_"+toString(j)+"_ENTITY");
	    COMPONENT_MAP(_component,src , "in_UPDATE_"+toString(i)+"_VICTIM"   ,
			             dest,"out_ACCESS_"+toString(j)+"_VICTIM");
	  }
      }
    }
    // ~~~~~[ Others ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

#if DEBUG_Branch_Target_Buffer == true
    _component->test_map();
#endif

#ifdef POSITION
    if (usage_is_set(_usage,USE_POSITION))
      _component->generate_file();
#endif

    log_printf(FUNC,Branch_Target_Buffer,FUNCTION,"End");
  };

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

}; // end namespace behavioural
}; // end namespace morpheo              
