/*
 * $Id: Execution_unit_to_Write_unit_allocation.cpp 97 2008-12-19 15:34:00Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Network/Execution_unit_to_Write_unit/include/Execution_unit_to_Write_unit.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace network {
namespace execution_unit_to_write_unit {



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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Execution_unit_to_Write_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 "execute_unit_out" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     {
       ALLOC2_INTERFACE("execute_unit_out", IN, EAST, "Output of execution_unit", _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);

       _ALLOC2_VALACK_IN ( in_EXECUTE_UNIT_OUT_VAL,VAL, _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_VALACK_OUT(out_EXECUTE_UNIT_OUT_ACK,ACK, _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_CONTEXT_ID   ,"context_id"   ,Tcontext_t        ,_param->_size_context_id      , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_FRONT_END_ID ,"front_end_id" ,Tcontext_t        ,_param->_size_front_end_id    , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id   , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_PACKET_ID    ,"packet_id"    ,Tpacket_t         ,_param->_size_rob_ptr         , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
     //_ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_OPERATION    ,"operation"    ,Toperation_t      ,_param->_size_operation       , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
     //_ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_TYPE         ,"type"         ,Ttype_t           ,_param->_size_type            , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_WRITE_RD     ,"write_rd"     ,Tcontrol_t        ,1                             , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_NUM_REG_RD   ,"num_reg_rd"   ,Tgeneral_address_t,_param->_size_general_register, _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_DATA_RD      ,"data_rd"      ,Tgeneral_data_t   ,_param->_size_general_data    , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_WRITE_RE     ,"write_re"     ,Tcontrol_t        ,1                             , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_NUM_REG_RE   ,"num_reg_re"   ,Tspecial_address_t,_param->_size_special_register, _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_DATA_RE      ,"data_re"      ,Tspecial_data_t   ,_param->_size_special_data    , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_EXCEPTION    ,"exception"    ,Texception_t      ,_param->_size_exception       , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_NO_SEQUENCE  ,"no_sequence"  ,Tcontrol_t        ,1                             , _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
       _ALLOC2_SIGNAL_IN ( in_EXECUTE_UNIT_OUT_ADDRESS      ,"address"      ,Taddress_t        ,_param->_size_instruction_address, _param->_nb_execute_unit, _param->_nb_execute_unit_port[it1]);
     }

    // ~~~~~[ Interface "write_unit_in" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     {
       ALLOC1_INTERFACE("write_unit_in", OUT, WEST, "Input of write_unit", _param->_nb_write_unit);

       ALLOC1_VALACK_OUT(out_WRITE_UNIT_IN_VAL,VAL);
       ALLOC1_VALACK_IN ( in_WRITE_UNIT_IN_ACK,ACK);
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_CONTEXT_ID   ,"context_id"   ,Tcontext_t        ,_param->_size_context_id      );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_FRONT_END_ID ,"front_end_id" ,Tcontext_t        ,_param->_size_front_end_id    );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id   );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_PACKET_ID    ,"packet_id"    ,Tpacket_t         ,_param->_size_rob_ptr         );
     //ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_OPERATION    ,"operation"    ,Toperation_t      ,_param->_size_operation       );
     //ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_TYPE         ,"type"         ,Ttype_t           ,_param->_size_type            );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_WRITE_RD     ,"write_rd"     ,Tcontrol_t        ,1                             );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_NUM_REG_RD   ,"num_reg_rd"   ,Tgeneral_address_t,_param->_size_general_register);
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_DATA_RD      ,"data_rd"      ,Tgeneral_data_t   ,_param->_size_general_data    );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_WRITE_RE     ,"write_re"     ,Tcontrol_t        ,1                             );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_NUM_REG_RE   ,"num_reg_re"   ,Tspecial_address_t,_param->_size_special_register);
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_DATA_RE      ,"data_re"      ,Tspecial_data_t   ,_param->_size_special_data    );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_EXCEPTION    ,"exception"    ,Texception_t      ,_param->_size_exception       );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_NO_SEQUENCE  ,"no_sequence"  ,Tcontrol_t        ,1                             );
       ALLOC1_SIGNAL_OUT(out_WRITE_UNIT_IN_ADDRESS      ,"address"      ,Taddress_t        ,_param->_size_instruction_address);
     }
    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

    if (usage_is_set(_usage,USE_SYSTEMC))
      {
     _destination = new std::list<uint32_t> ** [_param->_nb_execute_unit];
     for (uint32_t i=0; i<_param->_nb_execute_unit; i++)
       {
	 _destination [i] = new std::list<uint32_t> * [_param->_nb_execute_unit_port[i]];
	 for (uint32_t j=0; j<_param->_nb_execute_unit_port[i]; j++)
	   {
	     _destination [i][j] = new std::list<uint32_t> [_param->_nb_thread];
	   }
       }
      }

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

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

}; // end namespace execution_unit_to_write_unit
}; // end namespace network
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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