#ifdef SYSTEMC
/*
 * $Id$
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Read_queue/include/Read_queue.h"

namespace morpheo {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_read_unit {
namespace read_unit {
namespace read_queue {

#undef  FUNCTION
#define FUNCTION "Read_queue::genMealy_read_queue_out_spr"
  void Read_queue::genMealy_read_queue_out_spr (void)
  {
    log_printf(FUNC,Read_queue,FUNCTION,"Begin");

    internal_READ_QUEUE_OUT_DATA_RC_VAL = (// Previous value
					   _queue_head->_data_rc_val or
					   // Test if have already access at the registerfile
					   (_queue_head->_read_rc_val           and
					    PORT_READ(in_SPR_READ_ACK      [0]) and
					    PORT_READ(in_SPR_READ_DATA_VAL [0]))
					   );

    log_printf(TRACE,Read_queue,FUNCTION," * internal_READ_QUEUE_OUT_DATA_RC_VAL   : %d",internal_READ_QUEUE_OUT_DATA_RC_VAL);
    log_printf(TRACE,Read_queue,FUNCTION,"   * _queue_head->_data_rc_val           : %d",_queue_head->_data_rc_val);
    log_printf(TRACE,Read_queue,FUNCTION,"   * _queue_head->_read_rc_val           : %d",_queue_head->_read_rc_val);
    log_printf(TRACE,Read_queue,FUNCTION,"   * in_SPR_READ_ACK      [0]            : %d",PORT_READ(in_SPR_READ_ACK      [0]));
    log_printf(TRACE,Read_queue,FUNCTION,"   * in_SPR_READ_DATA_VAL [0]            : %d",PORT_READ(in_SPR_READ_DATA_VAL [0]));

    internal_READ_QUEUE_OUT_DATA_RC     = (// Test if have an previous access
					   (_queue_head->_data_rc_val)?
					   // if precious access, take previous data
					   _queue_head->_data_rc:
					   // else, take the read_data (don't test the validity of data)
					   PORT_READ(in_SPR_READ_DATA [0]));

//     cout << "yo1 : " << internal_READ_QUEUE_OUT_DATA_RC << endl;

    // Test all bypass
    for (uint32_t i=0; i<_param->_nb_spr_write ; i++)
      {
	// Test if this bypass is valid
	if ( (PORT_READ (in_SPR_WRITE_VAL        [i]) == 1) and
	     (PORT_READ (in_SPR_WRITE_CONTEXT_ID [i]) == _queue_head->_context_id)
	     )
	  {
	    if (_queue_head->_num_reg_rc == PORT_READ(in_SPR_WRITE_NUM_REG [i]))
	      {
		log_printf(TRACE,Read_queue,FUNCTION," * internal_READ_QUEUE_OUT_DATA_RC_VAL   - bypass hit (%d)",i);
		internal_READ_QUEUE_OUT_DATA_RC_VAL = 1;
		internal_READ_QUEUE_OUT_DATA_RC     = PORT_READ(in_SPR_WRITE_DATA [i]);
	      }
	  }
      }

//     cout << "yo2 : " << internal_READ_QUEUE_OUT_DATA_RC << endl;

    // Affectation out port
    PORT_WRITE(out_READ_QUEUE_OUT_DATA_RC_VAL,internal_READ_QUEUE_OUT_DATA_RC_VAL);
    PORT_WRITE(out_READ_QUEUE_OUT_DATA_RC    ,internal_READ_QUEUE_OUT_DATA_RC    );

    log_printf(FUNC,Read_queue,FUNCTION,"End");
  };

}; // end namespace read_queue
}; // end namespace read_unit
}; // end namespace multi_read_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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