#ifndef MEMORYREQUEST_H
#define MEMORYREQUEST_H

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h"

//========================================================={MemoryRequest_t}
class MemoryRequest_t
{
public : double                                   _cycle                ;
public : morpheo::behavioural::Tcontext_t         _context_id           ;
public : morpheo::behavioural::Tcontext_t         _front_end_id         ;
public : morpheo::behavioural::Tcontext_t         _ooo_engine_id        ;
public : morpheo::behavioural::Tpacket_t          _packet_id            ;
public : morpheo::behavioural::Toperation_t       _operation            ;
public : morpheo::behavioural::Ttype_t            _type                 ;
public : morpheo::behavioural::Tlsq_ptr_t         _store_queue_ptr_write;
public : morpheo::behavioural::Tlsq_ptr_t         _load_queue_ptr_write ;
public : morpheo::behavioural::Tgeneral_data_t    _immediat             ;
public : morpheo::behavioural::Tgeneral_data_t    _data_ra              ;
public : morpheo::behavioural::Tgeneral_data_t    _data_rb              ;
public : morpheo::behavioural::Tcontrol_t         _write_rd             ;
public : morpheo::behavioural::Tgeneral_address_t _num_reg_rd           ;
public : bool                                     _write_spec_ko        ;
public : bool                                     _previous_load_speculative;
public : morpheo::behavioural::Tgeneral_data_t    _data_wait            ;

  MemoryRequest_t (void) 
  {
    _cycle                 = 0;
    _context_id            = 0;
    _front_end_id          = 0;
    _ooo_engine_id         = 0;
    _packet_id             = 0;
    _operation             = 0;
    _type                  = 0;
    _store_queue_ptr_write = 0;
    _load_queue_ptr_write  = 0;
    _immediat              = 0;
    _data_ra               = 0;
    _data_rb               = 0;
    _write_rd              = 0;
    _num_reg_rd            = 0;
    _write_spec_ko         = 0;
    _previous_load_speculative = 0;
    _data_wait             = 0;
  };

  MemoryRequest_t (double             cycle                ,
		   morpheo::behavioural::Tcontext_t         context_id           ,
		   morpheo::behavioural::Tcontext_t         front_end_id         ,
		   morpheo::behavioural::Tcontext_t         ooo_engine_id        ,
		   morpheo::behavioural::Tpacket_t          packet_id            ,
		   morpheo::behavioural::Toperation_t       operation            ,
		   morpheo::behavioural::Ttype_t            type                 ,
		   morpheo::behavioural::Tlsq_ptr_t         store_queue_ptr_write,
		   morpheo::behavioural::Tlsq_ptr_t         load_queue_ptr_write ,
		   morpheo::behavioural::Tgeneral_data_t    immediat             ,
		   morpheo::behavioural::Tgeneral_data_t    data_ra              ,
		   morpheo::behavioural::Tgeneral_data_t    data_rb              ,
		   morpheo::behavioural::Tcontrol_t         write_rd             ,
		   morpheo::behavioural::Tgeneral_address_t num_reg_rd           ,
		   bool                                     write_spec_ko        ,
		   morpheo::behavioural::Tgeneral_data_t    data_wait=0)
  {
    _cycle                 = cycle                ;
    _context_id            = context_id           ;
    _front_end_id          = front_end_id         ;
    _ooo_engine_id         = ooo_engine_id        ;
    _packet_id             = packet_id            ;
    _operation             = operation            ;
    _type                  = type                 ;
    _store_queue_ptr_write = store_queue_ptr_write;
    _load_queue_ptr_write  = load_queue_ptr_write ;
    _immediat              = immediat             ;
    _data_ra               = data_ra              ;
    _data_rb               = data_rb              ;
    _write_rd              = write_rd             ;
    _num_reg_rd            = num_reg_rd           ;
    _write_spec_ko         = write_spec_ko        ;
    _previous_load_speculative = 0;
    _data_wait             = data_wait            ;
  }

