#ifndef morpheo_behavioural_core_multi_ooo_engine_ooo_engine_rename_unit_Rename_unit_h
#define morpheo_behavioural_core_multi_ooo_engine_ooo_engine_rename_unit_Rename_unit_h

/*
 * $Id: Rename_unit.h 123 2009-06-08 20:43:30Z rosiere $
 *
 * [ Description ]
 * 
 */

#ifdef SYSTEMC
#include "systemc.h"
#endif

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/include/Parameters.h"
#include "Behavioural/include/Types.h"

#ifdef STATISTICS
#include "Behavioural/include/Stat.h"
#endif
#include "Behavioural/include/Component.h"
#ifdef VHDL
#include "Behavioural/include/Vhdl.h"
#endif
#include "Behavioural/include/Usage.h"

#include "Common/include/ToString.h"
#include "Common/include/Debug.h"

#include <iostream>

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Rename_select/include/Rename_select.h"
#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/include/Register_translation_unit.h"
#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Load_Store_pointer_unit/include/Load_Store_pointer_unit.h"
#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Rename_unit_Glue/include/Rename_unit_Glue.h"

namespace morpheo {
namespace behavioural {

namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace rename_unit {


  class Rename_unit 
#if SYSTEMC
    : public sc_module
#endif
  {
    // -----[ fields ]----------------------------------------------------
    // Parameters
  protected : const std::string  _name;
  protected : const Parameters * _param;
  private   : const Tusage_t     _usage;

#ifdef STATISTICS
  public    : Stat                           * _stat;
#endif

  public    : Component                      * _component;
  private   : Interfaces                     * _interfaces;

#ifdef SYSTEMC
    // ~~~~~[ Interface ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // ~~~~~[ Interface : "" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_CLOCK                      *  in_CLOCK        ;
  public    : SC_IN (Tcontrol_t)            *  in_NRESET       ;

    // ~~~~~[ Interface : "rename_in" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_VAL               ;//[nb_front_end][nb_inst_decod]
  public    : SC_OUT(Tcontrol_t        )  *** out_RENAME_IN_ACK               ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontext_t        )  ***  in_RENAME_IN_FRONT_END_ID      ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontext_t        )  ***  in_RENAME_IN_CONTEXT_ID        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tdepth_t          )  ***  in_RENAME_IN_DEPTH             ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Ttype_t           )  ***  in_RENAME_IN_TYPE              ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Toperation_t      )  ***  in_RENAME_IN_OPERATION         ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_NO_EXECUTE        ;//[nb_front_end][nb_inst_decod]
//public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_HAVE_EVENT        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_LAST_EVENT        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_IS_DELAY_SLOT     ;//[nb_front_end][nb_inst_decod]
#ifdef DEBUG
  public    : SC_IN (Taddress_t        )  ***  in_RENAME_IN_ADDRESS           ;//[nb_front_end][nb_inst_decod]
#endif
  public    : SC_IN (Taddress_t        )  ***  in_RENAME_IN_ADDRESS_NEXT      ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_HAS_IMMEDIAT      ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tgeneral_data_t   )  ***  in_RENAME_IN_IMMEDIAT          ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_READ_RA           ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tgeneral_address_t)  ***  in_RENAME_IN_NUM_REG_RA        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_READ_RB           ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tgeneral_address_t)  ***  in_RENAME_IN_NUM_REG_RB        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_READ_RC           ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tspecial_address_t)  ***  in_RENAME_IN_NUM_REG_RC        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_WRITE_RD          ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tgeneral_address_t)  ***  in_RENAME_IN_NUM_REG_RD        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tcontrol_t        )  ***  in_RENAME_IN_WRITE_RE          ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Tspecial_address_t)  ***  in_RENAME_IN_NUM_REG_RE        ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Texception_t      )  ***  in_RENAME_IN_EXCEPTION_USE     ;//[nb_front_end][nb_inst_decod]
  public    : SC_IN (Texception_t      )  ***  in_RENAME_IN_EXCEPTION         ;//[nb_front_end][nb_inst_decod]

    // ~~~~~[ Interface "insert" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_VAL                  ;//[nb_inst_insert]
  public    : SC_IN (Tcontrol_t        )   **  in_INSERT_ACK                  ;//[nb_inst_insert]
  public    : SC_OUT(Tcontext_t        )   ** out_INSERT_FRONT_END_ID         ;//[nb_inst_insert]
  public    : SC_OUT(Tcontext_t        )   ** out_INSERT_CONTEXT_ID           ;//[nb_inst_insert]
  public    : SC_OUT(Tdepth_t          )   ** out_INSERT_DEPTH                ;//[nb_inst_insert]
  public    : SC_OUT(Ttype_t           )   ** out_INSERT_TYPE                 ;//[nb_inst_insert]
  public    : SC_OUT(Toperation_t      )   ** out_INSERT_OPERATION            ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_NO_EXECUTE           ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_LAST_EVENT           ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_IS_DELAY_SLOT        ;//[nb_inst_insert]
