#ifndef morpheo_behavioural_Types_h
#define morpheo_behavioural_Types_h

#include "Common/include/Types.h"
#include "Common/include/ToString.h"
#include "Behavioural/include/Constants.h"

namespace morpheo {
namespace behavioural {
  
  //============================================
  // Type definition
  //============================================

  // ***** general
  typedef bool          Tcontrol_t;
  typedef uint32_t      Toperation_t;
//typedef uint32_t      Tdestination1_t;
//typedef uint32_t      Tdestination2_t;
//typedef uint32_t      Texec_flag_t;
//typedef bool          Texec_excep_t;
//typedef uint32_t      Tcondition_t;
//typedef uint32_t      Tbranch_state_t;

  typedef uint32_t      Texception_t;
  typedef uint32_t      Tcontext_t;
  typedef uint32_t      Tpacket_t;
  typedef uint32_t      Ttype_t;

  // ***** Register
  typedef uint32_t      Tgeneral_address_t;
  typedef uint32_t      Tgeneral_data_t;
  typedef uint32_t      Tspecial_address_t;
  typedef uint32_t      Tspecial_data_t;

  // ***** component dependant
  // ~~~~~ load store queue
  typedef uint32_t      Taccess_t;
  typedef uint32_t      Tlsq_ptr_t;
  typedef uint32_t      Tdcache_address_t;
  typedef uint32_t      Tdcache_data_t;
  typedef bool          Tdcache_error_t;
  typedef uint32_t      Tdcache_type_t;

  //----------------------------------------------[ spr_mode_access ]-----
  class spr_access_mode_t
  {
  public : uint8_t _user_access_mode      ;
  public : uint8_t _supervisor_access_mode;
    
  public : spr_access_mode_t (uint32_t user_access_mode       = SPR_ACCESS_MODE_NONE,
			      uint32_t supervisor_access_mode = SPR_ACCESS_MODE_NONE)
    {
      _user_access_mode       = user_access_mode      ;
      _supervisor_access_mode = supervisor_access_mode;
    }
  };

  inline Tcontext_t get_num_thread (Tcontext_t num_context_id   , uint32_t size_context_id   ,
				    Tcontext_t num_front_end_id , uint32_t size_front_end_id ,
				    Tcontext_t num_ooo_engine_id, uint32_t size_ooo_engine_id)
  {
    return ((num_ooo_engine_id << (size_context_id + size_front_end_id)) |
	    (num_front_end_id  << (size_context_id)) |
	    (num_context_id));
  }

  inline uint32_t get_nb_thread (uint32_t nb_context ,
				 uint32_t nb_front_end ,
				 uint32_t nb_ooo_engine )
  {
    return (nb_ooo_engine *
	    nb_front_end  *
	    nb_context) ;
  }

}; // end namespace behavioural

  inline std::string toString_type(const morpheo::behavioural::Ttype_t& x)
  {
    switch (x)
      {
      case TYPE_ALU     : return "ALU"    ; break;
      case TYPE_SHIFT   : return "SHIFT"  ; break;
      case TYPE_MOVE    : return "MOVE"   ; break;
      case TYPE_TEST    : return "TEST"   ; break;
      case TYPE_MUL_DIV : return "MUL_DIV"; break;
      case TYPE_EXTEND  : return "EXTEND" ; break;
      case TYPE_FIND    : return "FIND"   ; break;
      case TYPE_SPECIAL : return "SPECIAL"; break;
      case TYPE_CUSTOM  : return "CUSTOM" ; break;
      case TYPE_BRANCH  : return "BRANCH" ; break;
      case TYPE_MEMORY  : return "MEMORY" ; break;
      default           : return ""       ; break;
      }
  };

}; // end namespace morpheo              

#endif
