#ifdef SYSTEMC
/*
 * $Id: Return_Address_Stack_genMealy_decod.cpp 123 2009-06-08 20:43:30Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Return_Address_Stack/include/Return_Address_Stack.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace prediction_unit {
namespace return_address_stack {


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

    if (PORT_READ(in_NRESET) == 1)
      {
#ifdef DEBUG_TEST
    // just to test if have many transaction on a same context
    bool context_valid [_param->_nb_context];
    for (uint32_t i=0; i<_param->_nb_context; i++)
      context_valid [i] = true;
#endif

    for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
      {
        // Read context number
	Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;

#ifdef DEBUG_TEST
	if (PORT_READ(in_DECOD_VAL [i]))
	  {
	    if (context_valid[context] == false)
	      ERRORMORPHEO(FUNCTION,"Can't have 2 transactions with the same context_id");
	    context_valid[context] = false;
	  }
#endif

	Tptr_t     top  = reg_TOP[context];
	Tcontrol_t push = PORT_READ(in_DECOD_PUSH [i]);

	// if push : value is hit
	// if pop  : val and not miss
	//   when the predictor : if hit = 0, wait (is not accurate)
	internal_DECOD_HIT [i] = (push or (reg_NB_ELT[context]>0));
	PORT_WRITE(out_DECOD_HIT         [i], internal_DECOD_HIT [i]);

	// if pop  : address_pop   = stack [top]
	// if push : stock [top+1] = address_push; also stock [top+1] is erase ! give the old value at the update table
	if (push)
	  top = (top+1)%_param->_size_queue[context];

	PORT_WRITE(out_DECOD_ADDRESS_POP [i], reg_stack[context][top]._address);
	PORT_WRITE(out_DECOD_INDEX       [i], top);
      }
      }
    else
      {
// 	internal_DECOD_HIT [i] = (push or (reg_NB_ELT[context]>0));
      }

    log_end(Return_Address_Stack,FUNCTION);
  };

}; // end namespace return_address_stack
}; // end namespace prediction_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