#ifdef DEBUG
  public    : SC_OUT(Taddress_t        )   ** out_INSERT_ADDRESS              ;//[nb_inst_insert]
#endif
  public    : SC_OUT(Taddress_t        )   ** out_INSERT_ADDRESS_NEXT         ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_HAS_IMMEDIAT         ;//[nb_inst_insert]
  public    : SC_OUT(Tgeneral_data_t   )   ** out_INSERT_IMMEDIAT             ;//[nb_inst_insert]
  public    : SC_OUT(Tlsq_ptr_t        )   ** out_INSERT_STORE_QUEUE_PTR_WRITE;//[nb_inst_insert]
  public    : SC_OUT(Tlsq_ptr_t        )   ** out_INSERT_STORE_QUEUE_PTR_READ ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_STORE_QUEUE_EMPTY    ;//[nb_inst_insert]
  public    : SC_OUT(Tlsq_ptr_t        )   ** out_INSERT_LOAD_QUEUE_PTR_WRITE ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_READ_RA              ;//[nb_inst_insert]
#ifdef DEBUG
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RA_LOG       ;//[nb_inst_insert]
#endif
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RA_PHY       ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_READ_RB              ;//[nb_inst_insert]
#ifdef DEBUG
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RB_LOG       ;//[nb_inst_insert]
#endif
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RB_PHY       ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_READ_RC              ;//[nb_inst_insert]
#ifdef DEBUG
  public    : SC_OUT(Tspecial_address_t)   ** out_INSERT_NUM_REG_RC_LOG       ;//[nb_inst_insert]
#endif
  public    : SC_OUT(Tspecial_address_t)   ** out_INSERT_NUM_REG_RC_PHY       ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_WRITE_RD             ;//[nb_inst_insert]
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RD_LOG       ;//[nb_inst_insert]
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RD_PHY_OLD   ;//[nb_inst_insert]
  public    : SC_OUT(Tgeneral_address_t)   ** out_INSERT_NUM_REG_RD_PHY_NEW   ;//[nb_inst_insert]
  public    : SC_OUT(Tcontrol_t        )   ** out_INSERT_WRITE_RE             ;//[nb_inst_insert]
  public    : SC_OUT(Tspecial_address_t)   ** out_INSERT_NUM_REG_RE_LOG       ;//[nb_inst_insert]
  public    : SC_OUT(Tspecial_address_t)   ** out_INSERT_NUM_REG_RE_PHY_OLD   ;//[nb_inst_insert]
  public    : SC_OUT(Tspecial_address_t)   ** out_INSERT_NUM_REG_RE_PHY_NEW   ;//[nb_inst_insert]
  public    : SC_OUT(Texception_t      )   ** out_INSERT_EXCEPTION_USE        ;//[nb_inst_insert]
  public    : SC_OUT(Texception_t      )   ** out_INSERT_EXCEPTION            ;//[nb_inst_insert]

    // ~~~~~[ Interface "retire" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_VAL                  ;//[nb_inst_retire]
  public    : SC_OUT(Tcontrol_t        )   ** out_RETIRE_ACK                  ;//[nb_inst_retire]
  public    : SC_IN (Tcontext_t        )   **  in_RETIRE_FRONT_END_ID         ;//[nb_inst_retire]
  public    : SC_IN (Tcontext_t        )   **  in_RETIRE_CONTEXT_ID           ;//[nb_inst_retire]
//public    : SC_IN (Ttype_t           )   **  in_RETIRE_TYPE                 ;//[nb_inst_retire]
//public    : SC_IN (Toperation_t      )   **  in_RETIRE_OPERATION            ;//[nb_inst_retire]
  public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_USE_STORE_QUEUE      ;//[nb_inst_retire]
  public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_USE_LOAD_QUEUE       ;//[nb_inst_retire]
  public    : SC_IN (Tlsq_ptr_t        )   **  in_RETIRE_STORE_QUEUE_PTR_WRITE;//[nb_inst_retire]
  public    : SC_IN (Tlsq_ptr_t        )   **  in_RETIRE_LOAD_QUEUE_PTR_WRITE ;//[nb_inst_retire]
