#ifndef morpheo_behavioural_core_multi_front_end_front_end_decod_unit_decod_queue_Types_h
#define morpheo_behavioural_core_multi_front_end_front_end_decod_unit_decod_queue_Types_h

/*
 * $Id: Types.h 112 2009-03-18 22:36:26Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/include/Types.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 {

  typedef enum 
    {
       DECOD_QUEUE_SCHEME_ONE_FIFO   // One fifo with a instruction bundle per slot (   internal fragmentation)
      ,DECOD_QUEUE_SCHEME_MULTI_FIFO // One fifo per instruction. Rename in order   (no internal fragmentation)
    } Tdecod_queue_scheme_t;

  class decod_queue_entry_t
  {
  private: const uint32_t       _nb_inst        ;

  public : Tcontrol_t         * _val            ;
  public : Tcontext_t         * _context_id     ;
  public : Tdepth_t           * _depth          ;
  public : Ttype_t            * _type           ;
  public : Toperation_t       * _operation      ;
  public : Tcontrol_t         * _no_execute     ;
  public : Tcontrol_t         * _is_delay_slot  ;
#ifdef DEBUG
  public : Tgeneral_data_t    * _address        ;
#endif
  public : Tgeneral_data_t    * _address_next   ;
  public : Tcontrol_t         * _has_immediat   ;
  public : Tgeneral_data_t    * _immediat       ;
  public : Tcontrol_t         * _read_ra        ;
  public : Tgeneral_address_t * _num_reg_ra     ;
  public : Tcontrol_t         * _read_rb        ;
  public : Tgeneral_address_t * _num_reg_rb     ;
  public : Tcontrol_t         * _read_rc        ;
  public : Tspecial_address_t * _num_reg_rc     ;
  public : Tcontrol_t         * _write_rd       ;
  public : Tgeneral_address_t * _num_reg_rd     ;
  public : Tcontrol_t         * _write_re       ;
  public : Tspecial_address_t * _num_reg_re     ;
  public : Texception_t       * _exception_use  ;
  public : Texception_t       * _exception      ;

  public :  decod_queue_entry_t (uint32_t nb_inst):
    _nb_inst (nb_inst)
    {
      ALLOC1(_val            ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_context_id     ,Tcontext_t         ,_nb_inst);
      ALLOC1(_depth          ,Tdepth_t           ,_nb_inst);
      ALLOC1(_type           ,Ttype_t            ,_nb_inst);
      ALLOC1(_operation      ,Toperation_t       ,_nb_inst);
      ALLOC1(_no_execute     ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_is_delay_slot  ,Tcontrol_t         ,_nb_inst);
#ifdef DEBUG
      ALLOC1(_address        ,Tgeneral_data_t    ,_nb_inst);
#endif
      ALLOC1(_address_next   ,Tgeneral_data_t    ,_nb_inst);
      ALLOC1(_has_immediat   ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_immediat       ,Tgeneral_data_t    ,_nb_inst);
      ALLOC1(_read_ra        ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_num_reg_ra     ,Tgeneral_address_t ,_nb_inst);
      ALLOC1(_read_rb        ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_num_reg_rb     ,Tgeneral_address_t ,_nb_inst);
      ALLOC1(_read_rc        ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_num_reg_rc     ,Tspecial_address_t ,_nb_inst);
      ALLOC1(_write_rd       ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_num_reg_rd     ,Tgeneral_address_t ,_nb_inst);
      ALLOC1(_write_re       ,Tcontrol_t         ,_nb_inst);
      ALLOC1(_num_reg_re     ,Tspecial_address_t ,_nb_inst);
      ALLOC1(_exception_use  ,Texception_t       ,_nb_inst);
      ALLOC1(_exception      ,Texception_t       ,_nb_inst);

      for (uint32_t i=0; i<_nb_inst; i++)
	_val [i]=0; // default : not valid
    }

  public : ~decod_queue_entry_t (void)
    {
      DELETE1(_val            ,_nb_inst);
      DELETE1(_context_id     ,_nb_inst);
      DELETE1(_depth          ,_nb_inst);
      DELETE1(_type           ,_nb_inst);
      DELETE1(_operation      ,_nb_inst);
      DELETE1(_no_execute     ,_nb_inst);
      DELETE1(_is_delay_slot  ,_nb_inst);
#ifdef DEBUG
      DELETE1(_address        ,_nb_inst);
#endif
      DELETE1(_address_next   ,_nb_inst);
      DELETE1(_has_immediat   ,_nb_inst);
      DELETE1(_immediat       ,_nb_inst);
      DELETE1(_read_ra        ,_nb_inst);
      DELETE1(_num_reg_ra     ,_nb_inst);
      DELETE1(_read_rb        ,_nb_inst);
      DELETE1(_num_reg_rb     ,_nb_inst);
      DELETE1(_read_rc        ,_nb_inst);
      DELETE1(_num_reg_rc     ,_nb_inst);
      DELETE1(_write_rd       ,_nb_inst);
      DELETE1(_num_reg_rd     ,_nb_inst);
      DELETE1(_write_re       ,_nb_inst);
      DELETE1(_num_reg_re     ,_nb_inst);
      DELETE1(_exception_use  ,_nb_inst);
      DELETE1(_exception      ,_nb_inst);
    }
  };

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

  template<> inline std::string toString<morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::Tdecod_queue_scheme_t>(const morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::Tdecod_queue_scheme_t& x)
  {
    switch (x)
      {
      case morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_ONE_FIFO   : return "one_fifo"  ; break;
      case morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_MULTI_FIFO : return "multi_fifo"; break;
      default : return ""; break;
      }
  };

  template<> inline morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::Tdecod_queue_scheme_t fromString<morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::Tdecod_queue_scheme_t>(const std::string& x)
  {
    if ( (x.compare(toString(static_cast<uint32_t>(morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_ONE_FIFO  ))) == 0) or
         (x.compare("one_fifo")   == 0))
      return morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_ONE_FIFO;
    if ( (x.compare(toString(static_cast<uint32_t>(morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_MULTI_FIFO))) == 0) or
         (x.compare("multi_fifo") == 0))
      return morpheo::behavioural::core::multi_front_end::front_end::decod_unit::decod_queue::DECOD_QUEUE_SCHEME_MULTI_FIFO;
    
    throw (ErrorMorpheo ("<fromString> : Unknow string : \""+x+"\""));
  };


}; // end namespace morpheo              

#endif
