#ifdef SYSTEMC
/*
 * $Id: Icache_Access_genMealy_rsp.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_rsp"
  void Icache_Access::genMealy_rsp (void)
  {
    log_begin(Icache_Access,FUNCTION); 
    log_function(Icache_Access,FUNCTION,_name.c_str());

    Tcontrol_t context_rsp_val [_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_rsp_val [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_RSP [%d]",i);
        
	Tcontrol_t val = PORT_READ(in_ICACHE_RSP_VAL [i]);
	Tcontrol_t ack;
	
	Tcontext_t thread_id = (_param->_have_port_icache_thread_id)?PORT_READ(in_ICACHE_RSP_THREAD_ID [i]):0;

        log_printf(TRACE,Icache_Access,FUNCTION,"    * val            : %d",val);
        log_printf(TRACE,Icache_Access,FUNCTION,"    * thread_id      : %d",thread_id);

#ifdef DEBUG_TEST
        if (thread_id > _param->_nb_thread)
          throw ERRORMORPHEO(FUNCTION,_("invalid thread_id.\n"));
#endif

	if (val)
	  {
	    Tcontext_t front_end_id = _param->_translate_thread_to_context  [thread_id];
	    Tcontext_t context_id   = _param->_translate_thread_to_front_end[thread_id];

            log_printf(TRACE,Icache_Access,FUNCTION,"    * front_end_id   : %d",front_end_id);
            log_printf(TRACE,Icache_Access,FUNCTION,"    * context_id     : %d",context_id  );
	    
// 	    log_printf(TRACE,Icache_Access,FUNCTION,"thread_id     : %d",thread_id);
// 	    log_printf(TRACE,Icache_Access,FUNCTION,"front_end_id  : %d",front_end_id);
// 	    log_printf(TRACE,Icache_Access,FUNCTION,"context_id    : %d",context_id);
	    
#ifdef DEBUG_TEST
	    if (front_end_id > _param->_nb_front_end)
	      throw ERRORMORPHEO(FUNCTION,_("invalid front_end_id.\n"));

	    if (context_id > _param->_nb_context[front_end_id])
	      throw ERRORMORPHEO(FUNCTION,_("invalid context_id.\n"));

	    if (_param->_table_routing [front_end_id][context_id] != i)
	      throw ERRORMORPHEO(FUNCTION,_("invalid route.\n"));
#endif

	    ack = PORT_READ(in_CONTEXT_RSP_ACK [front_end_id][context_id]);
	    
	    context_rsp_val [front_end_id][context_id] = 1;
//          if (_param->_have_port_icache_packet_id)
	    if (_param->_have_port_packet_id [front_end_id][context_id])
	    PORT_WRITE(out_CONTEXT_RSP_PACKET_ID   [front_end_id][context_id], PORT_READ(in_ICACHE_RSP_PACKET_ID   [i]));
	    PORT_WRITE(out_CONTEXT_RSP_ERROR       [front_end_id][context_id], PORT_READ(in_ICACHE_RSP_ERROR       [i]));
	    
	    for (uint32_t j=0; j<_param->_nb_instruction [front_end_id][context_id]; ++j)
              PORT_WRITE(out_CONTEXT_RSP_INSTRUCTION [front_end_id][context_id][j], PORT_READ(in_ICACHE_RSP_INSTRUCTION [i][j]));
	  }
	else
	  ack = 0;
		
	PORT_WRITE(out_ICACHE_RSP_ACK [i],ack);
      }

      }
    else
      for (uint32_t i=0; i<_param->_nb_icache_port; ++i)
	PORT_WRITE(out_ICACHE_RSP_ACK [i],0);

    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
        {
          log_printf(TRACE,Icache_Access,FUNCTION,"  * CONTEXT_RSP_VAL [%d][%d] : %d",i,j,context_rsp_val [i][j]);

          PORT_WRITE(out_CONTEXT_RSP_VAL [i][j], context_rsp_val [i][j]);
        }

    log_end(Icache_Access,FUNCTION);
  };

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

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