/*
 * $Id$
 *
 * [ 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" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC_INTERFACE("address", OUT, SOUTH, "Access at request icache.");

      ALLOC_VALACK_OUT (out_ADDRESS_VAL                        ,VAL);
      ALLOC_VALACK_IN  ( in_ADDRESS_ACK                        ,ACK);
      ALLOC_SIGNAL_OUT (out_ADDRESS_INSTRUCTION_ADDRESS        ,"instruction_address"        ,Tgeneral_address_t,_param->_size_address                 );
      ALLOC_SIGNAL_OUT (out_ADDRESS_INST_IFETCH_PTR            ,"inst_ifetch_ptr"            ,Tinst_ifetch_ptr_t,_param->_size_instruction_ptr         );
      ALLOC_SIGNAL_OUT (out_ADDRESS_BRANCH_STATE               ,"branch_state"               ,Tbranch_state_t   ,_param->_size_branch_state            );
      ALLOC_SIGNAL_OUT (out_ADDRESS_BRANCH_UPDATE_PREDICTION_ID,"branch_update_prediction_id",Tprediction_ptr_t ,_param->_size_branch_update_prediction);
    }

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

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

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

      ALLOC_VALACK_OUT (out_PREDICT_VAL                        ,VAL);
      ALLOC_VALACK_IN  ( in_PREDICT_ACK                        ,ACK);
      ALLOC_SIGNAL_OUT (out_PREDICT_PC_PREVIOUS                ,"pc_previous"                ,Tgeneral_address_t,_param->_size_address);
      ALLOC_SIGNAL_OUT (out_PREDICT_PC_CURRENT                 ,"pc_current"                 ,Tgeneral_address_t,_param->_size_address);
      ALLOC_SIGNAL_OUT (out_PREDICT_PC_CURRENT_IS_DS_TAKE      ,"pc_current_is_ds_take"      ,Tcontrol_t        ,1);
      ALLOC_SIGNAL_IN  ( in_PREDICT_PC_NEXT                    ,"pc_next"                    ,Tgeneral_address_t,_param->_size_address);
      ALLOC_SIGNAL_IN  ( in_PREDICT_PC_NEXT_IS_DS_TAKE         ,"pc_next_is_ds_take"         ,Tcontrol_t        ,1);
      ALLOC_SIGNAL_IN  ( in_PREDICT_INST_IFETCH_PTR            ,"inst_ifetch_ptr"            ,Tinst_ifetch_ptr_t,_param->_size_instruction_ptr);
      ALLOC_SIGNAL_IN  ( in_PREDICT_BRANCH_STATE               ,"branch_state"               ,Tbranch_state_t   ,_param->_size_branch_state);
      ALLOC_SIGNAL_IN  ( in_PREDICT_BRANCH_UPDATE_PREDICTION_ID,"branch_update_prediction_id",Tprediction_ptr_t ,_param->_size_branch_update_prediction);
    }
    {
      ALLOC1_INTERFACE("predict", IN, NORTH, "Request the prediction unit.",_param->_nb_instruction);

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

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

      ALLOC_VALACK_IN ( in_EVENT_VAL    ,VAL);
      ALLOC_VALACK_OUT(out_EVENT_ACK    ,ACK);
      ALLOC_SIGNAL_IN ( in_EVENT_ADDRESS,"address",Tgeneral_address_t,_param->_size_address);
    }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    reg_PC_CURRENT_INSTRUCTION_ENABLE = new Tcontrol_t [_param->_nb_instruction];
    reg_PC_NEXT_INSTRUCTION_ENABLE    = new Tcontrol_t [_param->_nb_instruction];

#ifdef 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              
