#ifdef SYSTEMC
/*
 * $Id: Icache_Access_genMealy_req.cpp 124 2009-06-17 12:11:25Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Icache_Access/include/Icache_Access.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace icache_access {


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

    Tcontrol_t icache_req_val [_param->_nb_icache_port];
    for (uint32_t i=0; i<_param->_nb_icache_port; ++i)
      icache_req_val [i] = 0;
    Tcontrol_t context_req_ack [_param->_nb_front_end][_param->_max_nb_context];
    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
	context_req_ack [i][j] = 0;

    if (PORT_READ(in_NRESET))
      {
    for (uint32_t i=0; i<_param->_nb_icache_port; ++i)
      {
//         log_printf(TRACE,Icache_Access,FUNCTION,"  * ICACHE_REQ [%d]",i);

#ifdef STATISTICS
	_internal_ICACHE_REQ_NB_ACCESS         [i] = 0;
	_internal_ICACHE_REQ_NB_ACCESS_CONFLIT [i] = 0;
#endif
      }
    
    std::list<generic::priority::select_t> * select = _priority ->select();
    for (std::list<generic::priority::select_t>::iterator it=select ->begin();
	 it!=select->end();
	 ++it)
      {
	uint32_t num_front_end = it->grp;
	uint32_t num_context   = it->elt;

        log_printf(TRACE,Dcache_Access,FUNCTION,"  * Context [%d][%d]",num_front_end, num_context);

	
	if (PORT_READ(in_CONTEXT_REQ_VAL [num_front_end][num_context]))
	  {
	    uint32_t   num_port       = _param->_table_routing[num_front_end][num_context];
	    Tcontrol_t icache_req_ack = PORT_READ(in_ICACHE_REQ_ACK [num_port]);

            log_printf(TRACE,Dcache_Access,FUNCTION,"    * context have request");
            log_printf(TRACE,Dcache_Access,FUNCTION,"    * num_port      : %d",num_port);
            log_printf(TRACE,Dcache_Access,FUNCTION,"    * icache_req_val: %d",icache_req_val [num_port]);

#ifdef STATISTICS
	    if (icache_req_ack)
	      {
		_internal_ICACHE_REQ_NB_ACCESS [num_port] ++;
		if (icache_req_val [num_port])
		_internal_ICACHE_REQ_NB_ACCESS_CONFLIT [num_port] ++;
	      }
#endif
	    if (not icache_req_val [num_port])
	      {
		icache_req_val  [num_port] = 1;
		context_req_ack [num_front_end][num_context] = icache_req_ack;

		if (_param->_have_port_icache_thread_id)
                  {
                Tcontext_t num_thread = _param->_translate_context_to_thread[num_front_end][num_context];
                log_printf(TRACE,Dcache_Access,FUNCTION,"    * num_thread  : %d",num_thread );

		PORT_WRITE(out_ICACHE_REQ_THREAD_ID [num_port], num_thread);
                  }
// 		if (_param->_have_port_icache_packet_id)
                if (_param->_have_port_packet_id [num_front_end][num_context])
		PORT_WRITE(out_ICACHE_REQ_PACKET_ID [num_port], PORT_READ(in_CONTEXT_REQ_PACKET_ID [num_front_end][num_context]));
		PORT_WRITE(out_ICACHE_REQ_ADDRESS   [num_port], PORT_READ(in_CONTEXT_REQ_ADDRESS   [num_front_end][num_context]));
		PORT_WRITE(out_ICACHE_REQ_TYPE      [num_port], PORT_READ(in_CONTEXT_REQ_TYPE      [num_front_end][num_context]));
	      }
	  }
      }
      }


    for (uint32_t i=0; i<_param->_nb_icache_port; ++i)
      PORT_WRITE(out_ICACHE_REQ_VAL [i], icache_req_val [i]);
    
    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
	PORT_WRITE(out_CONTEXT_REQ_ACK [i][j], context_req_ack [i][j]);

    log_end(Icache_Access,FUNCTION);
  };

}; // end namespace icache_access
}; // end namespace core

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