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

#include "Behavioural/Core/Dcache_Access/include/Dcache_Access.h"
#include "Behavioural/include/Allocation.h"
#include "Common/include/Max.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace dcache_access {



#undef  FUNCTION
#define FUNCTION "Dcache_Access::allocation"
  void Dcache_Access::allocation (
#ifdef STATISTICS
			       morpheo::behavioural::Parameters_Statistics * param_statistics
#else
			       void
#endif
			       )
  {
    log_begin(Dcache_Access,FUNCTION);

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Dcache_Access"
#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 "dcache_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("dcache_req", OUT, NORTH, _("Request to data cache"),_param->_nb_dcache_port);
      
      ALLOC1_VALACK_OUT(out_DCACHE_REQ_VAL         ,VAL);
      ALLOC1_VALACK_IN ( in_DCACHE_REQ_ACK         ,ACK);
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_THREAD_ID   ,"thread_id",Tcontext_t           ,_param->_size_dcache_thread_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_address);
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_WDATA       ,"wdata"    ,Tdcache_data_t       ,_param->_size_data);
      ALLOC1_SIGNAL_OUT(out_DCACHE_REQ_TYPE        ,"type"     ,Tdcache_type_t       ,_param->_size_dcache_type);

      ALLOC1_INTERFACE_END(param->_nb_dcache_port);
    }
									    
    // ~~~~~[ Interface "dcache_rsp" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    {
      ALLOC1_INTERFACE_BEGIN("dcache_rsp", IN , NORTH, _("Respons from data cache"),_param->_nb_dcache_port);

      ALLOC1_VALACK_IN ( in_DCACHE_RSP_VAL         ,VAL);
      ALLOC1_VALACK_OUT(out_DCACHE_RSP_ACK         ,ACK);
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_THREAD_ID   ,"thread_id",Tcontext_t           ,_param->_size_dcache_thread_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_data);
      ALLOC1_SIGNAL_IN ( in_DCACHE_RSP_ERROR       ,"error"    ,Tdcache_error_t      ,_param->_size_dcache_error);

      ALLOC1_INTERFACE_END(_param->_nb_dcache_port);
    }

    // ~~~~~[ Interface "lsq_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC3_INTERFACE_BEGIN("lsq_req", IN, SOUTH, _("Request from load_store queue"), _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);

      _ALLOC3_VALACK_IN ( in_LSQ_REQ_VAL            ,VAL, _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_VALACK_OUT(out_LSQ_REQ_ACK            ,ACK, _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_IN ( in_LSQ_REQ_THREAD_ID      ,"thread_id",Tcontext_t           ,_param->_size_thread_id [it1][it2], _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_IN ( in_LSQ_REQ_PACKET_ID      ,"packet_id",Tpacket_t            ,_param->_size_packet_id [it1][it2], _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_IN ( in_LSQ_REQ_ADDRESS        ,"address"  ,Tdcache_address_t    ,_param->_size_address             , _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_IN ( in_LSQ_REQ_WDATA          ,"wdata"    ,Tdcache_data_t       ,_param->_size_data                , _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_IN ( in_LSQ_REQ_TYPE           ,"type"     ,Tdcache_type_t       ,_param->_size_dcache_type         , _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);

      ALLOC3_INTERFACE_END(_param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
    }

    // ~~~~~[ Interface "lsq_rsp" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC3_INTERFACE_BEGIN("lsq_rsp",OUT, SOUTH, _("Respons to load_store queue"), _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      
      _ALLOC3_VALACK_OUT(out_LSQ_RSP_VAL            ,VAL, _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_VALACK_IN ( in_LSQ_RSP_ACK            ,ACK, _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_OUT(out_LSQ_RSP_THREAD_ID      ,"thread_id",Tcontext_t           ,_param->_size_thread_id [it1][it2], _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_OUT(out_LSQ_RSP_PACKET_ID      ,"packet_id",Tpacket_t            ,_param->_size_packet_id [it1][it2], _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_OUT(out_LSQ_RSP_RDATA          ,"rdata"    ,Tdcache_data_t       ,_param->_size_data                , _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
      _ALLOC3_SIGNAL_OUT(out_LSQ_RSP_ERROR          ,"error"    ,Tdcache_error_t      ,_param->_size_dcache_error       , _param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);

      ALLOC3_INTERFACE_END(_param->_nb_execute_loop, _param->_nb_load_store_unit[it1], _param->_nb_cache_access[it1][it2]);
    }

    // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef STATISTICS
    if (usage_is_set(_usage,USE_SYSTEMC))
      {
        ALLOC1(_internal_DCACHE_REQ_NB_ACCESS        ,uint32_t,_param->_nb_dcache_port);
        ALLOC1(_internal_DCACHE_REQ_NB_ACCESS_CONFLIT,uint32_t,_param->_nb_dcache_port);
      }
#endif

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    _priority  = new generic::priority::Priority (_name+"_priority",
						  _param->_priority          ,
						  _param->_load_balancing    ,
						  _param->_nb_execute_loop   ,
						  _param->_nb_load_store_unit,
						  _param->_nb_execute_loop   );

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

    log_end(Dcache_Access,FUNCTION);
  };

}; // end namespace dcache_access
}; // end namespace core

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