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

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Network/Read_unit_to_Execution_unit/include/Read_unit_to_Execution_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace network {
namespace read_unit_to_execution_unit {


#undef  FUNCTION
#define FUNCTION "Read_unit_to_Execution_unit::transition"
  void Read_unit_to_Execution_unit::transition (void)
  {
    log_printf(FUNC,Read_unit_to_Execution_unit,FUNCTION,"Begin");

    if (PORT_READ(in_NRESET) == 0)
      {
	// Flush routing_table
	for (uint32_t i=0; i<_param->_nb_read_unit; i++)
	  for (uint32_t j=0; j<_param->_nb_thread; j++)
	    for (uint32_t k=0; k<_param->_nb_type; k++)
	      _destination [i][j][k].clear();
	
	// Fill routing table
	for (uint32_t i=0; i<_param->_nb_read_unit; i++)
	  for (uint32_t x=0; x<_param->_nb_execute_unit; x++)
	    for (uint32_t y=0; y<_param->_nb_execute_unit_port[x]; y++)
	      // Test if link between src and dest
	      if (_param->_table_routing [i][x][y])
		// Test the thread accepted by the execute_unit
		for (uint32_t k=0; k<_param->_nb_thread; k++)
		  if (_param->_table_execute_thread[x][k])
		    // Test the type accepted by the execute_unit
		    for (uint32_t l=0; l<_param->_nb_type; l++)
		      if (_param->_table_execute_type [x][l])
			// push_back == minor have a better priority
			_destination [i][k][l].push_back(destination_t(x,y));
      }
    else
      {
	if (_param->_priority == PRIORITY_ROUND_ROBIN)
	  for (uint32_t i=0; i<_param->_nb_read_unit; i++)
	    for (uint32_t j=0; j<_param->_nb_thread; j++)
	      for (uint32_t k=0; k<_param->_nb_type; k++)
		if (_destination [i][j][k].size() > 1)
		  {
		    // Head queue became the Tail queue
		    _destination [i][j][k].push_back(_destination [i][j][k].front());
		    _destination [i][j][k].pop_front();
		  }
      }


#if (DEBUG >= DEBUG_TRACE)
//     // Print
//     log_printf(TRACE,Read_unit_to_Execution_unit,FUNCTION,"Routing Table");
//     for (uint32_t i=0; i<_param->_nb_read_unit; i++)
//       for (uint32_t j=0; j<_param->_nb_thread; j++)
// 	for (uint32_t k=0; k<_param->_nb_type; k++)
// 	  for (std::list<uint32_t>::iterator l=_destination[i][j][k].begin();
// 	       l != _destination[i][j][k].end();
// 	       l++)
// 	    log_printf(TRACE,Read_unit_to_Execution_unit,FUNCTION,"  * Read_unit [%d], send at the execution_unit [%d], the operation of thread [%d] with the type [%s].",i,*l,j,toString_type(k).c_str());
#endif

#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
    end_cycle ();
#endif

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

}; // end namespace read_unit_to_execution_unit
}; // end namespace network
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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