#ifdef SYSTEMC
/*
 * $Id: Dcache_Access_genMealy_req.cpp 88 2008-12-10 18:31:39Z 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_req"
  void Dcache_Access::genMealy_req (void)
  {
    log_begin(Dcache_Access,FUNCTION);

    Tcontrol_t dcache_req_val [_param->_nb_dcache_port];
    for (uint32_t i=0; i<_param->_nb_dcache_port; ++i)
      {
	dcache_req_val [i] = 0;
	
#ifdef STATISTICS
	_internal_DCACHE_REQ_NB_ACCESS         [i] = 0;
	_internal_DCACHE_REQ_NB_ACCESS_CONFLIT [i] = 0;
#endif
      }
    
    Tcontrol_t lsq_req_ack [_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_req_ack [i][j][k] = 0;
    
    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_execute_loop    = it->grp;
	uint32_t num_load_store_unit = it->elt;
	
	for (uint32_t num_cache_access = 0; num_cache_access<_param->_nb_cache_access [num_execute_loop][num_load_store_unit]; ++num_cache_access)
	  {
	    if (PORT_READ(in_LSQ_REQ_VAL [num_execute_loop][num_load_store_unit][num_cache_access]))
	      {
		uint32_t   num_port       = _param->_table_routing[num_execute_loop][num_load_store_unit][num_cache_access];
		Tcontrol_t dcache_req_ack = PORT_READ(in_DCACHE_REQ_ACK [num_port]);
		
#ifdef STATISTICS
		if (dcache_req_ack)
		  {
		    _internal_DCACHE_REQ_NB_ACCESS [num_port] ++;
		    if (dcache_req_val [num_port])
		    _internal_DCACHE_REQ_NB_ACCESS_CONFLIT [num_port] ++;
		  }
#endif
		if (not dcache_req_val [num_port])
		  {
		    dcache_req_val  [num_port] = 1;
		    lsq_req_ack [num_execute_loop][num_load_store_unit][num_cache_access] = dcache_req_ack;
		    
		    if (_param->_have_port_dcache_thread_id)
                      {
		    Tcontext_t num_context = (_param->_have_port_lsq_thread_id [num_execute_loop][num_load_store_unit])?PORT_READ(in_LSQ_REQ_THREAD_ID [num_execute_loop][num_load_store_unit][num_cache_access]):0;
                    PORT_WRITE(out_DCACHE_REQ_THREAD_ID [num_port], _param->_translate_load_store_unit_to_thread[num_execute_loop][num_load_store_unit][num_context]);
                      }
// 		    PORT_WRITE(out_DCACHE_REQ_THREAD_ID [num_port], ((num_execute_loop    << _param->_shift_num_execute_loop   )+
// 								     (num_load_store_unit << _param->_shift_num_load_store_unit)+
// 								     (num_cache_access    << _param->_shift_num_cache_access   )+
// 								      num_context));
 		    if (_param->_have_port_dcache_packet_id)
                      {
                    Tpacket_t packet_id = (_param->_have_port_lsq_packet_id [num_execute_loop][num_load_store_unit])?PORT_READ(in_LSQ_REQ_PACKET_ID [num_execute_loop][num_load_store_unit][num_cache_access]):0;
                    PORT_WRITE(out_DCACHE_REQ_PACKET_ID [num_port], ((num_cache_access    << _param->_shift_num_cache_access   )+
                                                                     packet_id));
                      }
		    PORT_WRITE(out_DCACHE_REQ_ADDRESS   [num_port], PORT_READ(in_LSQ_REQ_ADDRESS   [num_execute_loop][num_load_store_unit][num_cache_access]));
		    PORT_WRITE(out_DCACHE_REQ_WDATA     [num_port], PORT_READ(in_LSQ_REQ_WDATA     [num_execute_loop][num_load_store_unit][num_cache_access]));
		    PORT_WRITE(out_DCACHE_REQ_TYPE      [num_port], PORT_READ(in_LSQ_REQ_TYPE      [num_execute_loop][num_load_store_unit][num_cache_access]));
		  }
	      }
	  }
      }
    
    for (uint32_t i=0; i<_param->_nb_dcache_port; ++i)
      PORT_WRITE(out_DCACHE_REQ_VAL [i], dcache_req_val [i]);
    
    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_REQ_ACK [i][j][k], lsq_req_ack [i][j][k]);

    log_end(Dcache_Access,FUNCTION);
  };

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

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