#ifdef SYSTEMC
/*
 * $Id$
 *
 * [ Description ]
 * 
 */

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

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


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

    if (PORT_READ(in_NRESET) != 0)
      {
    // For each prediction
    for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
      {
        // Read information
	Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
	uint32_t   top     = reg_UFPT_TOP[context]; // not multi branch prediction

	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"PREDICT [%d] (genMealy)",i);
	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * context     : %d",context);
	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * top         : %d",top);
	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * state       : %s",toString(reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state).c_str());
	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * is accurate : %d",PORT_READ(in_PREDICT_BTB_IS_ACCURATE [i]));
// 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * need update : %d",reg_NB_ELT_NEED_UPDATE [context]);

        bool is_accurate = (_param->_always_accurate_predict or 
                            (_param->_can_accurate_predict and reg_IS_ACCURATE [context]));

        // Ack if :
        //  * no previous event (ufpt and upt is ok)
        //  * top slot is empty
        //  * is_accurate
	internal_PREDICT_ACK [i] = ((reg_UFPT_EVENT_STATE [context] == UFPT_EVENT_STATE_OK) and
                                    (reg_UPT_EVENT_STATE  [context] == UPT_EVENT_STATE_OK ) and
                                    (reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state == UPDATE_FETCH_PREDICTION_STATE_EMPTY) and
                                    is_accurate);

        internal_PREDICT_UPDATE_PREDICTION_ID [i] = top;

 	log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * ACK         : %d",internal_PREDICT_ACK [i]);

        if (_param->_have_port_depth)
        PORT_WRITE(out_PREDICT_UPDATE_PREDICTION_ID [i], internal_PREDICT_UPDATE_PREDICTION_ID [i]);
      }

      }//don't reset
    else
      {
        for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
          {
            internal_PREDICT_ACK [i] = 0;
//          internal_PREDICT_UPDATE_PREDICTION_ID [i] = top;
          }
      }

    for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
      PORT_WRITE(out_PREDICT_ACK [i], internal_PREDICT_ACK [i]);

    log_end(Update_Prediction_Table,FUNCTION);
  };

}; // end namespace update_prediction_table
}; // end namespace prediction_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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