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

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_execute_unit {
namespace execute_unit {
namespace load_store_unit {



#undef  FUNCTION
#define FUNCTION "Load_store_unit::allocation"
  void Load_store_unit::allocation (void)
  {
    log_printf(FUNC,Load_store_unit,FUNCTION,"Begin");

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Load_store_unit"
#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 "memory_in" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("memory_in",IN,WEST,_("Instruction from Reservations station"),_param->_nb_inst_memory);

      ALLOC1_VALACK_IN ( in_MEMORY_IN_VAL                  ,VAL);
      ALLOC1_VALACK_OUT(out_MEMORY_IN_ACK                  ,ACK);
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_CONTEXT_ID           ,"context_id"           ,Tcontext_t        ,_param->_size_context_id           );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_FRONT_END_ID         ,"front_end_id"         ,Tcontext_t        ,_param->_size_front_end_id         );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_OOO_ENGINE_ID        ,"ooo_engine_id"        ,Tcontext_t        ,_param->_size_ooo_engine_id        );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_PACKET_ID            ,"packet_id"            ,Tpacket_t         ,_param->_size_rob_ptr              );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_OPERATION            ,"operation"            ,Toperation_t      ,_param->_size_operation            );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_TYPE                 ,"type"                 ,Ttype_t           ,_param->_size_type                 );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_STORE_QUEUE_PTR_WRITE,"store_queue_ptr_write",Tlsq_ptr_t        ,_param->_size_store_queue_ptr      );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_LOAD_QUEUE_PTR_WRITE ,"load_queue_ptr_write" ,Tlsq_ptr_t        ,_param->_size_load_queue_ptr       );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_HAS_IMMEDIAT         ,"has_immediat"         ,Tcontrol_t        ,1                                  );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_IMMEDIAT             ,"immediat"             ,Tgeneral_data_t   ,_param->_size_general_data         );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_DATA_RA              ,"data_ra"              ,Tgeneral_data_t   ,_param->_size_general_data         );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_DATA_RB              ,"data_rb"              ,Tgeneral_data_t   ,_param->_size_general_data         );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_DATA_RC              ,"data_rc"              ,Tspecial_data_t   ,_param->_size_special_data         );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_WRITE_RD             ,"write_rd"             ,Tcontrol_t        ,1                                  );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_NUM_REG_RD           ,"num_reg_rd"           ,Tgeneral_address_t,_param->_size_general_register     );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_WRITE_RE             ,"write_re"             ,Tcontrol_t        ,1                                  );
      ALLOC1_SIGNAL_IN ( in_MEMORY_IN_NUM_REG_RE           ,"num_reg_re"           ,Tspecial_address_t,_param->_size_special_register     );
    
      ALLOC1_INTERFACE_END(_param->_nb_inst_memory);
    }

    // ~~~~~[ Interface "memory_out" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("memory_out",OUT,EAST,_("Instruction to write queue"),_param->_nb_inst_memory);

      ALLOC1_VALACK_OUT(out_MEMORY_OUT_VAL          ,VAL);
      ALLOC1_VALACK_IN ( in_MEMORY_OUT_ACK          ,ACK);
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_CONTEXT_ID   ,"context_id"    ,Tcontext_t        ,_param->_size_context_id       );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_FRONT_END_ID ,"front_end_id"  ,Tcontext_t        ,_param->_size_front_end_id     );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_OOO_ENGINE_ID,"ooo_engine_id" ,Tcontext_t        ,_param->_size_ooo_engine_id    );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_PACKET_ID    ,"packet_id"     ,Tpacket_t         ,_param->_size_rob_ptr          );
//    ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_OPERATION    ,"operation"     ,Toperation_t      ,_param->_size_operation        );
//    ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_TYPE         ,"type"          ,Ttype_t           ,_param->_size_type             );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_WRITE_RD     ,"write_rd"      ,Tcontrol_t        ,1                              );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_NUM_REG_RD   ,"num_reg_rd"    ,Tgeneral_address_t,_param->_size_general_register );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_DATA_RD      ,"data_rd"       ,Tgeneral_data_t   ,_param->_size_general_data     );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_WRITE_RE     ,"write_re"      ,Tcontrol_t        ,1                              );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_NUM_REG_RE   ,"num_reg_re"    ,Tspecial_address_t,_param->_size_special_register );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_DATA_RE      ,"data_re"       ,Tspecial_data_t   ,_param->_size_special_data     );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_EXCEPTION    ,"exception"     ,Texception_t      ,_param->_size_exception        );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_NO_SEQUENCE  ,"no_sequence"   ,Tcontrol_t        ,1                              );
      ALLOC1_SIGNAL_OUT(out_MEMORY_OUT_ADDRESS      ,"address"       ,Taddress_t        ,_param->_size_instruction_address);
    
      ALLOC1_INTERFACE_END(_param->_nb_inst_memory);
    }

    // ~~~~~[ Interface "dcache_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("dcache_req",OUT,NORTH,_("Request port to dcache"),_param->_nb_cache_port);

      ALLOC1_VALACK_OUT(out_DCACHE_REQ_VAL        ,VAL);
      ALLOC1_VALACK_IN ( in_DCACHE_REQ_ACK        ,ACK);
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_CONTEXT_ID ,"context_id",Tcontext_t       ,_param->_size_dcache_context_id  );
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_PACKET_ID  ,"packet_id" ,Tpacket_t        ,_param->_size_dcache_packet_id   );
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_ADDRESS    ,"address"   ,Tdcache_address_t,_param->_size_general_data);
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_TYPE       ,"type"      ,Tdcache_type_t   ,_param->_size_dcache_type );
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_WDATA      ,"wdata"     ,Tdcache_data_t   ,_param->_size_general_data);
    
      ALLOC1_INTERFACE_END(_param->_nb_cache_port);
    }

    // ~~~~~[ Interface "dcache_rsp" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("dcache_rsp",IN,NORTH,_("Respons port from dcache"),_param->_nb_cache_port);

      ALLOC1_VALACK_IN ( in_DCACHE_RSP_VAL        ,VAL);
      ALLOC1_VALACK_OUT(out_DCACHE_RSP_ACK        ,ACK);
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_CONTEXT_ID ,"context_id",Tcontext_t     ,_param->_size_dcache_context_id  );
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_PACKET_ID  ,"packet_id" ,Tpacket_t      ,_param->_size_dcache_packet_id   );
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_RDATA      ,"rdata"     ,Tdcache_data_t ,_param->_size_general_data);
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_ERROR      ,"error"     ,Tdcache_error_t,_param->_size_dcache_error);

      ALLOC1_INTERFACE_END(_param->_nb_cache_port);
    }
    // ~~~~~[ Interface "bypass_memory" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    {
      ALLOC1_INTERFACE_BEGIN("bypass_memory",OUT,NORTH,_("Bypass between the load queue and the reservation station"),_param->_nb_bypass_memory);
	    
      ALLOC1_VALACK_OUT(out_BYPASS_MEMORY_VAL           ,VAL);
      ALLOC1_SIGNAL_OUT(out_BYPASS_MEMORY_OOO_ENGINE_ID ,"ooo_engine_id",Tcontext_t        , _param->_size_ooo_engine_id   );
      ALLOC1_SIGNAL_OUT(out_BYPASS_MEMORY_NUM_REG       ,"num_reg"      ,Tgeneral_address_t, _param->_size_general_register);
      ALLOC1_SIGNAL_OUT(out_BYPASS_MEMORY_DATA          ,"data"         ,Tgeneral_data_t   , _param->_size_general_data    );

      ALLOC1_INTERFACE_END(_param->_nb_bypass_memory);
    }

    // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//     internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ = new Tlsq_ptr_t [_param->_nb_cache_port];

