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

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

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


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

    if (PORT_READ(in_NRESET))
      {
    for (uint32_t i=0; i<_param->_nb_inst_branch_update; i++)
      {
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * UPDATE [%d]",i);
	Tcontrol_t btb_ack = PORT_READ(in_UPDATE_BTB_ACK [i]);
	Tcontrol_t dir_ack = PORT_READ(in_UPDATE_DIR_ACK [i]);
	Tcontrol_t ras_ack = PORT_READ(in_UPDATE_RAS_ACK [i]);
	Tcontrol_t upt_val = PORT_READ(in_UPDATE_UPT_VAL [i]);

	Tcontrol_t upt_btb_val = PORT_READ(in_UPDATE_UPT_BTB_VAL [i]);
	Tcontrol_t upt_dir_val = PORT_READ(in_UPDATE_UPT_DIR_VAL [i]);
	Tcontrol_t upt_ras_val = PORT_READ(in_UPDATE_UPT_RAS_VAL [i]);
	
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_val               : %d",upt_val);
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_btb_val - btb_ack : %d - %d",upt_btb_val, btb_ack);
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_dir_val - dir_ack : %d - %d",upt_dir_val, dir_ack);
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_ras_val - ras_ack : %d - %d",upt_ras_val, ras_ack);

	Tcontrol_t btb_val = (upt_val  and
                              upt_btb_val and
//                            upt_dir_val and
//                            upt_ras_val and
// 			      (not upt_btb_val or (upt_btb_val and btb_ack)) and
			      (not upt_dir_val or (upt_dir_val and dir_ack)) and
			      (not upt_ras_val or (upt_ras_val and ras_ack))
                              );

	Tcontrol_t dir_val = (upt_val and 
//                            upt_btb_val and
                              upt_dir_val and
//                            upt_ras_val and
			      (not upt_btb_val or (upt_btb_val and btb_ack)) and
// 			      (not upt_dir_val or (upt_dir_val and dir_ack)) and
			      (not upt_ras_val or (upt_ras_val and ras_ack))
                              );

	Tcontrol_t ras_val = (upt_val  and
//                            upt_btb_val and
//                            upt_dir_val and
                              upt_ras_val and
			      (not upt_btb_val or (upt_btb_val and btb_ack)) and
			      (not upt_dir_val or (upt_dir_val and dir_ack))//  and
// 			      (not upt_ras_val or (upt_ras_val and ras_ack))
                              );

	Tcontrol_t upt_ack = (
//                            upt_val  and
//                            upt_btb_val and
//                            upt_dir_val and
//                            upt_ras_val and
			      (not upt_btb_val or (upt_btb_val and btb_ack)) and
			      (not upt_dir_val or (upt_dir_val and dir_ack)) and
			      (not upt_ras_val or (upt_ras_val and ras_ack))
                              );

        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    *     btb_val           : %d",btb_val);
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    *     dir_val           : %d",dir_val);
        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    *     ras_val           : %d",ras_val);

        PORT_WRITE(out_UPDATE_BTB_VAL [i], btb_val);
        PORT_WRITE(out_UPDATE_DIR_VAL [i], dir_val);
        PORT_WRITE(out_UPDATE_RAS_VAL [i], ras_val);
        PORT_WRITE(out_UPDATE_UPT_ACK [i], upt_ack);
      }
      }
    else
      {
        // RESET
        for (uint32_t i=0; i<_param->_nb_inst_branch_update; i++)
          {
            PORT_WRITE(out_UPDATE_BTB_VAL [i], 0);
            PORT_WRITE(out_UPDATE_DIR_VAL [i], 0);
            PORT_WRITE(out_UPDATE_RAS_VAL [i], 0);
            PORT_WRITE(out_UPDATE_UPT_ACK [i], 0);
          }
      }

    log_end(Prediction_unit_Glue,FUNCTION);
  };

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

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