#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::genMoore" void Update_Prediction_Table::genMoore (void) { log_begin(Update_Prediction_Table,FUNCTION); log_function(Update_Prediction_Table,FUNCTION,_name.c_str()); if (PORT_READ(in_NRESET) == 1) { // =================================================================== // =====[ DEPTH ]===================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_context; i++) { if (_param->_have_port_depth) { PORT_WRITE(out_DEPTH_CURRENT [i], reg_UPT_TOP [i]); PORT_WRITE(out_DEPTH_MIN [i], reg_UPT_BOTTOM [i]); } PORT_WRITE(out_DEPTH_MAX [i], reg_UPT_TOP [i]); } // =================================================================== // =====[ UPDATE ]==================================================== // =================================================================== bool retire_ras_from_ufpt [_param->_nb_context]; // event ufpt -> restore RAS, else update upt bool retire_ras_from_upt [_param->_nb_context]; // event upt -> restore RAS, else restore others structure bool ufpt_update [_param->_nb_context]; bool upt_update [_param->_nb_context]; Tdepth_t tab_ufpt_depth [_param->_nb_context]; Tdepth_t tab_upt_depth [_param->_nb_context]; for (uint32_t i=0; i<_param->_nb_context; i++) { event_state_t event_state = reg_EVENT_STATE [i]; retire_ras_from_ufpt [i] = ((event_state == EVENT_STATE_FLUSH_UFPT ) or (event_state == EVENT_STATE_FLUSH_UFPT_AND_UPT)); retire_ras_from_upt [i] = (event_state == EVENT_STATE_FLUSH_UPT); ufpt_update [i] = true; upt_update [i] = true; tab_ufpt_depth [i] = reg_UFPT_UPDATE [i]; tab_upt_depth [i] = reg_UPT_UPDATE [i]; } for (uint32_t i=0; i<_param->_nb_inst_update; i++) { Tcontext_t context = (reg_UPDATE_PRIORITY+i)%_param->_nb_context; log_printf(TRACE,Update_Prediction_Table,FUNCTION," * UPDATE [%d] (genMoore)",i); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * context : %d",context); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * event_state : %s",toString(reg_EVENT_STATE [context]).c_str()); Tcontrol_t val = false; Tcontrol_t val_without_ack = false; Tcontrol_t miss_prediction ; Tcontrol_t direction_good ; Tcontrol_t btb_val ; Taddress_t btb_address_src ; Taddress_t btb_address_dest ; Tbranch_condition_t btb_condition ; Tcontrol_t dir_val ; Thistory_t dir_history ; Tcontrol_t ras_val ; Tcontrol_t ras_flush ; Tcontrol_t ras_push ; Taddress_t ras_address ; Tptr_t ras_index ; Tcontrol_t ras_prediction_ifetch; // Test if update fetch prediction table need update port if (retire_ras_from_ufpt [context]) { if (ufpt_update [context]) { // Update Fetch Prediction Table // An update of ufpt is to previous miss. Just restore Return Address Stack Tdepth_t depth = tab_ufpt_depth[context]; ufpt_state_t state = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state; Tbranch_condition_t condition = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition; log_printf(TRACE,Update_Prediction_Table,FUNCTION," * Update Fetch Prediction Table"); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * depth : %d",depth ); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * state : %s",toString(state ).c_str()); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * condition : %s",toString(condition).c_str()); val = (state == UPDATE_FETCH_PREDICTION_STATE_EVENT); // val_without_ack = not update_ras(condition); miss_prediction = 1; // direction_good = ; btb_val = 0; // don't update btb (is update by the event branch) // btb_address_src = ; // btb_address_dest = ; // btb_condition = ; dir_val = 0; // don't update btb (is update by the event branch (if conditionnal branch)) // dir_history = ; ras_val = update_ras(condition); // repop/ repush data -> don't corrupt ras ras_flush = 0; ras_push = push_ras(condition); ras_address = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._address_ras; ras_index = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._index_ras; ras_prediction_ifetch = 1; internal_UPDATE_FROM_UFPT [i] = true; internal_UPDATE_DEPTH [i] = depth; internal_UPDATE_RAS [i] = false; // Warning : don't update same entry if (depth == reg_UFPT_BOTTOM[context]) ufpt_update [context] = false; tab_ufpt_depth[context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1; } } else { if (upt_update [context]) { // Update Prediction Table Tdepth_t depth = tab_upt_depth[context]; upt_state_t state = reg_UPDATE_PREDICTION_TABLE [context][depth]._state; Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition; Tcontrol_t ifetch = reg_UPDATE_PREDICTION_TABLE [context][depth]._ifetch_prediction; log_printf(TRACE,Update_Prediction_Table,FUNCTION," * Update Prediction Table"); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * depth : %d",depth ); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * state : %s",toString(state ).c_str()); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * condition : %s",toString(condition).c_str()); Tcontrol_t state_is_ok_ko = ((state == UPDATE_PREDICTION_STATE_OK ) or (state == UPDATE_PREDICTION_STATE_KO )); Tcontrol_t state_is_event = ((state == UPDATE_PREDICTION_STATE_KO ) or (state == UPDATE_PREDICTION_STATE_EVENT)); Tcontrol_t state_is_event_update = state_is_event and need_update(condition); Tcontrol_t state_is_event_no_update = state_is_event and not need_update(condition); if (retire_ras_from_upt [context]) { val = state_is_event_update; val_without_ack = state_is_event_no_update; } else { val = (state == UPDATE_PREDICTION_STATE_OK); val_without_ack = false; } miss_prediction = (state != UPDATE_PREDICTION_STATE_OK); direction_good = reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take ; btb_val = state_is_ok_ko and update_btb(condition); btb_address_src = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src ; btb_address_dest = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest; btb_condition = condition; dir_val = state_is_ok_ko and update_dir(condition) and ifetch; // if not ifetch, then static prediction dir_history = reg_UPDATE_PREDICTION_TABLE [context][depth]._history ; ras_val = update_ras(condition); // repop/ repush data -> don't corrupt ras ras_flush = (state == UPDATE_PREDICTION_STATE_KO); // miss prediction, RAS is corrupted ras_push = push_ras(condition); ras_address = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_ras; ras_index = reg_UPDATE_PREDICTION_TABLE [context][depth]._index_ras; ras_prediction_ifetch = ifetch; internal_UPDATE_FROM_UFPT [i] = false; internal_UPDATE_DEPTH [i] = depth; internal_UPDATE_RAS [i] = retire_ras_from_upt [context]; // Warning : don't update same entry if (retire_ras_from_upt [context]) { // Restore RAS. if ((depth == reg_UPT_BOTTOM[context]) or not (val or val_without_ack)) upt_update [context] = false; tab_upt_depth[context] = (depth==0)?(_param->_size_upt_queue[context]-1):(depth-1); } else { if ((depth == reg_UPT_TOP [context]) or not (val or val_without_ack)) upt_update [context] = false; tab_upt_depth[context] = (depth+1)%_param->_size_upt_queue[context]; } } } log_printf(TRACE,Update_Prediction_Table,FUNCTION," * val : %d",val ); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * val_without_ack : %d",val_without_ack); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * miss_prediction : %d",miss_prediction); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * direction_good : %d",direction_good ); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * btb_val : %d",btb_val); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * dir_val : %d",dir_val); log_printf(TRACE,Update_Prediction_Table,FUNCTION," * ras_val : %d",ras_val); internal_UPDATE_VAL [i] = val; internal_UPDATE_VAL_WITHOUT_ACK [i] = val_without_ack; internal_UPDATE_CONTEXT_ID [i] = context; PORT_WRITE(out_UPDATE_VAL [i],internal_UPDATE_VAL [i]); if (val) { if (_param->_have_port_context_id) PORT_WRITE(out_UPDATE_CONTEXT_ID [i],context ); PORT_WRITE(out_UPDATE_MISS_PREDICTION [i],miss_prediction ); PORT_WRITE(out_UPDATE_DIRECTION_GOOD [i],direction_good ); PORT_WRITE(out_UPDATE_BTB_VAL [i],btb_val ); PORT_WRITE(out_UPDATE_BTB_ADDRESS_SRC [i],btb_address_src ); PORT_WRITE(out_UPDATE_BTB_ADDRESS_DEST [i],btb_address_dest ); PORT_WRITE(out_UPDATE_BTB_CONDITION [i],btb_condition ); PORT_WRITE(out_UPDATE_DIR_VAL [i],dir_val ); if (_param->_have_port_history) PORT_WRITE(out_UPDATE_DIR_HISTORY [i],dir_history ); PORT_WRITE(out_UPDATE_RAS_VAL [i],ras_val ); PORT_WRITE(out_UPDATE_RAS_FLUSH [i],ras_flush ); PORT_WRITE(out_UPDATE_RAS_PUSH [i],ras_push ); PORT_WRITE(out_UPDATE_RAS_ADDRESS [i],ras_address ); PORT_WRITE(out_UPDATE_RAS_INDEX [i],ras_index ); PORT_WRITE(out_UPDATE_RAS_PREDICTION_IFETCH [i],ras_prediction_ifetch); } } // =================================================================== // =====[ BRANCH_EVENT ]============================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_context; i++) { Tcontrol_t val = (reg_EVENT_STATE [i] == EVENT_STATE_UPDATE_CONTEXT); PORT_WRITE(out_BRANCH_EVENT_VAL [i],val); PORT_WRITE(out_BRANCH_EVENT_ADDRESS_SRC [i],reg_EVENT_ADDRESS_SRC [i]); PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST_VAL [i],reg_EVENT_ADDRESS_DEST_VAL [i]); PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST [i],reg_EVENT_ADDRESS_DEST [i]); internal_BRANCH_EVENT_VAL [i] = val; } } 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