//   public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_READ_RA              ;//[nb_inst_retire]
//   public    : SC_IN (Tgeneral_address_t)   **  in_RETIRE_NUM_REG_RA_PHY       ;//[nb_inst_retire]
//   public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_READ_RB              ;//[nb_inst_retire]
//   public    : SC_IN (Tgeneral_address_t)   **  in_RETIRE_NUM_REG_RB_PHY       ;//[nb_inst_retire]
//   public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_READ_RC              ;//[nb_inst_retire]
//   public    : SC_IN (Tspecial_address_t)   **  in_RETIRE_NUM_REG_RC_PHY       ;//[nb_inst_retire]
  public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_WRITE_RD             ;//[nb_inst_retire]
  public    : SC_IN (Tgeneral_address_t)   **  in_RETIRE_NUM_REG_RD_LOG       ;//[nb_inst_retire]
  public    : SC_IN (Tgeneral_address_t)   **  in_RETIRE_NUM_REG_RD_PHY_OLD   ;//[nb_inst_retire]
  public    : SC_IN (Tgeneral_address_t)   **  in_RETIRE_NUM_REG_RD_PHY_NEW   ;//[nb_inst_retire]
  public    : SC_IN (Tcontrol_t        )   **  in_RETIRE_WRITE_RE             ;//[nb_inst_retire]
  public    : SC_IN (Tspecial_address_t)   **  in_RETIRE_NUM_REG_RE_LOG       ;//[nb_inst_retire]
  public    : SC_IN (Tspecial_address_t)   **  in_RETIRE_NUM_REG_RE_PHY_OLD   ;//[nb_inst_retire]
  public    : SC_IN (Tspecial_address_t)   **  in_RETIRE_NUM_REG_RE_PHY_NEW   ;//[nb_inst_retire]

    // ~~~~~[ Interface "retire_event" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_IN (Tcontrol_t        )  ***  in_RETIRE_EVENT_VAL            ;//[nb_front_end][nb_context]
  public    : SC_OUT(Tcontrol_t        )  *** out_RETIRE_EVENT_ACK            ;//[nb_front_end][nb_context]
  public    : SC_IN (Tevent_state_t    )  ***  in_RETIRE_EVENT_STATE          ;//[nb_front_end][nb_context]
//public    : SC_IN (Tcontrol_t        )  ***  in_RETIRE_EVENT_FLUSH          ;//[nb_front_end][nb_context]
  public    : SC_IN (Tcontrol_t        )  ***  in_RETIRE_EVENT_STOP           ;//[nb_front_end][nb_context]

    // ~~~~~[ Interface : "spr_read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  public    : SC_IN (Tspr_t            )  ***  in_SPR_READ_SR                 ;//[nb_front_end][nb_context]

    // ~~~~~[ interface : "info" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef DEBUG_TEST
  public    : SC_IN (bool      )            *  in_INFO_ROB_EMPTY  ;
#endif

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  private   : morpheo::behavioural::core::multi_ooo_engine::ooo_engine::rename_unit::rename_select            ::Rename_select             * _component_rename_select            ;
  private   : morpheo::behavioural::core::multi_ooo_engine::ooo_engine::rename_unit::register_translation_unit::Register_translation_unit * _component_register_translation_unit;
  private   : morpheo::behavioural::core::multi_ooo_engine::ooo_engine::rename_unit::load_store_pointer_unit  ::Load_Store_pointer_unit   * _component_load_store_pointer_unit  ;
  private   : morpheo::behavioural::core::multi_ooo_engine::ooo_engine::rename_unit::rename_unit_glue         ::Rename_unit_Glue          * _component_glue                     ;

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

    // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#endif

    // -----[ Methods ]---------------------------------------------------

#ifdef SYSTEMC
    SC_HAS_PROCESS (Rename_unit);
#endif
  public  :          Rename_unit              
  (
#ifdef SYSTEMC
   sc_module_name                                name,
#else					       
   std::string                                   name,
#endif					       
#ifdef STATISTICS
   morpheo::behavioural::Parameters_Statistics * param_statistics,
#endif
   Parameters                                  * param,
   morpheo::behavioural::Tusage_t                usage
   );
  public  :          ~Rename_unit             (void);
					       
  private : void        allocation                (
#ifdef STATISTICS
						   morpheo::behavioural::Parameters_Statistics * param_statistics
#else
						   void
#endif
						   );
  private : void        deallocation              (void);
					       
#ifdef SYSTEMC				       
# if defined(STATISTICS) or defined(VHDL_TESTBENCH)
  public  : void        transition                (void);
# endif					       
#endif					       

#if VHDL				       
  public  : void        vhdl                      (void);
#endif					       

#ifdef STATISTICS
  public  : void        statistics_allocation     (morpheo::behavioural::Parameters_Statistics * param_statistics);
  public  : void        statistics_deallocation   (void);
#endif
#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
  private : void        end_cycle                 (void);
#endif
  };

}; // end namespace rename_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

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

#endif
