#ifdef SYSTEMC
/*
 * $Id: Dcache_Access_genMealy_rsp.cpp 128 2009-06-26 08:43:23Z rosiere $
 *
 * [ Description ]
 * 
 */

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

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace dcache_access {


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

    if (PORT_READ(in_NRESET))
      {
    Tcontrol_t lsq_rsp_val [_param->_nb_execute_loop][_param->_max_nb_load_store_unit][_param->_max_nb_cache_access];
    for (uint32_t i=0; i<_param->_nb_execute_loop; ++i)
      for (uint32_t j=0; j<_param->_nb_load_store_unit[i]; ++j)
	for (uint32_t k=0; k<_param->_nb_cache_access [i][j]; ++k)
	  lsq_rsp_val [i][j][k] = 0;

    for (uint32_t i=0; i<_param->_nb_dcache_port; ++i)
      {
	Tcontrol_t val = PORT_READ(in_DCACHE_RSP_VAL [i]);
	Tcontrol_t ack;
	
	if (val)
	  {
            Tcontext_t thread_id = (_param->_have_port_dcache_thread_id)?PORT_READ(in_DCACHE_RSP_THREAD_ID [i]):0;
            Tcontext_t packet_id = (_param->_have_port_dcache_packet_id)?PORT_READ(in_DCACHE_RSP_PACKET_ID [i]):0;

	    Tcontext_t execute_loop_id     = _param->_translate_thread_to_execute_loop    [thread_id];
	    Tcontext_t load_store_unit_id  = _param->_translate_thread_to_load_store_unit [thread_id];
            Tcontext_t context_id          = _param->_translate_thread_to_context         [thread_id];

	    Tpacket_t  cache_access_id     = (packet_id >> _param->_shift_num_cache_access   ) & _param->_mask_num_cache_access;
	    Tpacket_t  lsq_packet_id       =  packet_id                                        & _param->_mask_num_lsq_packet;

            log_printf(TRACE,Dcache_Access,FUNCTION,"  * DCACHE_RSP [%d] <-> LSQ_RSP [%d][%d][%d]",i,execute_loop_id,load_store_unit_id,cache_access_id);

	    log_printf(TRACE,Dcache_Access,FUNCTION,"    * thread_id            : %d",thread_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"      * execute_loop_id    : %d",execute_loop_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"      * load_store_unit_id : %d",load_store_unit_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"      * context_id         : %d",context_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"    * packet_id            : %d",thread_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"      * cache_access_id    : %d",cache_access_id);
	    log_printf(TRACE,Dcache_Access,FUNCTION,"      * lsq_packet_id      : %d",lsq_packet_id);
	    
#ifdef DEBUG_TEST
	    if (execute_loop_id > _param->_nb_execute_loop)
	      throw ERRORMORPHEO(FUNCTION,_("invalid execute_loop_id.\n"));

	    if (load_store_unit_id > _param->_nb_load_store_unit[execute_loop_id])
	      throw ERRORMORPHEO(FUNCTION,_("invalid load_store_unit_id.\n"));

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

	    if (cache_access_id > _param->_nb_cache_access[execute_loop_id][load_store_unit_id])
	      throw ERRORMORPHEO(FUNCTION,_("invalid cache_access_id.\n"));

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

	    ack = PORT_READ(in_LSQ_RSP_ACK [execute_loop_id][load_store_unit_id][cache_access_id]);
	    
	    lsq_rsp_val [execute_loop_id][load_store_unit_id][cache_access_id] = 1;

	    if (_param->_have_port_lsq_thread_id [execute_loop_id][load_store_unit_id])
	    PORT_WRITE(out_LSQ_RSP_THREAD_ID   [execute_loop_id][load_store_unit_id][cache_access_id], context_id);
	    if (_param->_have_port_lsq_packet_id [execute_loop_id][load_store_unit_id])
	    PORT_WRITE(out_LSQ_RSP_PACKET_ID   [execute_loop_id][load_store_unit_id][cache_access_id], lsq_packet_id);
	    PORT_WRITE(out_LSQ_RSP_RDATA       [execute_loop_id][load_store_unit_id][cache_access_id], PORT_READ(in_DCACHE_RSP_RDATA       [i]));
	    PORT_WRITE(out_LSQ_RSP_ERROR       [execute_loop_id][load_store_unit_id][cache_access_id], PORT_READ(in_DCACHE_RSP_ERROR       [i]));
	  }
	else
	  ack = 0;
		
	PORT_WRITE(out_DCACHE_RSP_ACK [i],ack);
      }

    for (uint32_t i=0; i<_param->_nb_execute_loop; ++i)
      for (uint32_t j=0; j<_param->_nb_load_store_unit[i]; ++j)
	for (uint32_t k=0; k<_param->_nb_cache_access [i][j]; ++k)
	  PORT_WRITE(out_LSQ_RSP_VAL [i][j][k], lsq_rsp_val [i][j][k]);
      }
    else
      {
        for (uint32_t i=0; i<_param->_nb_dcache_port; ++i)
          PORT_WRITE(out_DCACHE_RSP_ACK [i],0);

        for (uint32_t i=0; i<_param->_nb_execute_loop; ++i)
          for (uint32_t j=0; j<_param->_nb_load_store_unit[i]; ++j)
            for (uint32_t k=0; k<_param->_nb_cache_access [i][j]; ++k)
              PORT_WRITE(out_LSQ_RSP_VAL [i][j][k], 0);
      }

    log_end(Dcache_Access,FUNCTION);
  };

}; // end namespace dcache_access
}; // end namespace core

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