/*
 * $Id: Icache_Access_allocation.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

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

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace icache_access {



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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Icache_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 "icache_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE("icache_req",WEST,OUT,_("Request to instruction cache"),_param->_nb_icache_port);
      
      ALLOC1_VALACK_OUT(out_ICACHE_REQ_VAL         ,VAL);
      ALLOC1_VALACK_IN ( in_ICACHE_REQ_ACK         ,ACK);
      ALLOC1_SIGNAL_OUT(out_ICACHE_REQ_THREAD_ID   ,"thread_id",Tcontext_t           ,_param->_size_icache_thread_id);
      ALLOC1_SIGNAL_OUT(out_ICACHE_REQ_PACKET_ID   ,"packet_id",Tpacket_t            ,_param->_size_icache_packet_id);
      ALLOC1_SIGNAL_OUT(out_ICACHE_REQ_ADDRESS     ,"address"  ,Ticache_address_t    ,_param->_size_address         );
      ALLOC1_SIGNAL_OUT(out_ICACHE_REQ_TYPE        ,"type"     ,Ticache_type_t       ,_param->_size_icache_type     );
    }

    // ~~~~~[ Interface "icache_rsp" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    {
      ALLOC1_INTERFACE("icache_rsp",WEST,IN ,_("Respons from instruction cache"),_param->_nb_icache_port);

      ALLOC1_VALACK_IN ( in_ICACHE_RSP_VAL         ,VAL);
      ALLOC1_VALACK_OUT(out_ICACHE_RSP_ACK         ,ACK);
      ALLOC1_SIGNAL_IN ( in_ICACHE_RSP_THREAD_ID   ,"thread_id"  ,Tcontext_t           ,_param->_size_icache_thread_id);
      ALLOC1_SIGNAL_IN ( in_ICACHE_RSP_PACKET_ID   ,"packet_id"  ,Tpacket_t            ,_param->_size_icache_packet_id);
      ALLOC1_SIGNAL_IN ( in_ICACHE_RSP_ERROR       ,"error"      ,Ticache_error_t      ,_param->_size_icache_error    );
    }
    {
      // NOTE : max_nb_instruction is too wide ...
      ALLOC2_INTERFACE("icache_rsp",WEST,IN ,_("Respons from instruction cache"),_param->_nb_icache_port,_param->_icache_nb_instruction[it1]);

      _ALLOC2_SIGNAL_IN ( in_ICACHE_RSP_INSTRUCTION ,"instruction",Ticache_instruction_t,_param->_size_instruction,_param->_nb_icache_port,_param->_icache_nb_instruction[it1]);
    }

    // ~~~~~[ Interface "context_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE("context_req",EAST,IN ,_("Request from context_unit."),_param->_nb_front_end, _param->_nb_context[it1]);

      _ALLOC2_VALACK_IN ( in_CONTEXT_REQ_VAL        ,VAL,_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_VALACK_OUT(out_CONTEXT_REQ_ACK        ,ACK,_param->_nb_front_end, _param->_nb_context[it1]);
//    _ALLOC2_SIGNAL_IN ( in_CONTEXT_REQ_THREAD_ID  ,"thread_id"  ,Tcontext_t           ,_param->_size_);
      _ALLOC2_SIGNAL_IN ( in_CONTEXT_REQ_PACKET_ID  ,"packet_id"  ,Tpacket_t            ,_param->_size_packet_id[it1][it2],_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_SIGNAL_IN ( in_CONTEXT_REQ_ADDRESS    ,"address"    ,Ticache_address_t    ,_param->_size_address            ,_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_SIGNAL_IN ( in_CONTEXT_REQ_TYPE       ,"type"       ,Ticache_type_t       ,_param->_size_icache_type        ,_param->_nb_front_end, _param->_nb_context[it1]);
    }

    // ~~~~~[ Interface "context_rsp" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE("context_rsp",EAST,OUT,_("Respons to context_unit."),_param->_nb_front_end, _param->_nb_context[it1]);

      _ALLOC2_VALACK_OUT(out_CONTEXT_RSP_VAL        ,VAL,_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_VALACK_IN ( in_CONTEXT_RSP_ACK        ,ACK,_param->_nb_front_end, _param->_nb_context[it1]);
//    _ALLOC2_SIGNAL_OUT(out_CONTEXT_RSP_THREAD_ID  ,"thread_id"  ,Tcontext_t           ,_param->_size_                   ,_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_SIGNAL_OUT(out_CONTEXT_RSP_PACKET_ID  ,"packet_id"  ,Tpacket_t            ,_param->_size_packet_id[it1][it2],_param->_nb_front_end, _param->_nb_context[it1]);
      _ALLOC2_SIGNAL_OUT(out_CONTEXT_RSP_ERROR      ,"error"      ,Ticache_error_t      ,_param->_size_icache_error       ,_param->_nb_front_end, _param->_nb_context[it1]);
    }
    {
      ALLOC3_INTERFACE("context_rsp",EAST,OUT,_("Respons to context_unit."),_param->_nb_front_end, _param->_nb_context[it1],_param->_nb_instruction[it1][it2]);

      _ALLOC3_SIGNAL_OUT(out_CONTEXT_RSP_INSTRUCTION,"instruction",Ticache_instruction_t,_param->_size_instruction,_param->_nb_front_end, _param->_nb_context[it1],_param->_nb_instruction[it1][it2]);
    }

    if (usage_is_set(_usage,USE_SYSTEMC))
      {
        // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef STATISTICS
        _internal_ICACHE_REQ_NB_ACCESS         = new uint32_t [_param->_nb_icache_port];
        _internal_ICACHE_REQ_NB_ACCESS_CONFLIT = new uint32_t [_param->_nb_icache_port];
#endif
      }

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

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

    log_end(Icache_Access,FUNCTION);
  };

}; // end namespace icache_access
}; // end namespace core

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