@@ -137,7 +137,6 @@ tageStats(this, p.numPredictors, p.numBanks)
137137
138138 // initialize use_alt_on_na table
139139 useAlt.resize (useAltOnNaSize, 0 );
140-
141140#ifndef UNIT_TEST
142141 hasDB = true ;
143142 switch (getDelay ()) {
@@ -640,56 +639,58 @@ BTBTAGE::handleNewEntryAllocation(const Addr &startPC,
640639}
641640
642641/* *
643- * @brief Updates the TAGE predictor state based on actual branch execution results
644- *
645- * @param stream The fetch stream containing branch execution information
642+ * @brief Probe resolved update for bank conflicts without mutating state.
643+ * Returns false if the update cannot proceed due to a bank conflict.
646644 */
647- void
648- BTBTAGE::update (const FetchStream &stream) {
645+ bool
646+ BTBTAGE::canResolveUpdate (const FetchStream &stream) {
649647 Addr startAddr = stream.getRealStartPC ();
650648 unsigned updateBank = getBankId (startAddr);
651649
652- DPRINTF (TAGE, " update startAddr: %#lx, bank: %u\n " , startAddr, updateBank);
653-
654650#ifndef UNIT_TEST
655- // Record update access per bank
651+ // Record attempted update access per bank (even if it conflicts)
656652 tageStats.updateAccessPerBank [updateBank]++;
657653#endif
658654
659- // ========== Bank Conflict Detection ==========
660- // Check if this update conflicts with the last prediction
661- // Only perform conflict detection if enableBankConflict is true
662- if (enableBankConflict) {
663- // Conflict happens when:
664- // 1. There was a valid prediction in this or previous tick (predBankValid)
665- // 2. Update and prediction target the same bank (updateBank == lastPredBankId)
666- //
667- // Note: This assumes one update() call per tick (guaranteed by fetch stage)
668- if (predBankValid && updateBank == lastPredBankId) {
669- tageStats.updateBankConflict ++;
670- tageStats.updateDroppedDueToConflict ++;
671-
655+ if (enableBankConflict && predBankValid && updateBank == lastPredBankId) {
656+ tageStats.updateBankConflict ++;
657+ tageStats.updateDeferredDueToConflict ++;
672658#ifndef UNIT_TEST
673- // Record conflict for this specific bank
674- tageStats.updateBankConflictPerBank [updateBank]++;
659+ tageStats.updateBankConflictPerBank [updateBank]++;
675660#endif
661+ DPRINTF (TAGE, " Bank conflict detected: update bank %u conflicts with prediction bank %u, "
662+ " deferring this update (will retry after blocking prediction)\n " ,
663+ updateBank, lastPredBankId);
664+ predBankValid = false ;
665+ return false ;
666+ }
676667
677- DPRINTF (TAGE, " Bank conflict detected: update bank %u conflicts with "
678- " prediction bank %u, dropping this update\n " ,
679- updateBank, lastPredBankId);
680-
681- // Clear prediction state after consuming it
682- predBankValid = false ;
683- return ; // Drop this update entirely
684- }
668+ return true ;
669+ }
685670
686- // If no conflict, clear prediction state (prediction has been consumed)
687- if (predBankValid) {
688- DPRINTF (TAGE, " No bank conflict: update bank %u != prediction bank %u\n " ,
689- updateBank, lastPredBankId);
690- }
671+ /* *
672+ * @brief Perform resolved update after probe success.
673+ */
674+ void
675+ BTBTAGE::doResolveUpdate (const FetchStream &stream) {
676+ if (enableBankConflict && predBankValid) {
677+ // Prediction consumed; clear bank tag for next cycle
691678 predBankValid = false ;
692679 }
680+ update (stream);
681+ }
682+
683+ /* *
684+ * @brief Updates the TAGE predictor state based on actual branch execution results
685+ *
686+ * @param stream The fetch stream containing branch execution information
687+ */
688+ void
689+ BTBTAGE::update (const FetchStream &stream) {
690+ Addr startAddr = stream.getRealStartPC ();
691+ unsigned updateBank = getBankId (startAddr);
692+
693+ DPRINTF (TAGE, " update startAddr: %#lx, bank: %u\n " , startAddr, updateBank);
693694
694695 // ========== Normal Update Logic ==========
695696 // Prepare BTB entries to update
@@ -1023,7 +1024,7 @@ BTBTAGE::TageStats::TageStats(statistics::Group* parent, int numPredictors, int
10231024 ADD_STAT (updateMispred, statistics::units::Count::get (), " mispred when update" ),
10241025 ADD_STAT (updateResetU, statistics::units::Count::get (), " reset u when update" ),
10251026 ADD_STAT (updateBankConflict, statistics::units::Count::get (), " number of bank conflicts detected" ),
1026- ADD_STAT (updateDroppedDueToConflict , statistics::units::Count::get (), " number of updates dropped due to bank conflict" ),
1027+ ADD_STAT (updateDeferredDueToConflict , statistics::units::Count::get (), " number of updates deferred due to bank conflict (retried later) " ),
10271028 ADD_STAT (updateBankConflictPerBank, statistics::units::Count::get (), " bank conflicts per bank" ),
10281029 ADD_STAT (updateAccessPerBank, statistics::units::Count::get (), " update accesses per bank" ),
10291030 ADD_STAT (predAccessPerBank, statistics::units::Count::get (), " prediction accesses per bank" ),
0 commit comments