  void modif (double             cycle                ,
	      morpheo::behavioural::Tcontext_t         context_id           ,
	      morpheo::behavioural::Tcontext_t         front_end_id         ,
	      morpheo::behavioural::Tcontext_t         ooo_engine_id        ,
	      morpheo::behavioural::Tpacket_t          packet_id            ,
	      morpheo::behavioural::Toperation_t       operation            ,
	      morpheo::behavioural::Ttype_t            type                 ,
	      morpheo::behavioural::Tlsq_ptr_t         store_queue_ptr_write,
	      morpheo::behavioural::Tlsq_ptr_t         load_queue_ptr_write ,
	      morpheo::behavioural::Tgeneral_data_t    immediat             ,
	      morpheo::behavioural::Tgeneral_data_t    data_ra              ,
	      morpheo::behavioural::Tgeneral_data_t    data_rb              ,
	      morpheo::behavioural::Tcontrol_t         write_rd             ,
	      morpheo::behavioural::Tgeneral_address_t num_reg_rd           ,
	      bool                                     write_spec_ko        ,
	      morpheo::behavioural::Tgeneral_data_t    data_wait=0          )
  {
    _cycle                 = cycle                ;
    _context_id            = context_id           ;
    _front_end_id          = front_end_id         ;
    _ooo_engine_id         = ooo_engine_id        ;
    _packet_id             = packet_id            ;
    _operation             = operation            ;
    _type                  = type                 ;
    _store_queue_ptr_write = store_queue_ptr_write;
    _load_queue_ptr_write  = load_queue_ptr_write ;
    _immediat              = immediat             ;
    _data_ra               = data_ra              ;
    _data_rb               = data_rb              ;
    _write_rd              = write_rd             ;
    _num_reg_rd            = num_reg_rd           ;
    _write_spec_ko         = write_spec_ko        ;
    _previous_load_speculative = 0;
    _data_wait             = data_wait            ;
  }

  bool operator< (const MemoryRequest_t & right) const 
  {
    return _cycle > right._cycle; 
  }

  friend std::ostream& operator<<(std::ostream & os, const MemoryRequest_t & x)
  {
    return os << "<" << morpheo::toString(x._cycle) << "> : "
	      << "{" << morpheo::toString(static_cast<uint32_t>(x._packet_id)) << "}" << endl
	      << "\t * context / front_end / ooo_engine  : " << morpheo::toString(static_cast<uint32_t>(x._context_id   )) << " - " << morpheo::toString(static_cast<uint32_t>(x._front_end_id )) << " - " << morpheo::toString(static_cast<uint32_t>(x._ooo_engine_id)) << endl
	      << "\t * operation  / type / write_spec_ko : " << morpheo::toString(static_cast<uint32_t>(x._operation)) << " " << morpheo::toString(static_cast<uint32_t>(x._type)) << " " << morpheo::toString(static_cast<uint32_t>(x._write_spec_ko)) << endl
	      << "\t * ptr_write store/load              : " << morpheo::toString(static_cast<uint32_t>(x._store_queue_ptr_write)) << " " << morpheo::toString(static_cast<uint32_t>(x._load_queue_ptr_write)) << endl
	      << "\t * immediat / data_ra / data_rb      : " << morpheo::toString(static_cast<uint32_t>(x._immediat)) << " - " << morpheo::toString(static_cast<uint32_t>(x._data_ra)) << " - " << morpheo::toString(static_cast<uint32_t>(x._data_rb)) << endl
	      << "\t * write_rd / num_reg_rd             : " << morpheo::toString(static_cast<uint32_t>(x._write_rd)) << " " << morpheo::toString(static_cast<uint32_t>(x._num_reg_rd)) << endl
	      << "\t * data_wait                         : " << morpheo::toString(static_cast<uint32_t>(x._data_wait)) << endl;
  }

};

#endif
