/*
 * $Id: Front_end_Glue_allocation.cpp 119 2009-05-25 17:40:26Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Front_end_Glue/include/Front_end_Glue.h"
#include "Behavioural/include/Allocation.h"
#include "Common/include/Max.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace front_end_glue {



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

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Front_end_Glue"
#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 : "ifetch" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE_BEGIN("ifetch",OUT,SOUTH,_("ifetch"),_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);

      _ALLOC2_SIGNAL_OUT(out_IFETCH_DECOD_UNIT_CONTEXT_ID                     ,"DECOD_UNIT_CONTEXT_ID"          ,Tcontext_t           ,_param->_size_context_id,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);

      ALLOC2_INTERFACE_END(_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
    }

    // ~~~~~[ Interface : "decod" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE_BEGIN("decod",OUT,EAST,_("decod"),_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);

      _ALLOC2_SIGNAL_OUT(out_DECOD_CONTEXT_ID                                 ,"CONTEXT_ID"                     ,Tcontext_t           ,_param->_size_context_id,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
      _ALLOC2_SIGNAL_IN ( in_DECOD_DECOD_UNIT_CONTEXT_ID                      ,"DECOD_UNIT_CONTEXT_ID"          ,Tcontext_t           ,_param->_size_context_id,_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);

      ALLOC2_INTERFACE_END(_param->_nb_decod_unit,_param->_nb_inst_decod[it1]);
    }

    // ~~~~~[ Interface : "branch_complete" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("branch_complete",IN,EAST,_("branch_complete"),_param->_nb_inst_branch_complete);

      ALLOC1_SIGNAL_IN  ( in_BRANCH_COMPLETE_VAL                              ,"VAL"                            ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_BRANCH_COMPLETE_ACK                              ,"ACK"                            ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_BRANCH_COMPLETE_MISS_PREDICTION                  ,"MISS_PREDICTION"                ,Tcontrol_t           ,1);
      
      ALLOC1_SIGNAL_OUT (out_BRANCH_COMPLETE_PREDICTION_UNIT_VAL              ,"PREDICTION_UNIT_VAL"            ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_BRANCH_COMPLETE_PREDICTION_UNIT_ACK              ,"PREDICTION_UNIT_ACK"            ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_BRANCH_COMPLETE_PREDICTION_UNIT_MISS_PREDICTION  ,"PREDICTION_UNIT_MISS_PREDICTION",Tcontrol_t           ,1);
      
      ALLOC1_SIGNAL_OUT (out_BRANCH_COMPLETE_CONTEXT_STATE_VAL                ,"CONTEXT_STATE_VAL"              ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_BRANCH_COMPLETE_CONTEXT_STATE_ACK                ,"CONTEXT_STATE_ACK"              ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_BRANCH_COMPLETE_CONTEXT_STATE_MISS_PREDICTION    ,"CONTEXT_STATE_MISS_PREDICTION"  ,Tcontrol_t           ,1);

      ALLOC1_INTERFACE_END(_param->_nb_inst_branch_complete);
    }

    // ~~~~~[ Interface "event" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("event",OUT,EAST,_("event"),_param->_nb_context);

      ALLOC1_SIGNAL_OUT (out_EVENT_VAL                                         ,"VAL"                           ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_ACK                                         ,"ACK"                           ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_ADDRESS                                     ,"ADDRESS"                       ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT (out_EVENT_ADDRESS_NEXT                                ,"ADDRESS_NEXT"                  ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT (out_EVENT_ADDRESS_NEXT_VAL                            ,"ADDRESS_NEXT_VAL"              ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_IS_DS_TAKE                                  ,"IS_DS_TAKE"                    ,Tcontrol_t           ,1);
                                                                                                            
      ALLOC1_SIGNAL_OUT (out_EVENT_IFETCH_UNIT_VAL                             ,"IFETCH_UNIT_VAL"               ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_IFETCH_UNIT_ACK                             ,"IFETCH_UNIT_ACK"               ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_IFETCH_UNIT_ADDRESS                         ,"IFETCH_UNIT_ADDRESS"           ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT (out_EVENT_IFETCH_UNIT_ADDRESS_NEXT                    ,"IFETCH_UNIT_ADDRESS_NEXT"      ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_OUT (out_EVENT_IFETCH_UNIT_ADDRESS_NEXT_VAL                ,"IFETCH_UNIT_ADDRESS_NEXT_VAL"  ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_IFETCH_UNIT_IS_DS_TAKE                      ,"IFETCH_UNIT_IS_DS_TAKE"        ,Tcontrol_t           ,1);

      ALLOC1_SIGNAL_OUT (out_EVENT_PREDICTION_UNIT_VAL                         ,"PREDICTION_UNIT_VAL"           ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_PREDICTION_UNIT_ACK                         ,"PREDICTION_UNIT_ACK"           ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_PREDICTION_UNIT_TYPE                        ,"PREDICTION_UNIT_TYPE"          ,Tevent_type_t        ,_param->_size_event_type);
      ALLOC1_SIGNAL_OUT (out_EVENT_PREDICTION_UNIT_DEPTH                       ,"PREDICTION_UNIT_DEPTH"         ,Tdepth_t             ,_param->_size_depth);
                                                                                                            
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_VAL                           ,"CONTEXT_STATE_VAL"             ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_OUT (out_EVENT_CONTEXT_STATE_ACK                           ,"CONTEXT_STATE_ACK"             ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_ADDRESS                       ,"CONTEXT_STATE_ADDRESS"         ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_ADDRESS_NEXT                  ,"CONTEXT_STATE_ADDRESS_NEXT"    ,Taddress_t           ,_param->_size_instruction_address);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_ADDRESS_NEXT_VAL              ,"CONTEXT_STATE_ADDRESS_NEXT_VAL",Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_IS_DS_TAKE                    ,"CONTEXT_STATE_IS_DS_TAKE"      ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_TYPE                          ,"CONTEXT_STATE_TYPE"            ,Tevent_type_t        ,_param->_size_event_type);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_DEPTH                         ,"CONTEXT_STATE_DEPTH"           ,Tdepth_t             ,_param->_size_depth);
      ALLOC1_SIGNAL_IN  ( in_EVENT_CONTEXT_STATE_FLUSH_ONLY                    ,"CONTEXT_STATE_FLUSH_ONLY"      ,Tcontrol_t           ,1);


      ALLOC1_INTERFACE_END(_param->_nb_context);
    }

    // ~~~~~[ Interface : "depth" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("depth",OUT,EAST,_("depth"),_param->_nb_context);

//    ALLOC1_SIGNAL_OUT (out_DEPTH_CURRENT                                     ,"CURRENT"                       ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_OUT (out_DEPTH_MIN                                         ,"MIN"                           ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_OUT (out_DEPTH_MAX                                         ,"MAX"                           ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_OUT (out_DEPTH_FULL                                        ,"FULL"                          ,Tcontrol_t           ,1);
                                                                                                                
      ALLOC1_SIGNAL_IN  ( in_DEPTH_PREDICTION_UNIT_VAL                         ,"PREDICTION_UNIT_VAL"           ,Tcontrol_t           ,1);
      ALLOC1_SIGNAL_IN  ( in_DEPTH_PREDICTION_UNIT_CURRENT                     ,"PREDICTION_UNIT_CURRENT"       ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_IN  ( in_DEPTH_PREDICTION_UNIT_MIN                         ,"PREDICTION_UNIT_MIN"           ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_IN  ( in_DEPTH_PREDICTION_UNIT_MAX                         ,"PREDICTION_UNIT_MAX"           ,Tdepth_t             ,_param->_size_depth  );
      ALLOC1_SIGNAL_IN  ( in_DEPTH_PREDICTION_UNIT_FULL                        ,"PREDICTION_UNIT_FULL"          ,Tcontrol_t           ,1);
                                                                                                                
      ALLOC1_SIGNAL_OUT (out_DEPTH_CONTEXT_STATE_MIN                           ,"CONTEXT_STATE_MIN"             ,Tdepth_t             ,_param->_size_depth  );

      ALLOC1_INTERFACE_END(_param->_nb_context);
    }
    {
      ALLOC2_INTERFACE_BEGIN("depth",OUT,EAST,_("depth"),_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);

//    _ALLOC2_SIGNAL_OUT(out_DEPTH_DECOD_UNIT_CURRENT                          ,"DECOD_UNIT_CURRENT"            ,Tdepth_t             ,_param->_size_depth  ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
      _ALLOC2_SIGNAL_OUT(out_DEPTH_DECOD_UNIT_MIN                              ,"DECOD_UNIT_MIN"                ,Tdepth_t             ,_param->_size_depth  ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
      _ALLOC2_SIGNAL_OUT(out_DEPTH_DECOD_UNIT_MAX                              ,"DECOD_UNIT_MAX"                ,Tdepth_t             ,_param->_size_depth  ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
      _ALLOC2_SIGNAL_OUT(out_DEPTH_DECOD_UNIT_FULL                             ,"DECOD_UNIT_FULL"               ,Tcontrol_t           ,1                    ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);

      ALLOC2_INTERFACE_END(_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
    }

    // ~~~~~[ Interface : "context" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE_BEGIN("context",OUT,EAST,_("context"),_param->_nb_decod_unit,_param->_translate_context_id_from_decod_unit[it1].size());
      
      _ALLOC2_SIGNAL_OUT(out_CONTEXT_DECOD_UNIT_DEPTH_VAL                      ,"DECOD_UNIT_DEPTH_VAL"          ,Tcontrol_t           ,1                    ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);
      _ALLOC2_SIGNAL_OUT(out_CONTEXT_DECOD_UNIT_DEPTH                          ,"DECOD_UNIT_DEPTH"              ,Tdepth_t             ,_param->_size_depth  ,_param->_nb_decod_unit,_param->_decod_unit_nb_context [it1]);

      ALLOC2_INTERFACE_END(_param->_nb_decod_unit,_param->_translate_context_id_from_decod_unit[it1].size());
    }

    // ~~~~~[ Interface : "nb_inst" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("nb_inst",OUT,EAST,_("nb inst"),_param->_nb_context);

      ALLOC1_SIGNAL_OUT(out_NB_INST_DECOD_ALL                                  ,"DECOD_ALL"                     ,Tcounter_t           ,_param->_size_nb_inst_decod);
      ALLOC1_SIGNAL_IN ( in_NB_INST_DECOD_UNIT_DECOD_ALL                       ,"DECOD_UNIT_DECOD_ALL"          ,Tcounter_t           ,_param->_size_nb_inst_decod);
      ALLOC1_SIGNAL_OUT(out_NB_INST_CONTEXT_STATE_DECOD_ALL                    ,"CONTEXT_STATE_DECOD_ALL"       ,Tcounter_t           ,_param->_size_nb_inst_decod);

      ALLOC1_INTERFACE_END(_param->_nb_context);
    }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

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

    log_end(Front_end_Glue,FUNCTION);
  };

}; // end namespace front_end_glue
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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