/*
 * $Id: Decod_queue_allocation.cpp 118 2009-05-20 22:01:32Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod_queue/include/Decod_queue.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace decod_unit {
namespace decod_queue {

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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Decod_queue"
#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 : "decod_in" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("decod_in",IN ,WEST,_("Input of decod_queue"), _param->_nb_inst_decod);

      ALLOC1_VALACK_IN ( in_DECOD_IN_VAL            ,VAL);
      ALLOC1_VALACK_OUT(out_DECOD_IN_ACK            ,ACK);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_CONTEXT_ID     ,"context_id"   ,Tcontext_t         ,_param->_size_context_id            );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_DEPTH          ,"depth"        ,Tdepth_t           ,_param->_size_depth                 );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_TYPE           ,"type"         ,Ttype_t            ,_param->_size_type                  );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_OPERATION      ,"operation"    ,Toperation_t       ,_param->_size_operation             );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NO_EXECUTE     ,"no_execute"   ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_IS_DELAY_SLOT  ,"is_delay_slot",Tcontrol_t         ,1                                   );
#ifdef DEBUG
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_ADDRESS        ,"address"      ,Tgeneral_data_t    ,_param->_size_instruction_address   );
#endif
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_ADDRESS_NEXT   ,"address_next" ,Tgeneral_data_t    ,_param->_size_instruction_address   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_HAS_IMMEDIAT   ,"has_immediat" ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_IMMEDIAT       ,"immediat"     ,Tgeneral_data_t    ,_param->_size_general_data          );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_READ_RA        ,"read_ra"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NUM_REG_RA     ,"num_reg_ra"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_READ_RB        ,"read_rb"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NUM_REG_RB     ,"num_reg_rb"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_READ_RC        ,"read_rc"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NUM_REG_RC     ,"num_reg_rc"   ,Tspecial_address_t ,_param->_size_special_register_logic);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_WRITE_RD       ,"write_rd"     ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NUM_REG_RD     ,"num_reg_rd"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_WRITE_RE       ,"write_re"     ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_NUM_REG_RE     ,"num_reg_re"   ,Tspecial_address_t ,_param->_size_special_register_logic);
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_EXCEPTION_USE  ,"exception_use",Texception_t       ,_param->_size_exception_use         );
      ALLOC1_SIGNAL_IN ( in_DECOD_IN_EXCEPTION      ,"exception"    ,Texception_t       ,_param->_size_exception_decod       );

      ALLOC1_INTERFACE_END(_param->_nb_inst_decod);
    }

    // ~~~~~[ Interface : "decod_out" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("decod_out",OUT,EAST,_("Output of decod_queue"), _param->_nb_inst_decod);

      ALLOC1_VALACK_OUT(out_DECOD_OUT_VAL            ,VAL);
      ALLOC1_VALACK_IN ( in_DECOD_OUT_ACK            ,ACK);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_CONTEXT_ID     ,"context_id"   ,Tcontext_t         ,_param->_size_context_id            );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_DEPTH          ,"depth"        ,Tdepth_t           ,_param->_size_depth                 );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_TYPE           ,"type"         ,Ttype_t            ,_param->_size_type                  );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_OPERATION      ,"operation"    ,Toperation_t       ,_param->_size_operation             );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NO_EXECUTE     ,"no_execute"   ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_IS_DELAY_SLOT  ,"is_delay_slot",Tcontrol_t         ,1                                   );
#ifdef DEBUG
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_ADDRESS        ,"address"      ,Tgeneral_data_t    ,_param->_size_instruction_address   );
#endif
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_ADDRESS_NEXT   ,"address_next" ,Tgeneral_data_t    ,_param->_size_instruction_address   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_HAS_IMMEDIAT   ,"has_immediat" ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_IMMEDIAT       ,"immediat"     ,Tgeneral_data_t    ,_param->_size_general_data          );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_READ_RA        ,"read_ra"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NUM_REG_RA     ,"num_reg_ra"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_READ_RB        ,"read_rb"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NUM_REG_RB     ,"num_reg_rb"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_READ_RC        ,"read_rc"      ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NUM_REG_RC     ,"num_reg_rc"   ,Tspecial_address_t ,_param->_size_special_register_logic);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_WRITE_RD       ,"write_rd"     ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NUM_REG_RD     ,"num_reg_rd"   ,Tgeneral_address_t ,_param->_size_general_register_logic);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_WRITE_RE       ,"write_re"     ,Tcontrol_t         ,1                                   );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_NUM_REG_RE     ,"num_reg_re"   ,Tspecial_address_t ,_param->_size_special_register_logic);
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_EXCEPTION_USE  ,"exception_use",Texception_t       ,_param->_size_exception_use         );
      ALLOC1_SIGNAL_OUT(out_DECOD_OUT_EXCEPTION      ,"exception"    ,Texception_t       ,_param->_size_exception_decod       );

      ALLOC1_INTERFACE_END(_param->_nb_inst_decod);
    }

    // ~~~~~[ Interface : "depth" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~            
    {
      ALLOC1_INTERFACE_BEGIN("depth",IN ,NORTH,_("Depth"), _param->_nb_context);

      ALLOC1_SIGNAL_IN ( in_DEPTH_MIN      ,"min"      ,Tdepth_t           ,_param->_size_depth);
      ALLOC1_SIGNAL_IN ( in_DEPTH_MAX      ,"max"      ,Tdepth_t           ,_param->_size_depth);
      ALLOC1_SIGNAL_IN ( in_DEPTH_FULL     ,"full"     ,Tcontrol_t         ,1);

      ALLOC1_INTERFACE_END(_param->_nb_context);
    }

    // ~~~~~[ Interface : "nb_inst" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~            
    {
      ALLOC1_INTERFACE_BEGIN("nb_inst",OUT,NORTH,_("Instruction's number"), _param->_nb_context);

      ALLOC1_SIGNAL_OUT(out_NB_INST_ALL    ,"all"      ,Tcounter_t         ,_param->_size_nb_inst_decod);

      ALLOC1_INTERFACE_END(_param->_nb_context);
    }

    if (usage_is_set(_usage,USE_SYSTEMC))
      {
    // ~~~~~[ Register ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    switch (_param->_queue_scheme)
      {
      case DECOD_QUEUE_SCHEME_ONE_FIFO   : ALLOC0(reg_QUEUE,std::list<decod_queue_entry_t*>); break;
      case DECOD_QUEUE_SCHEME_MULTI_FIFO : ALLOC1(reg_QUEUE,std::list<decod_queue_entry_t*>,_param->_nb_bank); break;
      }

    ALLOC1(reg_NB_INST,uint32_t,_param->_nb_context);

    // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ALLOC1(internal_DECOD_IN_ACK ,Tcontrol_t,_param->_nb_inst_decod);
    ALLOC1(internal_DECOD_OUT_VAL,Tcontrol_t,_param->_nb_inst_decod);
    ALLOC1(internal_DECOD_OUT_ACK,Tcontrol_t,_param->_nb_inst_decod);
      }
    
    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

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

    log_end(Decod_queue,FUNCTION);
  };

}; // end namespace decod_queue
}; // end namespace decod_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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