#ifdef SYSTEMC
/*
 * $Id: Issue_queue_function_out_of_order_transition.cpp 111 2009-02-27 18:37:40Z rosiere $
 *
 * [ Description ]
 * 
 */

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

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace issue_queue {


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

    if (PORT_READ(in_NRESET) == 0)
      {
// 	_priority_in ->reset();
	_priority_out->reset();
	_priority_reg->reset();
	
	for (uint32_t i=0; i<_param->_nb_bank; i++)
	  _issue_queue [i].clear();
      }
    else
      {
// 	_priority_in ->transition();
 	_priority_out->transition();
	_priority_reg->transition();

	// ===================================================================
	// =====[ ISSUE_IN ]==================================================
	// ===================================================================

	for (uint32_t i=0; i<_param->_nb_bank; i++)
	  if (internal_BANK_IN_ACK [i])
	    {
              uint32_t x = internal_BANK_IN_NUM_RENAME_UNIT [i];
              uint32_t y = internal_BANK_IN_NUM_INST [i];
              
              if (PORT_READ(in_ISSUE_IN_VAL[x][y]))
                {
                  log_printf(TRACE,Issue_queue,FUNCTION,"  * ISSUE_IN [%d] - Transaction with ISSUE_IN [%d][%d]",i,x,y);

#ifdef STATISTICS
                  if (usage_is_set(_usage,USE_STATISTICS))
                    (*_stat_nb_inst_issue_in [x]) ++;
#endif
                  entry_t * entry = new entry_t
                    (
                     (_param->_have_port_context_id    )?PORT_READ(in_ISSUE_IN_CONTEXT_ID            [x][y]):0,
                     (_param->_have_port_front_end_id  )?PORT_READ(in_ISSUE_IN_FRONT_END_ID          [x][y]):0,
                     (_param->_have_port_rob_ptr       )?PORT_READ(in_ISSUE_IN_PACKET_ID             [x][y]):0,
			                                 PORT_READ(in_ISSUE_IN_OPERATION             [x][y]),
			                                 PORT_READ(in_ISSUE_IN_TYPE                  [x][y]),
			                                 PORT_READ(in_ISSUE_IN_STORE_QUEUE_PTR_WRITE [x][y]),
                     (_param->_have_port_load_queue_ptr)?PORT_READ(in_ISSUE_IN_LOAD_QUEUE_PTR_WRITE  [x][y]):0,
			                                 PORT_READ(in_ISSUE_IN_HAS_IMMEDIAT          [x][y]),
			                                 PORT_READ(in_ISSUE_IN_IMMEDIAT              [x][y]),
			                                 PORT_READ(in_ISSUE_IN_READ_RA               [x][y]),
			                                 PORT_READ(in_ISSUE_IN_NUM_REG_RA            [x][y]),
			                                 PORT_READ(in_ISSUE_IN_READ_RB               [x][y]),
			                                 PORT_READ(in_ISSUE_IN_NUM_REG_RB            [x][y]),
			                                 PORT_READ(in_ISSUE_IN_READ_RC               [x][y]),
			                                 PORT_READ(in_ISSUE_IN_NUM_REG_RC            [x][y]),
			                                 PORT_READ(in_ISSUE_IN_WRITE_RD              [x][y]),
			                                 PORT_READ(in_ISSUE_IN_NUM_REG_RD            [x][y]),
			                                 PORT_READ(in_ISSUE_IN_WRITE_RE              [x][y]),
			                                 PORT_READ(in_ISSUE_IN_NUM_REG_RE            [x][y])
                     );

                  _issue_queue [i].push_back(entry);
                }
	    }

	// ===================================================================
	// =====[ ISSUE_OUT ]=================================================
	// ===================================================================

        for (uint32_t i=0; i<_param->_nb_inst_issue; ++i)
          if (internal_ISSUE_OUT_VAL [i] and PORT_READ(in_ISSUE_OUT_ACK [i]))
            if (not internal_ISSUE_OUT_FROM_REEXECUTE [i])
              {
                entry_t * entry = internal_ISSUE_OUT_ENTRY    [i];
                
                // front ...
                uint32_t  num_bank = internal_ISSUE_OUT_NUM_BANK [i];
                
                log_printf(TRACE,Issue_queue,FUNCTION,"  * ISSUE_OUT [%d] - From issue_queue [%d]",i,num_bank);
                
                _issue_queue [num_bank].remove(entry);
                delete entry;
              } 
      }

    log_end(Issue_queue,FUNCTION);
  };

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

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