#ifdef SYSTEMC
/*
 * $Id: Load_Store_pointer_unit_genMealy_retire.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Load_Store_pointer_unit/include/Load_Store_pointer_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace rename_unit {
namespace load_store_pointer_unit {


#undef  FUNCTION
#define FUNCTION "Load_Store_pointer_unit::genMealy_retire"
  void Load_Store_pointer_unit::genMealy_retire (void)
  {
    log_printf(FUNC,Load_Store_pointer_unit,FUNCTION,"Begin");
    
    bool use_lsq [_param->_nb_load_store_queue];
    for (uint32_t i=0; i<_param->_nb_load_store_queue; i++)
      use_lsq [i] = false;

    for (uint32_t i=0; i<_param->_nb_inst_retire; i++)
      {
	Tcontrol_t ack = false;
	Tcontrol_t use_sq  = PORT_READ(in_RETIRE_USE_STORE_QUEUE [i]);
	Tcontrol_t use_lq  = PORT_READ(in_RETIRE_USE_LOAD_QUEUE  [i]);
	if ( (PORT_READ(in_RETIRE_VAL  [i]) == true) and (use_sq or use_lq))
// 	     (PORT_READ(in_RETIRE_TYPE [i]) == TYPE_MEMORY))
	  {
	    Tcontext_t front_end_id = (_param->_have_port_front_end_id)?PORT_READ(in_RETIRE_FRONT_END_ID [i]):0;
	    Tcontext_t context_id   = (_param->_have_port_context_id  )?PORT_READ(in_RETIRE_CONTEXT_ID   [i]):0;
	    uint32_t   lsq          = _param->_link_load_store_unit_with_thread[front_end_id][context_id];

	    // Test if a previous instruction use the same lsq
	    // Authorize once memory access by load store unit
	    if (use_lsq [lsq] == false)
	      {
		use_lsq [lsq] = true;
		ack = true;

		uint32_t   ptr;
		
		// operation became of decod_stage. Also operation is != store_head_ok and store_head_ko
// 		if (is_operation_memory_store(PORT_READ(in_RETIRE_OPERATION [i])))
		if (use_sq)
		  {
		    internal_RETIRE_OPERATION_USE [i] = OPERATION_USE_STORE_QUEUE;
		    
		    ptr = PORT_READ(in_RETIRE_STORE_QUEUE_PTR_WRITE [i]);
		  }
		else
		  {
		    internal_RETIRE_OPERATION_USE [i] = OPERATION_USE_LOAD_QUEUE;
		    
		    ptr = (_param->_have_port_load_queue_ptr)?PORT_READ(in_RETIRE_LOAD_QUEUE_PTR_WRITE [i]):0;
		  }
		
		internal_RETIRE_LSQ [i] = lsq;
		internal_RETIRE_PTR [i] = ptr;
	      }
	  }
	else
	  {
	    ack = true;

	    internal_RETIRE_OPERATION_USE [i] = OPERATION_USE_NONE;
	  }

	// Write output
	internal_RETIRE_ACK [i] = ack;
	PORT_WRITE(out_RETIRE_ACK                   [i], ack);
      }
    
    log_printf(FUNC,Load_Store_pointer_unit,FUNCTION,"End");
  };

}; // end namespace load_store_pointer_unit
}; // end namespace rename_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

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