#ifdef SYSTEMC /* * $Id: Two_Level_Branch_Predictor_transition.cpp 124 2009-06-17 12:11:25Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor/include/Two_Level_Branch_Predictor.h" // #include namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace prediction_unit { namespace direction { namespace meta_predictor { namespace two_level_branch_predictor { #undef FUNCTION #define FUNCTION "Two_Level_Branch_Predictor::transition" void Two_Level_Branch_Predictor::transition (void) { log_begin(Two_Level_Branch_Predictor,FUNCTION); log_function(Two_Level_Branch_Predictor,FUNCTION,_name.c_str()); if (PORT_READ(in_NRESET) == 0) { } else { // =================================================================== // =====[ PREDICT ]=================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_inst_predict; ++i) if (PORT_READ(in_PREDICT_VAL[i]) and internal_PREDICT_ACK[i]) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * PREDICT [%d]",i); // Predict if // * update_on_prediction and direction is valid if (_param->_update_on_prediction) if (PORT_READ(in_PREDICT_DIRECTION_VAL [i])) { Tcontrol_t direction = PORT_READ(in_PREDICT_DIRECTION [i]); if (_param->_have_bht) { Thistory_t bht_num_reg = internal_PREDICT_BHT_NUM_REG [i]; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_num_reg : %lld",bht_num_reg); // #ifdef DEBUG_TEST // assert(bht_num_reg < _param->_bht_nb_shifter); // #endif Thistory_t bht_history = reg_BHT[bht_num_reg]; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_history (old): %llx",bht_history); bht_history = ((bht_history<<1) | direction)&_param->_bht_history_mask ; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_history (new): %llx",bht_history); reg_BHT [bht_num_reg] = bht_history; } if (_param->_have_pht) { Thistory_t pht_num_reg = internal_PREDICT_PHT_NUM_REG [i]; Thistory_t pht_num_bank= internal_PREDICT_PHT_NUM_BANK [i]; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_num_reg : %lld",pht_num_reg); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_num_bank : %lld",pht_num_bank); Thistory_t pht_history = reg_PHT [pht_num_bank][pht_num_reg]; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_history (old): %llx",pht_history); // PHT : saturation counter pht_history = (direction==1)?((pht_history<_param->_pht_counter_max)?(pht_history+1):(pht_history)):((pht_history>0)?(pht_history-1):(pht_history)); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_history (new): %llx",pht_history); reg_PHT [pht_num_bank][pht_num_reg] = pht_history; } } } // =================================================================== // =====[ UPDATE ]==================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_inst_update; ++i) if (PORT_READ(in_UPDATE_VAL[i]) and internal_UPDATE_ACK[i]) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * UPDATE [%d]",i); if (_param->_update_on_prediction) log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * miss : %d",PORT_READ(in_UPDATE_MISS [i])); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * update_on_predict: %d",_param->_update_on_prediction); // Update if // * update_on_prediction and miss // * not update_on_prediction Tcontrol_t history_val = PORT_READ(in_UPDATE_HISTORY_VAL [i]); if (not _param->_update_on_prediction or (_param->_update_on_prediction and PORT_READ(in_UPDATE_MISS [i])) or not history_val // static_prediction ) { Taddress_t address = PORT_READ(in_UPDATE_ADDRESS [i]); Thistory_t history = PORT_READ(in_UPDATE_HISTORY [i]); Tcontrol_t direction = PORT_READ(in_UPDATE_DIRECTION [i])&1; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * address : %.8x",address); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * direction : %d",direction); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * history_val : %d",direction); Thistory_t pht_bht_history = 0; if (_param->_have_bht) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht"); Thistory_t bht_history = (history>>_param->_bht_history_shift )&_param->_bht_history_mask; Thistory_t bht_num_reg = address & _param->_bht_address_mask; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_history (old): %llx",bht_history); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_num_reg : %llx",bht_num_reg); // BHT : shift register if (not history_val) { bht_history = (direction)?_param->_bht_init_take:_param->_bht_init_ntake; } else { bht_history = ((bht_history<<1) | direction)&_param->_bht_history_mask ; } pht_bht_history = bht_history; log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_history (new): %llx",bht_history); // #ifdef DEBUG_TEST // assert(bht_num_reg < _param->_bht_nb_shifter); // #endif reg_BHT [bht_num_reg] = bht_history; } if (_param->_have_pht) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht"); Thistory_t pht_history = (history>>_param->_pht_history_shift )&_param->_pht_history_mask; Thistory_t pht_num_bank= (address>>_param->_pht_address_bank_shift )&_param->_pht_address_bank_mask; Thistory_t pht_num_reg = pht_bht_history xor ((address&_param->_pht_address_share_mask)<<_param->_pht_address_share_shift); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * bht_history (old): %llx",pht_bht_history); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_history (old): %llx",pht_history); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_num_reg : %llx",pht_num_reg); log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_num_bank : %llx",pht_num_bank); // PHT : saturation counter if (not history_val) { pht_history = (direction)?_param->_pht_init_take:_param->_pht_init_ntake; } else { pht_history = (direction==1)?((pht_history<_param->_pht_counter_max)?(pht_history+1):(pht_history)):((pht_history>0)?(pht_history-1):(pht_history)); } log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * pht_history (new): %llx",pht_history); reg_PHT [pht_num_bank][pht_num_reg] = pht_history; } } } } #if defined(DEBUG) and DEBUG_Two_Level_Branch_Predictor and (DEBUG >= DEBUG_TRACE) # if 0 { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * Dump Two_Level_Branch_Predictor"); if (_param->_have_bht) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * Dump BHT"); uint32_t limit = 4; for (uint32_t i=0; i<_param->_bht_nb_shifter; i+=limit) { std::string str = ""; for (uint32_t j=0; j= _param->_bht_nb_shifter) break; else { str+=toString("[%.4d] %.4x ",index,reg_BHT[index]); } } log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," %s",str.c_str()); } } if (_param->_have_pht) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," * Dump PHT"); uint32_t limit = 4; for (uint32_t num_bank=0; num_bank <_param->_pht_nb_bank; ++num_bank) { if (_param->_pht_size_bank == 1) { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," [%.4d][0000] %4x",num_bank,reg_PHT[num_bank][0]); } else { log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," [%.4d]",num_bank); for (uint32_t i=0; i<_param->_pht_size_bank; i+=limit) { std::string str = ""; for (uint32_t j=0; j= _param->_pht_size_bank) break; else str+=toString("[%.4d] %.4x ",index,reg_PHT[num_bank][index]); } log_printf(TRACE,Two_Level_Branch_Predictor,FUNCTION," %s",str.c_str()); } } } } } # endif #endif #if defined(STATISTICS) or defined(VHDL_TESTBENCH) end_cycle (); #endif log_end(Two_Level_Branch_Predictor,FUNCTION); }; }; // end namespace two_level_branch_predictor }; // end namespace meta_predictor }; // end namespace direction }; // end namespace prediction_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif