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

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

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


  void Two_Level_Branch_Predictor::vhdl_body (Vhdl & vhdl)
  {
    log_printf(FUNC,Two_Level_Branch_Predictor,"vhdl_body","Begin");

    list<string> list_port_map;

    if (_param._have_bht)
      {
	list_port_map.clear();

	vhdl.set_body_component_port_map (list_port_map,"in_CLOCK ","in_CLOCK ");
	vhdl.set_body_component_port_map (list_port_map,"in_NRESET","in_NRESET");

	for (uint32_t i=0; i<_param._nb_prediction; i++)
	  {
	    vhdl.set_body_component_port_map (list_port_map," in_PREDICT_VAL_"+toString(i)+"              ","    in_PREDICT_VAL_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_ACK_"+toString(i)+"              ","signal_PREDICT_BHT_ACK_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_PREDICT_ADDRESS_"+toString(i)+"          ","signal_PREDICT_BHT_ADDRESS_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_HISTORY_"+toString(i)+"          ","signal_PREDICT_BHT_HISTORY_"+toString(i));
	  }
	
	for (uint32_t i=0; i<_param._nb_branch_complete; i++)
	  {
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_VAL_"+toString(i)+"      ","    in_BRANCH_COMPLETE_VAL_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_BRANCH_COMPLETE_ACK_"+toString(i)+"      ","signal_BRANCH_COMPLETE_BHT_ACK_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_ADDRESS_"+toString(i)+"  ","signal_BRANCH_COMPLETE_BHT_ADDRESS_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_HISTORY_"+toString(i)+"  ","    in_BRANCH_COMPLETE_BHT_HISTORY_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_DIRECTION_"+toString(i)+"","    in_BRANCH_COMPLETE_DIRECTION_"+toString(i));
	  }
	
	vhdl.set_body_component ("component_Branch_History_Table",_name+"_Branch_History_Table",list_port_map);
      }

    if (_param._have_pht)
      {
	list_port_map.clear();

	vhdl.set_body_component_port_map (list_port_map,"in_CLOCK ","in_CLOCK ");
	vhdl.set_body_component_port_map (list_port_map,"in_NRESET","in_NRESET");

	for (uint32_t i=0; i<_param._nb_prediction; i++)
	  {
	    vhdl.set_body_component_port_map (list_port_map," in_PREDICT_VAL_"+toString(i)+"              ","    in_PREDICT_VAL_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_ACK_"+toString(i)+"              ","signal_PREDICT_PHT_ACK_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_PREDICT_ADDRESS_"+toString(i)+"          ","signal_PREDICT_PHT_ADDRESS_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_HISTORY_"+toString(i)+"          ","   out_PREDICT_PHT_HISTORY_"+toString(i));
	  }
	
	for (uint32_t i=0; i<_param._nb_branch_complete; i++)
	  {
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_VAL_"+toString(i)+"      ","    in_BRANCH_COMPLETE_VAL_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map,"out_BRANCH_COMPLETE_ACK_"+toString(i)+"      ","signal_BRANCH_COMPLETE_PHT_ACK_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_ADDRESS_"+toString(i)+"  ","signal_BRANCH_COMPLETE_PHT_ADDRESS_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_HISTORY_"+toString(i)+"  ","    in_BRANCH_COMPLETE_PHT_HISTORY_"+toString(i));
	    vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_DIRECTION_"+toString(i)+"","    in_BRANCH_COMPLETE_DIRECTION_"+toString(i));
	  }
	
	vhdl.set_body_component ("component_Pattern_History_Table",_name+"_Pattern_History_Table",list_port_map);
      }

    list_port_map.clear();
    
    for (uint32_t i=0; i<_param._nb_prediction; i++)
      {
	if (_param._have_bht)
	  {
	vhdl.set_body_component_port_map (list_port_map," in_PREDICT_BHT_ACK_"+toString(i)+"            ","signal_PREDICT_BHT_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_BHT_ADDRESS_"+toString(i)+"        ","signal_PREDICT_BHT_ADDRESS_"+toString(i));
	  }											   										  
	if (_param._have_pht)								   							  
	  {											   										  
	vhdl.set_body_component_port_map (list_port_map," in_PREDICT_PHT_ACK_"+toString(i)+"            ","signal_PREDICT_PHT_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_PHT_ADDRESS_"+toString(i)+"        ","signal_PREDICT_PHT_ADDRESS_"+toString(i));
	  }											   										  
	if (_param._have_bht and _param._have_pht)						   					  
	  {											   										  
	vhdl.set_body_component_port_map (list_port_map," in_PREDICT_BHT_HISTORY_"+toString(i)+"        ","signal_PREDICT_BHT_HISTORY_"+toString(i));
	  }											   										  
	vhdl.set_body_component_port_map (list_port_map,"out_PREDICT_ACK_"+toString(i)+"                ","   out_PREDICT_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map," in_PREDICT_ADDRESS_"+toString(i)+"            ","    in_PREDICT_ADDRESS_"+toString(i));
      }
    
    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	if (_param._have_bht)
	  {
	vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_BHT_ACK_"+toString(i)+"    ","signal_BRANCH_COMPLETE_BHT_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map,"out_BRANCH_COMPLETE_BHT_ADDRESS_"+toString(i)+"","signal_BRANCH_COMPLETE_BHT_ADDRESS_"+toString(i));
	  }										   					       				  
	if (_param._have_pht)
	  {
	vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_PHT_ACK_"+toString(i)+"    ","signal_BRANCH_COMPLETE_PHT_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map,"out_BRANCH_COMPLETE_PHT_ADDRESS_"+toString(i)+"","signal_BRANCH_COMPLETE_PHT_ADDRESS_"+toString(i));
	  }										   					       				  
	if (_param._have_bht and _param._have_pht)
	  {
        vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_BHT_HISTORY_"+toString(i)+"","    in_BRANCH_COMPLETE_BHT_HISTORY_"+toString(i));
	  }										   					       				  
	vhdl.set_body_component_port_map (list_port_map,"out_BRANCH_COMPLETE_ACK_"+toString(i)+"        ","   out_BRANCH_COMPLETE_ACK_"+toString(i));
	vhdl.set_body_component_port_map (list_port_map," in_BRANCH_COMPLETE_ADDRESS_"+toString(i)+"    ","    in_BRANCH_COMPLETE_ADDRESS_"+toString(i));
      }

    vhdl.set_body_component ("component_Two_Level_Branch_Predictor_Glue",_name+"_Two_Level_Branch_Predictor_Glue",list_port_map);

    if (_param._have_bht)
      for (uint32_t i=0; i<_param._nb_prediction; i++)
	vhdl.set_body("out_PREDICT_BHT_HISTORY_"+toString(i)+" <= signal_PREDICT_BHT_HISTORY_"+toString(i)+";");
    
    log_printf(FUNC,Two_Level_Branch_Predictor,"vhdl_body","End");
  };

}; // 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
