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

#include "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Address_management/include/Address_management.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace ifetch_unit {
namespace address_management {

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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Address_management"
#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 : "address" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC0_INTERFACE_BEGIN("address", OUT, SOUTH, _("Access at request icache."));

      ALLOC0_VALACK_OUT (out_ADDRESS_VAL                        ,VAL);
      ALLOC0_VALACK_IN  ( in_ADDRESS_ACK                        ,ACK);
      ALLOC0_SIGNAL_OUT (out_ADDRESS_INSTRUCTION_ADDRESS        ,"instruction_address"        ,Tgeneral_address_t,_param->_size_instruction_address     );
      ALLOC0_SIGNAL_OUT (out_ADDRESS_INST_IFETCH_PTR            ,"inst_ifetch_ptr"            ,Tinst_ifetch_ptr_t,_param->_size_inst_ifetch_ptr         );
      ALLOC0_SIGNAL_OUT (out_ADDRESS_BRANCH_STATE               ,"branch_state"               ,Tbranch_state_t   ,_param->_size_branch_state            );
      ALLOC0_SIGNAL_OUT (out_ADDRESS_BRANCH_UPDATE_PREDICTION_ID,"branch_update_prediction_id",Tprediction_ptr_t ,_param->_size_depth);

      ALLOC0_INTERFACE_END();
    }

    {
      ALLOC1_INTERFACE_BEGIN("address", OUT, SOUTH, _("Access at request icache."),_param->_nb_instruction);

      ALLOC1_SIGNAL_OUT(out_ADDRESS_INSTRUCTION_ENABLE         ,"instruction_enable"         ,Tcontrol_t        ,1);

      ALLOC1_INTERFACE_END(_param->_nb_instruction);
    }

    // ~~~~~[ Interface : "predict" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC0_INTERFACE_BEGIN("predict", IN, NORTH, _("Request the prediction unit."));

      ALLOC0_VALACK_OUT (out_PREDICT_VAL                        ,VAL);
      ALLOC0_VALACK_IN  ( in_PREDICT_ACK                        ,ACK);
      ALLOC0_SIGNAL_OUT (out_PREDICT_PC_PREVIOUS                ,"pc_previous"                ,Tgeneral_address_t,_param->_size_instruction_address);
      ALLOC0_SIGNAL_OUT (out_PREDICT_PC_CURRENT                 ,"pc_current"                 ,Tgeneral_address_t,_param->_size_instruction_address);
      ALLOC0_SIGNAL_OUT (out_PREDICT_PC_CURRENT_IS_DS_TAKE      ,"pc_current_is_ds_take"      ,Tcontrol_t        ,1);
      ALLOC0_SIGNAL_IN  ( in_PREDICT_PC_NEXT                    ,"pc_next"                    ,Tgeneral_address_t,_param->_size_instruction_address);
      ALLOC0_SIGNAL_IN  ( in_PREDICT_PC_NEXT_IS_DS_TAKE         ,"pc_next_is_ds_take"         ,Tcontrol_t        ,1);
//    ALLOC0_SIGNAL_IN  ( in_PREDICT_BRANCH_IS_CURRENT          ,"branch_is_current"          ,Tcontrol_t        ,1);
      ALLOC0_SIGNAL_IN  ( in_PREDICT_BRANCH_STATE               ,"branch_state"               ,Tbranch_state_t   ,_param->_size_branch_state);
      ALLOC0_SIGNAL_IN  ( in_PREDICT_BRANCH_UPDATE_PREDICTION_ID,"branch_update_prediction_id",Tprediction_ptr_t ,_param->_size_depth);
      ALLOC0_SIGNAL_IN  ( in_PREDICT_INST_IFETCH_PTR            ,"inst_ifetch_ptr"            ,Tinst_ifetch_ptr_t,_param->_size_inst_ifetch_ptr);

      ALLOC0_INTERFACE_END();
    }
    {
      ALLOC1_INTERFACE_BEGIN("predict", IN, NORTH, _("Request the prediction unit."),_param->_nb_instruction);

      ALLOC1_SIGNAL_IN (in_PREDICT_INSTRUCTION_ENABLE          ,"instruction_enable"         ,Tcontrol_t        ,1);

      ALLOC1_INTERFACE_END(_param->_nb_instruction);
    }

    // ~~~~~[ Interface "event" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC0_INTERFACE_BEGIN("event", IN, SOUTH, _("Event (miss, exception ...)"));

      ALLOC0_VALACK_IN ( in_EVENT_VAL          ,VAL);
      ALLOC0_VALACK_OUT(out_EVENT_ACK          ,ACK);
      ALLOC0_SIGNAL_IN ( in_EVENT_ADDRESS         ,"address"         ,Tgeneral_address_t,_param->_size_instruction_address);
      ALLOC0_SIGNAL_IN ( in_EVENT_ADDRESS_NEXT    ,"address_next"    ,Tgeneral_address_t,_param->_size_instruction_address);
      ALLOC0_SIGNAL_IN ( in_EVENT_ADDRESS_NEXT_VAL,"address_next_val",Tcontrol_t,1);
      ALLOC0_SIGNAL_IN ( in_EVENT_IS_DS_TAKE      ,"is_ds_take"      ,Tcontrol_t,1);

      ALLOC0_INTERFACE_END();
    }

    // ~~~~~[ Internal  ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    if (usage_is_set(_usage,USE_SYSTEMC))
      {
        ALLOC1(reg_PC_ACCESS_INSTRUCTION_ENABLE ,Tcontrol_t,_param->_nb_instruction);
        ALLOC1(reg_PC_CURRENT_INSTRUCTION_ENABLE,Tcontrol_t,_param->_nb_instruction);
        ALLOC1(reg_PC_NEXT_INSTRUCTION_ENABLE   ,Tcontrol_t,_param->_nb_instruction);
      }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
#ifdef POSITION
     if (usage_is_set(_usage,USE_POSITION))
       _component->generate_file();
#endif

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

}; // end namespace address_management
}; // end namespace ifetch_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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