/*
 * $Id: Write_queue_allocation.cpp 114 2009-04-16 22:35:37Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit/Write_unit/Write_queue/include/Write_queue.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_write_unit {
namespace write_unit {
namespace write_queue {


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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,_param->_type
#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 "Write_queue_in" ]--------------------------------    
     {
       ALLOC0_INTERFACE_BEGIN ("write_queue_in", IN, WEST, "Input of write_queue");
       
       ALLOC0_VALACK_IN ( in_WRITE_QUEUE_IN_VAL,VAL);
       ALLOC0_VALACK_OUT(out_WRITE_QUEUE_IN_ACK,ACK);
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_CONTEXT_ID   ,"context_id"   ,Tcontext_t        ,_param->_size_context_id       );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_FRONT_END_ID ,"front_end_id" ,Tcontext_t        ,_param->_size_front_end_id     );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id    );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_PACKET_ID    ,"packet_id"    ,Tpacket_t         ,_param->_size_rob_ptr          );
//     ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_OPERATION    ,"operation"    ,Toperation_t      ,_param->_size_operation        );
//     ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_TYPE         ,"type"         ,Ttype_t           ,_param->_size_type             );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_WRITE_RD     ,"write_rd"     ,Tcontrol_t        ,1                              );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_NUM_REG_RD   ,"num_reg_rd"   ,Tgeneral_address_t,_param->_size_general_register );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_DATA_RD      ,"data_rd"      ,Tgeneral_data_t   ,_param->_size_general_data     );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_WRITE_RE     ,"write_re"     ,Tcontrol_t        ,1                              );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_NUM_REG_RE   ,"num_reg_re"   ,Tspecial_address_t,_param->_size_special_register );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_DATA_RE      ,"data_re"      ,Tspecial_data_t   ,_param->_size_special_data     );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_EXCEPTION    ,"exception"    ,Texception_t      ,_param->_size_exception        );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_NO_SEQUENCE  ,"no_sequence"  ,Tcontrol_t        ,1                              );
       ALLOC0_SIGNAL_IN ( in_WRITE_QUEUE_IN_ADDRESS      ,"address"      ,Taddress_t        ,_param->_size_instruction_address);

       ALLOC0_INTERFACE_END();
     }

    // -----[ Interface "Write_queue_out" ]-------------------------------
     {
       ALLOC0_INTERFACE_BEGIN("write_queue_out", OUT, EAST, "Output of write_queue");
       
       ALLOC0_VALACK_OUT(out_WRITE_QUEUE_OUT_VAL,VAL);
       ALLOC0_VALACK_IN ( in_WRITE_QUEUE_OUT_ACK,ACK);
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_CONTEXT_ID   ,"context_id"   ,Tcontext_t     ,_param->_size_context_id   );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_FRONT_END_ID ,"front_end_id" ,Tcontext_t     ,_param->_size_front_end_id );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t     ,_param->_size_ooo_engine_id);
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_PACKET_ID    ,"packet_id"    ,Tpacket_t      ,_param->_size_rob_ptr      );
//     ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_OPERATION    ,"operation"    ,Toperation_t   ,_param->_size_operation    );
//     ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_TYPE         ,"type"         ,Ttype_t        ,_param->_size_type         );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_FLAGS        ,"flags"        ,Tspecial_data_t,_param->_size_special_data );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_EXCEPTION    ,"exception"    ,Texception_t   ,_param->_size_exception    );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_NO_SEQUENCE  ,"no_sequence"  ,Tcontrol_t     ,1                          );
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_ADDRESS      ,"address"      ,Taddress_t     ,_param->_size_instruction_address);
       ALLOC0_SIGNAL_OUT(out_WRITE_QUEUE_OUT_DATA         ,"data"         ,Tgeneral_data_t,_param->_size_general_data );

       ALLOC0_INTERFACE_END();
     }

    // -----[ Interface "gpr_write" ]-------------------------------------
     {
       ALLOC1_INTERFACE_BEGIN("gpr_write", OUT, SOUTH ,"Output of write_queue", _param->_nb_gpr_write);

       ALLOC1_VALACK_OUT(out_GPR_WRITE_VAL,VAL);
       ALLOC1_VALACK_IN ( in_GPR_WRITE_ACK,ACK);
       ALLOC1_SIGNAL_OUT(out_GPR_WRITE_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id   );
       ALLOC1_SIGNAL_OUT(out_GPR_WRITE_NUM_REG      ,"num_reg"      ,Tgeneral_address_t,_param->_size_general_register);
       ALLOC1_SIGNAL_OUT(out_GPR_WRITE_DATA         ,"data"         ,Tgeneral_data_t   ,_param->_size_general_data    );

       ALLOC1_INTERFACE_END(_param->_nb_gpr_write);
     }

    // -----[ Interface "spr_write" ]-------------------------------------
     {
       ALLOC1_INTERFACE_BEGIN("spr_write", OUT, SOUTH ,"Output of write_queue", _param->_nb_spr_write);

       ALLOC1_VALACK_OUT(out_SPR_WRITE_VAL,VAL);
       ALLOC1_VALACK_IN ( in_SPR_WRITE_ACK,ACK);
       ALLOC1_SIGNAL_OUT(out_SPR_WRITE_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id   );
       ALLOC1_SIGNAL_OUT(out_SPR_WRITE_NUM_REG      ,"num_reg"      ,Tspecial_address_t,_param->_size_special_register);
       ALLOC1_SIGNAL_OUT(out_SPR_WRITE_DATA         ,"data"         ,Tspecial_data_t   ,_param->_size_special_data    );

       ALLOC1_INTERFACE_END(_param->_nb_spr_write);
     }

    // -----[ Interface "bypass_write" ]----------------------------------
     {
       ALLOC1_INTERFACE_BEGIN("bypass_write", OUT, NORTH ,"Output of internal write_queue", _param->_nb_bypass_write);
       
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id   );
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_GPR_VAL      ,"gpr_val"      ,Tcontrol_t        ,1                             );
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_GPR_NUM_REG  ,"gpr_num_reg"  ,Tgeneral_address_t,_param->_size_general_register);
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_GPR_DATA     ,"gpr_data"     ,Tgeneral_data_t   ,_param->_size_general_data    );
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_SPR_VAL      ,"spr_val"      ,Tcontrol_t        ,1                             );
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_SPR_NUM_REG  ,"spr_num_reg"  ,Tspecial_address_t,_param->_size_special_register);
       ALLOC1_SIGNAL_OUT(out_BYPASS_WRITE_SPR_DATA     ,"spr_data"     ,Tspecial_data_t   ,_param->_size_special_data    );

       ALLOC1_INTERFACE_END(_param->_nb_bypass_write);
     }

    // ~~~~~[ Register ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

     _queue = new std::list<write_queue_entry_t *>;

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
#ifdef VHDL
     if (usage_is_set(_usage,USE_VHDL))
       {
         _param_queue = new morpheo::behavioural::generic::queue::Parameters
           (_param->_size_queue,
            _param->_size_internal_queue,
            _param->_nb_bypass_write,
            false,
            false
            );
         
         std::string queue_name = _name + "_queue";
         _component_queue = new morpheo::behavioural::generic::queue::Queue
           (queue_name.c_str()
#ifdef STATISTICS
            ,NULL
#endif
            ,_param_queue
            ,USE_VHDL);
         
         _component->set_component(_component_queue->_component
#ifdef POSITION
                                   , 50, 50, 50, 50
#endif
                                   , INSTANCE_LIBRARY
                                   );
       }
#endif

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

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

}; // end namespace write_queue
}; // end namespace write_unit
}; // end namespace multi_write_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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