//     internal_MEMORY_IN_ACK           = new Tcontrol_t      [_param->_nb_inst_memory];
//     internal_MEMORY_OUT_VAL          = new Tcontrol_t      [_param->_nb_inst_memory];
//     internal_MEMORY_OUT_SELECT_QUEUE = new Tselect_queue_t [_param->_nb_inst_memory];
//     internal_MEMORY_OUT_PTR          = new Tlsq_ptr_t      [_param->_nb_inst_memory];
    
//     internal_DCACHE_RSP_ACK          = new Tcontrol_t      [_param->_nb_cache_port];
//     internal_DCACHE_REQ_VAL          = new Tcontrol_t      [_param->_nb_cache_port];
//     internal_DCACHE_REQ_SELECT_QUEUE = new Tselect_queue_t [_param->_nb_cache_port];

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

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

    _store_queue                      = new Tstore_queue_entry_t              [_param->_size_store_queue];
    _load_queue	                      = new Tload_queue_entry_t               [_param->_size_load_queue];
    _speculative_access_queue         = new Tspeculative_access_queue_entry_t [_param->_size_speculative_access_queue];
    _speculative_access_queue_control = new morpheo::behavioural::generic::queue_control::Queue_Control (_param->_size_speculative_access_queue);

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

}; // end namespace load_store_unit
}; // end namespace execute_unit
}; // end namespace multi_execute_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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