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

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Branch_Target_Buffer/Branch_Target_Buffer_Register/include/Branch_Target_Buffer_Register.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace prediction_unit {
namespace branch_target_buffer {
namespace branch_target_buffer_register {

#undef  FUNCTION
#define FUNCTION "Branch_Target_Buffer_Register::genMealy_decod"
  void Branch_Target_Buffer_Register::genMealy_decod (void)
  {
    log_printf(FUNC,Branch_Target_Buffer_Register,FUNCTION,"Begin");

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

	Tcontrol_t      hit       = false;
	uint32_t        num_bank  = (address>>_param->_shift_bank)&_param->_mask_bank;
	uint32_t        num_entry = 0;
	
	if (PORT_READ(in_DECOD_VAL [i]))
	  for (;num_entry < _param->_associativity; num_entry ++)
	    {
	      hit = ((reg_BTB[num_bank][num_entry]._val         == 1      ) and
		     (reg_BTB[num_bank][num_entry]._context     == context) and
		     (reg_BTB[num_bank][num_entry]._address_src == address));

	      if (hit)
		break;
	    }

	internal_DECOD_HIT       [i] = hit      ;
	internal_DECOD_NUM_BANK  [i] = num_bank ;
	internal_DECOD_NUM_ENTRY [i] = num_entry;

	PORT_WRITE(out_DECOD_HIT       [i], hit);
	if (_param->_have_port_victim)
	PORT_WRITE(out_DECOD_HIT_INDEX [i], num_entry);
      }

    log_printf(FUNC,Branch_Target_Buffer_Register,FUNCTION,"End");
  };

}; // end namespace branch_target_buffer_register
}; // end namespace branch_target_buffer
}; // end namespace prediction_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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