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

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Meta_Predictor_Glue/include/Meta_Predictor_Glue.h"

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

namespace meta_predictor {
namespace meta_predictor_glue {

  void Meta_Predictor_Glue::genMealy_branch_complete_val (void)
  {
    log_printf(FUNC,Meta_Predictor_Glue,"genMealy_branch_complete_val","Begin");
    
    for (uint32_t i=0; i<_param._nb_branch_complete; i++)
      {
	Tcontrol_t val                   = PORT_READ(in_BRANCH_COMPLETE_VAL             [i]);
	Thistory_t history               = PORT_READ(in_BRANCH_COMPLETE_HISTORY         [i]);
	Tcontrol_t direction             = PORT_READ(in_BRANCH_COMPLETE_DIRECTION       [i]);

	Tcontrol_t predictor_0_direction = (history>>(_param._shift_2-1))&1;
	Tcontrol_t predictor_1_direction = (history>>(_param._shift_4-1))&1;
// 	Tcontrol_t predictor_2_direction = (history>>(_param._shift_6-1))&1;

// 	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val","direction_(predictor_0 %d, predictor_1 %d, predictor_2 %d, good %d)", predictor_0_direction, predictor_1_direction, predictor_2_direction, direction);
	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val","direction_(predictor_0 %d, predictor_1 %d, good %d)", predictor_0_direction, predictor_1_direction, direction);

	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val"," *  direction_0 : %d >>(%d-1)",history,_param._shift_2);
	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val"," *  direction_1 : %d >>(%d-1)",history,_param._shift_4);
	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val"," *  direction_2 : %d >>(%d-1)",history,_param._shift_6);

	/*
	dir_0 dir_1 dir_2 | good_dir  || next_dir_2
	------------------+-----------++-----------
	  0     0     0   |     0     || no change 
	  1     0     0   |     0     ||         1 select pred_0 but miss
	  0     1     0   |     0     ||         0 select pred_0 and hit 
	  1     1     0   |     0     || no change
	  0     0     1   |     0     || no change
	  1     0     1   |     0     ||         1 select pred_1 and hit 
	  0     1     1   |     0     ||         0 select pred_1 but miss
	  1     1     1   |     0     || no change
	  0     0     0   |     1     || no change
	  1     0     0   |     1     ||         0 select pred_0 and hit 
	  0     1     0   |     1     ||         1 select pred_0 but miss
	  1     1     0   |     1     || no change
	  0     0     1   |     1     || no change
	  1     0     1   |     1     ||         0 select pred_1 but miss
	  0     1     1   |     1     ||         1 select pred_1 and hit 
	  1     1     1   |     1     || no change

	next_dir_2 = (good_dir and dir_1) or (not good_dir and dir_0)
	*/

	Tcontrol_t branch_complete_predictor_2_val       =       val and (predictor_0_direction xor predictor_1_direction);
	Tcontrol_t branch_complete_predictor_2_direction = ( (not direction and predictor_0_direction) or
							     (    direction and predictor_1_direction) );

	log_printf(TRACE,Meta_Predictor_Glue,"genMealy_branch_complete_val","branch_complete_predictor_2_( val %d, direction %d)",branch_complete_predictor_2_val, branch_complete_predictor_2_direction);

	// Modify meta_predictor if have a branch_complete and twice prediction have not predict the same way
									  PORT_WRITE(out_BRANCH_COMPLETE_PREDICTOR_2_DIRECTION [i], branch_complete_predictor_2_direction);
	PORT_WRITE(out_BRANCH_COMPLETE_PREDICTOR_2_VAL       [i], branch_complete_predictor_2_val      );
      }

    log_printf(FUNC,Meta_Predictor_Glue,"genMealy_branch_complete_val","End");
  };

}; // end namespace meta_predictor_glue
}; // end namespace meta_predictor

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

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