#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_val"
  void Read_queue::genMealy_read_queue_out_val (void)
  {
    log_printf(FUNC,Read_queue,FUNCTION,"Begin");

    internal_READ_QUEUE_OUT_READ_RA_VAL = (// Previous value
					   _queue_head->_read_ra_val  and
					   // Test if have already access at the registerfile
					   not PORT_READ(in_GPR_READ_ACK      [0])
					   );

    internal_READ_QUEUE_OUT_READ_RB_VAL = (_queue_head->_read_rb_val  and
					   not PORT_READ(in_GPR_READ_ACK      [1])
					   );
    
    internal_READ_QUEUE_OUT_READ_RC_VAL = (_queue_head->_read_rc_val  and
					   not PORT_READ(in_SPR_READ_ACK      [0])
					   );

    // Test all bypass
    for (uint32_t i=0; i<_param->_nb_gpr_write ; i++)
      {
	bool cmp;

	if (_param->_have_port_ooo_engine_id)
	  cmp = (PORT_READ (in_GPR_WRITE_OOO_ENGINE_ID [i]) == _queue_head->_ooo_engine_id);
	else
	  cmp = true;
	
	// Test if this bypass is valid
	if ((PORT_READ (in_GPR_WRITE_VAL           [i]) == 1) and cmp)
	  {
	    Tgeneral_address_t gpr_write_num_reg = PORT_READ(in_GPR_WRITE_NUM_REG [i]);
	    
	    if (_queue_head->_num_reg_ra == gpr_write_num_reg)
	      internal_READ_QUEUE_OUT_READ_RA_VAL = 0;

	    if (_queue_head->_num_reg_rb == gpr_write_num_reg)
	      internal_READ_QUEUE_OUT_READ_RB_VAL = 0;
	  }
      }

    for (uint32_t i=0; i<_param->_nb_spr_write ; i++)
      {
	bool cmp;

	if (_param->_have_port_ooo_engine_id)
	  cmp = (PORT_READ (in_SPR_WRITE_OOO_ENGINE_ID [i]) == _queue_head->_ooo_engine_id);
	else
	  cmp = true;
	
	// Test if this bypass is valid
	if ((PORT_READ (in_SPR_WRITE_VAL           [i]) == 1) and cmp)
	  {
	    Tspecial_address_t spr_write_num_reg = PORT_READ(in_SPR_WRITE_NUM_REG [i]);
	    
	    if (_queue_head->_num_reg_rc == spr_write_num_reg)
	      internal_READ_QUEUE_OUT_READ_RC_VAL = 0;
	  }
      }

    // Affectation out port

    // READ_QUEUE_OUT_VAL : mealy
    internal_READ_QUEUE_OUT_VAL = (not _queue->empty()                     and
				   not internal_READ_QUEUE_OUT_READ_RA_VAL and
				   not internal_READ_QUEUE_OUT_READ_RB_VAL and
				   not internal_READ_QUEUE_OUT_READ_RC_VAL
				   );

    // READ_QUEUE_OUT_VAL : moore
//     internal_READ_QUEUE_OUT_VAL = (not _queue->empty()           and
// 				   not _queue_head->_read_ra_val and
// 				   not _queue_head->_read_rb_val and
// 				   not _queue_head->_read_rc_val
// 				   );


    PORT_WRITE(out_READ_QUEUE_OUT_VAL, internal_READ_QUEUE_OUT_VAL);

    log_printf(TRACE,Read_queue,FUNCTION," * internal_READ_QUEUE_OUT_VAL           : %d",internal_READ_QUEUE_OUT_VAL);
    log_printf(TRACE,Read_queue,FUNCTION,"   * _queue->empty()                     : %d",_queue->empty());
    log_printf(TRACE,Read_queue,FUNCTION,"   * internal_READ_QUEUE_OUT_READ_RA_VAL : %d",internal_READ_QUEUE_OUT_READ_RA_VAL);
    log_printf(TRACE,Read_queue,FUNCTION,"     * _queue_head->_read_ra_val         : %d",_queue_head->_read_ra_val);
    log_printf(TRACE,Read_queue,FUNCTION,"     * in_GPR_READ_ACK      [0]          : %d",PORT_READ(in_GPR_READ_ACK      [0]));
    log_printf(TRACE,Read_queue,FUNCTION,"   * internal_READ_QUEUE_OUT_READ_RB_VAL : %d",internal_READ_QUEUE_OUT_READ_RB_VAL);
    log_printf(TRACE,Read_queue,FUNCTION,"     * _queue_head->_read_rb_val         : %d",_queue_head->_read_rb_val);
    log_printf(TRACE,Read_queue,FUNCTION,"     * in_GPR_READ_ACK      [1]          : %d",PORT_READ(in_GPR_READ_ACK      [1]));
    log_printf(TRACE,Read_queue,FUNCTION,"   * internal_READ_QUEUE_OUT_READ_RC_VAL : %d",internal_READ_QUEUE_OUT_READ_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(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
