#ifdef SYSTEMC
/*
 * $Id: Reexecute_unit_genMealy_reexecute.cpp 123 2009-06-08 20:43:30Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Reexecute_unit/include/Reexecute_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace reexecute_unit {


#undef  FUNCTION
#define FUNCTION "Reexecute_unit::genMealy_reexecute"
  void Reexecute_unit::genMealy_reexecute (void)
  {
    log_begin(Reexecute_unit,FUNCTION);
    log_function(Reexecute_unit,FUNCTION,_name.c_str());

    if (PORT_READ(in_NRESET))
      {
    // ===================================================================
    // =====[ REEXECUTE ]=================================================
    // ===================================================================
    // Between reexecute_rob and rexecute_queue, reexecute_queue is most priotary
    
    for (uint32_t i=0; i<_param->_nb_inst_reexecute; i++)
      {
	Tcontrol_t val;
	Tcontrol_t ack;

        log_printf(TRACE,Reexecute_unit,FUNCTION,"  * REEXECUTE[%d]",i);

	if (not _reexecute_queue [i].empty() and (_reexecute_queue [i].front()->state == STATE_REEXECUTE))
	  {
	    val = true ;
	    ack = false;

	    entry_t * entry = _reexecute_queue [i].front();
            Tpacket_t packet_id = (_param->_have_port_rob_ptr)?entry->packet_id:0;

            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * From Reexecute_queue");
            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * packet_id : %d",packet_id);

	    if (_param->_have_port_context_id)
	    PORT_WRITE(out_REEXECUTE_CONTEXT_ID            [i],entry->context_id    );
	    if (_param->_have_port_front_end_id)
	    PORT_WRITE(out_REEXECUTE_FRONT_END_ID          [i],entry->front_end_id  );
	    if (_param->_have_port_rob_ptr  )
	    PORT_WRITE(out_REEXECUTE_PACKET_ID             [i],       packet_id     );
	    PORT_WRITE(out_REEXECUTE_OPERATION             [i],entry->operation     );
	    PORT_WRITE(out_REEXECUTE_TYPE                  [i],entry->type          );
	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_WRITE [i],0);
// 	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_READ  [i], 0);
// 	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_EMPTY     [i], 0);
	    PORT_WRITE(out_REEXECUTE_HAS_IMMEDIAT          [i],1);
	    PORT_WRITE(out_REEXECUTE_IMMEDIAT              [i],entry->data          );
	    PORT_WRITE(out_REEXECUTE_WRITE_RD              [i],entry->write_rd      );
	    PORT_WRITE(out_REEXECUTE_NUM_REG_RD            [i],entry->num_reg_rd    );
	  }
	else
	  {
	    val = PORT_READ(in_REEXECUTE_ROB_VAL [i]);
	    ack = PORT_READ(in_REEXECUTE_ACK     [i]);

            Tpacket_t packet_id = (_param->_have_port_rob_ptr)?PORT_READ(in_REEXECUTE_ROB_PACKET_ID [i]):0;

            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * From ROB");
            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * val & ack : %d",val and ack);
            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * have ??   : %d",_param->_have_port_rob_ptr);
            log_printf(TRACE,Reexecute_unit,FUNCTION,"    * packet_id : %d",packet_id);

	    if (_param->_have_port_context_id)
	    PORT_WRITE(out_REEXECUTE_CONTEXT_ID            [i], PORT_READ(in_REEXECUTE_ROB_CONTEXT_ID              [i]));
	    if (_param->_have_port_front_end_id)
	    PORT_WRITE(out_REEXECUTE_FRONT_END_ID          [i], PORT_READ(in_REEXECUTE_ROB_FRONT_END_ID            [i]));
	    if (_param->_have_port_rob_ptr  )
	    PORT_WRITE(out_REEXECUTE_PACKET_ID             [i],                            packet_id                   );
	    PORT_WRITE(out_REEXECUTE_OPERATION             [i], PORT_READ(in_REEXECUTE_ROB_OPERATION               [i]));
	    PORT_WRITE(out_REEXECUTE_TYPE                  [i], PORT_READ(in_REEXECUTE_ROB_TYPE                    [i]));
	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_WRITE [i], PORT_READ(in_REEXECUTE_ROB_STORE_QUEUE_PTR_WRITE   [i]));
// 	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_READ  [i], 0);
// 	    PORT_WRITE(out_REEXECUTE_STORE_QUEUE_EMPTY     [i], 0);
	    PORT_WRITE(out_REEXECUTE_HAS_IMMEDIAT          [i], 0);
	    PORT_WRITE(out_REEXECUTE_IMMEDIAT              [i], 0);
	    PORT_WRITE(out_REEXECUTE_WRITE_RD              [i], 0);
	    PORT_WRITE(out_REEXECUTE_NUM_REG_RD            [i], 0);
	  }

	internal_REEXECUTE_VAL     [i] = val;
	internal_REEXECUTE_ROB_ACK [i] = ack;
      }
      }
    else
      {
        for (uint32_t i=0; i<_param->_nb_inst_reexecute; i++)
          {
            internal_REEXECUTE_VAL     [i] = 0;
            internal_REEXECUTE_ROB_ACK [i] = 0;
          }
      }

    for (uint32_t i=0; i<_param->_nb_inst_reexecute; i++)
      {
	PORT_WRITE(out_REEXECUTE_VAL     [i], internal_REEXECUTE_VAL     [i]);
	PORT_WRITE(out_REEXECUTE_ROB_ACK [i], internal_REEXECUTE_ROB_ACK [i]);
      }
    log_end(Reexecute_unit,FUNCTION);
  };

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

}; // end namespace behavioural
}; // end namespace morpheo              
#endif
