#ifdef SYSTEMC
/*
 * $Id: Return_Address_Stack_genMealy_predict.cpp 118 2009-05-20 22:01:32Z 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_predict"
  void Return_Address_Stack::genMealy_predict (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_predict; i++)
      {
        // Read context number
	Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
        
#ifdef DEBUG_TEST
	if (PORT_READ(in_PREDICT_VAL [i]))
	  {
	    if (context_valid[context] == false)
	      ERRORMORPHEO(FUNCTION,"Can't have 2 transactions with the same context_id");
	    context_valid[context] = false;
	  }
#endif
        
        // Get top
	Tptr_t     top  = reg_PREDICT_TOP[context];
	Tcontrol_t push = PORT_READ(in_PREDICT_PUSH [i]);

        // Hit :
	//   * if push : value is hit
	//   * if pop  : no empty
	internal_PREDICT_HIT [i] = (push or (reg_PREDICT_NB_ELT[context]>0));

	PORT_WRITE(out_PREDICT_HIT         [i], internal_PREDICT_HIT [i]);

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

	PORT_WRITE(out_PREDICT_ADDRESS_POP [i], reg_stack[context][top]._address);

	PORT_WRITE(out_PREDICT_INDEX       [i], top);
      }
      }

    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
