Skip to content

Utage check rtl align#773

Open
CJ362ff wants to merge 43 commits intoxs-devfrom
utage-check-RTL-align
Open

Utage check rtl align#773
CJ362ff wants to merge 43 commits intoxs-devfrom
utage-check-RTL-align

Conversation

@CJ362ff
Copy link
Collaborator

@CJ362ff CJ362ff commented Mar 6, 2026

Summary by CodeRabbit

  • New Features

    • Adds a MicroTAGE branch predictor with multi-table, bank-aware prediction and expanded prediction/update diagnostics and stats.
    • Exposes MicroTAGE as a selectable predictor type in the public API.
  • Chores

    • Integrates the new predictor into the build and adds a dedicated debug flag for tracing.
    • Example configs updated: one enables MicroTAGE; another adds a commented toggle suggestion.

Cao Jiaming added 30 commits March 6, 2026 11:35
Change-Id: I44b6175022a3a593ed385407bd95ec0c40c74642
Change-Id: I16ce79a7d8488d9a138d0a26f5500576ae54132e
Change-Id: I8be037a1cdacd7151f4fe8e743a32cca90a85036
Change-Id: I6b9c92c18c574a12c19532ae0b894e64c1187342
Change-Id: I953965b8e6feb1c15a238ac832d65bc16b32f496
Change-Id: I39cd471d452aa343c3dd741a80fdfa7d126e3a9f
Change-Id: I3567ae93652aac218c5b4646003abadddaf7cf32
Change-Id: If7c9d3aa68a23c36dde74d8cf3a286c9c48f3e3c
Change-Id: I83277ae5c801e9d22b594286580459d12cdec69b
Change-Id: I394246af184d3f07e02b85f06e4e5ceed368ec22
Change-Id: I762c11f8d15262fb9f1c9d443f77895fa76bbc79
Change-Id: Ia9bcdc028235447e254889d95e5ea98e7f067664
Change-Id: I56614e8ebc2dd33320d353562087ab456fc452da
Change-Id: Icdc7ac7f047a36dba6733a0e1d11e5e37aa4cdf1
Change-Id: I9cb7e7ef04efefbcbdbf705563563f50f3c83324
Change-Id: Iad486579b9ab0df207013348f02c6be30bd10cfd
Change-Id: I20e9fbfe161cd741b37bb69d46e99ee7755f79e5
Change-Id: If1187310e575a7c485d49fb89215742b1174393a
Change-Id: I2b9f9216a54405d517538958b717a8e3de2eca8a
Change-Id: I8c70b06b834fd5e713ef9ac4d3b26ec5b01ce2e6
Change-Id: Ic736ea7cc73abebb3af473510c16d837b4f535f4
Change-Id: I94ccc54b623bbf488bdaae9086c3cfff92c1fcdf
Change-Id: Ic7a506f9ee3bbbcaaf6b50f28cf74dc4a407cea8
Change-Id: Iffd21dbdb9f633841d1a9ac33dcd4e7f5f53b992
Change-Id: I93ab507fc32d1096a5fd07f68d85740577eb6ea9
Cao Jiaming added 9 commits March 6, 2026 11:40
Change-Id: I72fbca71841e9209f8803e928af907a8c1106bf2
Change-Id: If64a72e75eb5e8ee4c280a8362577617efa0c964
Change-Id: I0b5a16c19b91c36649a17171e49eb000626e7b98
Change-Id: I32ce96420169227820174c54ea4d7b423b910d22
Change-Id: I67953b502b3d2cb0f08a66f58537f6eaa800cdf1
Change-Id: Ic0faea91ca80f67e9b106eab459e3098bfe3b5a9
Change-Id: I34219f5fc8b3c4ac7ed515dd57aaca6543fcb4ba
Change-Id: I727d76e59df69d0cef0089b87a4e671ca25546b9
Change-Id: I15c1f248fa079ddd5b8cf4525fbaf23e04ddb1cf
@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new MicroTAGE branch predictor (header + implementation), exposes it as a first‑class SimObject, integrates it into build and configs, updates DecoupledBPUWithBTB to use MicroTAGE, and toggles MicroTAGE in example configs (one config enables it; another adds a commented suggestion).

Changes

Cohort / File(s) Summary
Config examples
configs/example/idealkmhv3.py, configs/example/kmhv3.py
idealkmhv3.py adds a commented suggestion about cpu.branchPred.microtage.enabled = False; kmhv3.py enables cpu.branchPred.microtage.enabled = True.
Predictor public API & build
src/cpu/pred/BranchPredictor.py, src/cpu/pred/SConscript
Adds MicroTAGE as a first‑class SimObject with expanded Param fields; registers MicroTAGE in BpType enum, adds btb/microtage.cc to build inputs, and introduces UTAGE debug flag.
BTB/Decoupled integration
src/cpu/pred/btb/decoupled_bpred.hh
Adds #include "cpu/pred/btb/microtage.hh" and changes DecoupledBPUWithBTB::microtage member type from BTBTAGE* to MicroTAGE*.
MicroTAGE header
src/cpu/pred/btb/microtage.hh
New public MicroTAGE class (TimedBaseBTBPredictor) with UNIT_TEST/production constructors, lifecycle/predict/update APIs, nested types (TageEntry/TagePrediction/TageStats), folded-history and bank-aware indexing interfaces.
MicroTAGE implementation
src/cpu/pred/btb/microtage.cc
Large production and UNIT_TEST implementation (~+1.1k lines): constructors/destructor, prediction generation, lookup/update logic, history folding, bank‑conflict handling, allocation logic, recovery, stats, and test scaffolding.

Sequence Diagram

sequenceDiagram
    participant Fetch as Fetch Pipeline
    participant MicroTAGE as MicroTAGE Predictor
    participant History as History Manager
    participant Tables as TAGE Tables
    participant Stats as Statistics

    Fetch->>MicroTAGE: putPCHistory(startPC, history)
    MicroTAGE->>History: compute/store folded histories
    Fetch->>MicroTAGE: generateSinglePrediction(BTBEntry, startPC)
    MicroTAGE->>Tables: getTageIndex/getTageTag(pc, table, foldedHist)
    Tables-->>MicroTAGE: entries / tag-match info
    MicroTAGE-->>Fetch: return prediction
    Fetch->>MicroTAGE: update(FetchTarget with actual outcome)
    MicroTAGE->>Tables: updatePredictorStateAndCheckAllocation()
    alt allocation needed
        MicroTAGE->>Tables: handleNewEntryAllocation()
        Tables->>Tables: select victim / allocate slot
    end
    MicroTAGE->>Stats: record update and misprediction metrics
    MicroTAGE->>History: recoverPHist() on misprediction
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

perf

Suggested reviewers

  • Yakkhini
  • jensen-yan

Poem

🐇 I fold the bits and chase each branch's light,
I hop through tables, pick a tag just right,
Counters click and banks hum soft at night,
I allocate, recover, and then delight—
A rabbit's hop to keep predictions bright.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Utage check rtl align' is vague and does not clearly convey the main purpose of the changeset, which involves introducing a new MicroTAGE branch predictor class and enabling it in configurations. Replace with a more descriptive title that clearly indicates the main change, such as 'Introduce MicroTAGE branch predictor implementation' or 'Add MicroTAGE predictor and enable RTL alignment checks'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch utage-check-RTL-align

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
src/cpu/pred/btb/microtage.cc (3)

772-783: Same potential issue for index bit width.

Similar to the tag calculation, the index mask could exhibit undefined behavior if tableIndexBits[t] >= 64.

🛡️ Optional: Add defensive bounds check
 Addr
 MicroTAGE::getTageIndex(Addr pc, int t, uint64_t foldedHist)
 {
     // Create mask for tableIndexBits[t] to limit result size
+    assert(tableIndexBits[t] < 64 && "Index bit width must be less than 64");
     Addr mask = (1ULL << tableIndexBits[t]) - 1;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 772 - 783,
MicroTAGE::getTageIndex builds mask with (1ULL << tableIndexBits[t]) - 1 which
is undefined when tableIndexBits[t] >= 64; add a defensive check in getTageIndex
to handle that case (or generally any tableIndexBits[t] >= sizeof(mask)*8) by
creating the mask without shifting past the word size (e.g., if
tableIndexBits[t] >= 64 set mask = ~0ULL else mask = (1ULL << tableIndexBits[t])
- 1), ensure mask uses a 64-bit type and then keep the existing
pcShift/indexShift, pcBits and foldedBits logic and return pcBits ^ foldedBits.

329-334: Minor: Signed/unsigned comparison in loop.

The loop compares int s with stagePreds.size() (which returns size_t). While safe in practice given reasonable stage counts, using consistent types would be cleaner.

♻️ Optional: Use consistent unsigned type
-    for (int s = getDelay(); s < stagePreds.size(); s++) {
+    for (size_t s = getDelay(); s < stagePreds.size(); s++) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 329 - 334, The loop uses an int
index `s` compared to `stagePreds.size()` (size_t); change the loop to use an
unsigned/size type to avoid signed/unsigned comparison—e.g. compute a size_t
start = static_cast<size_t>(std::max(0, getDelay())) (or otherwise safely cast
getDelay()) and iterate `for (size_t s = start; s < stagePreds.size(); ++s)` so
references like `stage_pred`, `stagePreds`, `lookupHelper(startPC,
stage_pred.btbEntries, stage_pred.condTakens)` remain unchanged.

753-770: Potential undefined behavior if tag bit width >= 64.

The mask calculation (1ULL << tableTagBits[t]) - 1 would exhibit undefined behavior if tableTagBits[t] >= 64. While the current Python defaults use 16 bits, adding a defensive check would prevent issues if parameters are misconfigured.

🛡️ Optional: Add defensive bounds check
 Addr
 MicroTAGE::getTageTag(Addr pc, int t, uint64_t foldedHist, uint64_t altFoldedHist, Addr position)
 {
     // Create mask for tableTagBits[t] to limit result size
+    assert(tableTagBits[t] < 64 && "Tag bit width must be less than 64");
     Addr mask = (1ULL << tableTagBits[t]) - 1;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 753 - 770, The mask calculation
in MicroTAGE::getTageTag can UB when tableTagBits[t] >= 64; change the mask
logic to handle this case safely by using a 64-bit mask variable (uint64_t) and
computing mask = (tableTagBits[t] >= 64) ? ~0ULL : ((1ULL << tableTagBits[t]) -
1); keep the rest of the function logic (pcBits, foldedBits, altTagBits, XOR)
the same and ensure all shifts/ANDs use the same uint64_t mask and types to
avoid promotions/undefined shifts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/cpu/pred/btb/microtage.cc`:
- Around line 772-783: MicroTAGE::getTageIndex builds mask with (1ULL <<
tableIndexBits[t]) - 1 which is undefined when tableIndexBits[t] >= 64; add a
defensive check in getTageIndex to handle that case (or generally any
tableIndexBits[t] >= sizeof(mask)*8) by creating the mask without shifting past
the word size (e.g., if tableIndexBits[t] >= 64 set mask = ~0ULL else mask =
(1ULL << tableIndexBits[t]) - 1), ensure mask uses a 64-bit type and then keep
the existing pcShift/indexShift, pcBits and foldedBits logic and return pcBits ^
foldedBits.
- Around line 329-334: The loop uses an int index `s` compared to
`stagePreds.size()` (size_t); change the loop to use an unsigned/size type to
avoid signed/unsigned comparison—e.g. compute a size_t start =
static_cast<size_t>(std::max(0, getDelay())) (or otherwise safely cast
getDelay()) and iterate `for (size_t s = start; s < stagePreds.size(); ++s)` so
references like `stage_pred`, `stagePreds`, `lookupHelper(startPC,
stage_pred.btbEntries, stage_pred.condTakens)` remain unchanged.
- Around line 753-770: The mask calculation in MicroTAGE::getTageTag can UB when
tableTagBits[t] >= 64; change the mask logic to handle this case safely by using
a 64-bit mask variable (uint64_t) and computing mask = (tableTagBits[t] >= 64) ?
~0ULL : ((1ULL << tableTagBits[t]) - 1); keep the rest of the function logic
(pcBits, foldedBits, altTagBits, XOR) the same and ensure all shifts/ANDs use
the same uint64_t mask and types to avoid promotions/undefined shifts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 35373c05-840d-43f9-b265-2fa421d81802

📥 Commits

Reviewing files that changed from the base of the PR and between 318c57c and 9e6be62.

📒 Files selected for processing (7)
  • configs/example/idealkmhv3.py
  • configs/example/kmhv3.py
  • src/cpu/pred/BranchPredictor.py
  • src/cpu/pred/SConscript
  • src/cpu/pred/btb/decoupled_bpred.hh
  • src/cpu/pred/btb/microtage.cc
  • src/cpu/pred/btb/microtage.hh

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2203 -
This PR 2.2219 📈 +0.0016 (+0.07%)

✅ Difftest smoke test passed!

@XiangShanRobot
Copy link

[Generated by GEM5 Performance Robot]
commit: 9e6be62
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Master Diff(%)
Score 17.91 17.84 +0.36 🟢

Change-Id: I0c21d2e3b9eb505570f72bf17d0253c2ebed7b83
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/cpu/pred/btb/microtage.cc`:
- Around line 605-615: The canResolveUpdate() path currently clears
predBankValid on a detected bank conflict (in microtage.cc) which prematurely
consumes the bank reservation; change canResolveUpdate() to leave predBankValid
untouched and only return false on conflict, and move the predBankValid = false
clearing to the corresponding doResolveUpdate() path (same class) so the flag is
cleared only when the resolved-update pass actually proceeds; update references
to updateBank and lastPredBankId checks accordingly and keep the existing stats
increments and DPRINTF intact.
- Around line 884-904: The code promotes aheadindexFoldedHist.front() into
indexFoldedHist but returns early on !taken without removing the consumed
snapshot; fix by popping the consumed entry immediately after assigning
indexFoldedHist (i.e., after the aheadindexFoldedHist.front() -> indexFoldedHist
promotion call) so the queue advances even on not-taken paths; ensure any later
logic that pushes a new delayed snapshot (the taken path) still runs only on
taken, and reference aheadindexFoldedHist, indexFoldedHist, and numPredictors
(and the doUpdateHist update path) when making the change.
- Around line 43-46: The code allows non-power-of-two numBanks which makes
bankIdWidth = ceilLog2(numBanks) produce a mask that can generate IDs >=
numBanks and index predAccessPerBank/updateAccessPerBank out of range; fix by
requiring numBanks to be a non-zero power of two in the microtage constructor
(and the other constructor/initialization sites referenced around the same
pattern), e.g. add a check/assert that numBanks > 0 && (numBanks & (numBanks -
1)) == 0, compute bankIdWidth as exact log2(numBanks) (not ceilLog2), and/or
replace masks with (numBanks - 1) if you choose to keep current width logic;
update getBankId(), and ensure all places that initialize predAccessPerBank and
updateAccessPerBank use the same validated numBanks logic.
- Around line 776-804: The mask computation in MicroTAGE::getTageTag and
MicroTAGE::getTageIndex uses (1ULL << tableTagBits[t]) - 1 and (1ULL <<
tableIndexBits[t]) - 1 which invoke undefined behavior if the bit count equals
the width of Addr; change both mask constructions to special-case full-width: if
tableTagBits[t] (or tableIndexBits[t]) == (sizeof(Addr)*8) then set mask =
~Addr(0) else set mask = (Addr(1) << bits) - 1. Update the mask logic in
getTageTag (for tableTagBits[t]) and in getTageIndex (for tableIndexBits[t])
accordingly, keeping the rest of each function unchanged.

In `@src/cpu/pred/btb/microtage.hh`:
- Around line 279-333: TageStats's Scalar members are left uninitialized in
UNIT_TEST builds (Scalar is uint64_t), causing UB when incremented; fix by
zero-initializing those fields in the UNIT_TEST branch—either add in-class
initializers (e.g., "Scalar updateProviderNa = 0;" for each Scalar like
predNoHitUseBim, updateUseAlt, updateProviderNa, updateAllocFailure,
updateBankConflict, etc.) or add a default TageStats() constructor in that
branch that sets all Scalar members to 0 (and leaves non-UNIT_TEST constructor
untouched); update the UNIT_TEST struct definition (TageStats) to ensure every
Scalar is explicitly initialized.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 730c628e-d0f6-49d4-8c79-b6cb57d58336

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6be62 and 8c18550.

📒 Files selected for processing (2)
  • src/cpu/pred/btb/microtage.cc
  • src/cpu/pred/btb/microtage.hh

Comment on lines +43 to +46
numBanks(numBanks),
bankIdWidth(ceilLog2(numBanks)),
bankBaseShift(instShiftAmt),
indexShift(bankBaseShift + ceilLog2(numBanks)),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reject non-power-of-two numBanks.

bankIdWidth = ceilLog2(numBanks) combined with the bitmask in getBankId() generates IDs in [0, 2^width - 1], not [0, numBanks - 1]. For example, numBanks = 3 gives bankIdWidth = 2, so getBankId() can return 3, but predAccessPerBank / updateAccessPerBank are only sized to 3 elements. Please require numBanks to be a non-zero power of two, or switch the mapping to something that cannot index past the allocated bank vectors.

Also applies to: 75-78, 856-861

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 43 - 46, The code allows
non-power-of-two numBanks which makes bankIdWidth = ceilLog2(numBanks) produce a
mask that can generate IDs >= numBanks and index
predAccessPerBank/updateAccessPerBank out of range; fix by requiring numBanks to
be a non-zero power of two in the microtage constructor (and the other
constructor/initialization sites referenced around the same pattern), e.g. add a
check/assert that numBanks > 0 && (numBanks & (numBanks - 1)) == 0, compute
bankIdWidth as exact log2(numBanks) (not ceilLog2), and/or replace masks with
(numBanks - 1) if you choose to keep current width logic; update getBankId(),
and ensure all places that initialize predAccessPerBank and updateAccessPerBank
use the same validated numBanks logic.

Comment on lines +605 to +615
if (enableBankConflict && predBankValid && updateBank == lastPredBankId) {
tageStats.updateBankConflict++;
tageStats.updateDeferredDueToConflict++;
#ifndef UNIT_TEST
tageStats.updateBankConflictPerBank[updateBank]++;
#endif
DPRINTF(UTAGE, "Bank conflict detected: update bank %u conflicts with prediction bank %u, "
"deferring this update (will retry after blocking prediction)\n",
updateBank, lastPredBankId);
predBankValid = false;
return false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Keep canResolveUpdate() side-effect free.

src/cpu/pred/btb/decoupled_bpred.cc:536-553 uses this as the phase-1 probe, so clearing predBankValid here consumes the bank reservation even when the resolved-update pass aborts before doResolveUpdate(). The sibling implementation in src/cpu/pred/btb/btb_tage.cc:639-674 only clears that flag in doResolveUpdate(), which is the safe behavior here too.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 605 - 615, The canResolveUpdate()
path currently clears predBankValid on a detected bank conflict (in
microtage.cc) which prematurely consumes the bank reservation; change
canResolveUpdate() to leave predBankValid untouched and only return false on
conflict, and move the predBankValid = false clearing to the corresponding
doResolveUpdate() path (same class) so the flag is cleared only when the
resolved-update pass actually proceeds; update references to updateBank and
lastPredBankId checks accordingly and keep the existing stats increments and
DPRINTF intact.

Comment on lines +776 to +804
MicroTAGE::getTageTag(Addr pc, int t, uint64_t foldedHist, uint64_t altFoldedHist, Addr position)
{
// Create mask for tableTagBits[t] to limit result size
Addr mask = (1ULL << tableTagBits[t]) - 1;

// Extract lower bits of PC directly (remove instruction alignment bits)
Addr pcBits = (pc >> bankBaseShift) & mask;

// Extract and prepare folded history bits
Addr foldedBits = foldedHist & mask;

// Extract alt tag bits and shift left by 1
Addr altTagBits = (altFoldedHist << 1) & mask;

// XOR all components together, including position (like RTL)
return pcBits ^ foldedBits ^ position ^ altTagBits;
}

Addr
MicroTAGE::getTageIndex(Addr pc, int t, uint64_t foldedHist)
{
// Create mask for tableIndexBits[t] to limit result size
Addr mask = (1ULL << tableIndexBits[t]) - 1;

const unsigned pcShift = enableBankConflict ? indexShift : bankBaseShift;
Addr pcBits = (pc >> pcShift) & mask;
Addr foldedBits = foldedHist & mask;

return pcBits ^ foldedBits;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the file
head -20 src/cpu/pred/btb/microtage.cc

Repository: OpenXiangShan/GEM5

Length of output: 425


🏁 Script executed:

# Check the specific functions mentioned in the review
sed -n '776,804p' src/cpu/pred/btb/microtage.cc

Repository: OpenXiangShan/GEM5

Length of output: 1083


🏁 Script executed:

# Search for tableTagBits and tableIndexBits member variable declarations
rg 'tableTagBits|tableIndexBits' src/cpu/pred/btb/

Repository: OpenXiangShan/GEM5

Length of output: 6403


🏁 Script executed:

# Look for the Addr typedef
rg 'typedef.*Addr|using Addr' src/cpu/pred/btb/

Repository: OpenXiangShan/GEM5

Length of output: 44


🏁 Script executed:

# Find the Addr typedef definition
rg 'typedef.*Addr|using.*Addr' src/base/ | head -20

Repository: OpenXiangShan/GEM5

Length of output: 500


🏁 Script executed:

# Look for parameter definitions and any bounds/assertions
grep -n "TTagBitSizes\|tableSizes" src/cpu/pred/btb/microtage.hh src/cpu/pred/btb/microtage.cc | head -20

Repository: OpenXiangShan/GEM5

Length of output: 681


🏁 Script executed:

# Check what ceilLog2 returns and its constraints
rg -A 5 'ceilLog2' src/base/intmath.hh | head -30

Repository: OpenXiangShan/GEM5

Length of output: 138


🏁 Script executed:

# Look for any assertions or checks on the bit values
rg -B 3 -A 3 'tableTagBits\[|tableIndexBits\[' src/cpu/pred/btb/microtage.cc | grep -E 'assert|if.*>|if.*<' | head -20

Repository: OpenXiangShan/GEM5

Length of output: 169


🏁 Script executed:

# Check the parameter definitions for TTagBitSizes
rg -B 5 -A 5 "TTagBitSizes" src/cpu/pred/btb/microtage.hh

Repository: OpenXiangShan/GEM5

Length of output: 44


🏁 Script executed:

# Look at the full initialization and parameter structure
sed -n '50,110p' src/cpu/pred/btb/microtage.cc

Repository: OpenXiangShan/GEM5

Length of output: 2203


🏁 Script executed:

# Check tableSizes range and any constraints
rg -B 2 -A 2 "tableSizes\[i\]" src/cpu/pred/btb/microtage.cc | head -30

Repository: OpenXiangShan/GEM5

Length of output: 417


🏁 Script executed:

# Look for any parameter validation or bounds
rg "invalid|check|validate|bounds" src/cpu/pred/btb/microtage.hh src/cpu/pred/btb/microtage.cc -i

Repository: OpenXiangShan/GEM5

Length of output: 2505


🏁 Script executed:

# Check for the full ceilLog2 implementation to understand its maximum return value
cat src/base/intmath.hh | grep -A 20 "ceilLog2"

Repository: OpenXiangShan/GEM5

Length of output: 443


🏁 Script executed:

# Look for any parameter size limits
grep -r "TTagBitSizes" src/cpu/pred/btb/*.hh

Repository: OpenXiangShan/GEM5

Length of output: 44


🏁 Script executed:

# Check if there are sim parameters or config files that might limit values
find src -name "*.py" | xargs grep -l "TTagBitSizes\|tableTagBits" 2>/dev/null | head -5

Repository: OpenXiangShan/GEM5

Length of output: 93


🏁 Script executed:

# Check the Python parameter file for constraints
grep -A 10 -B 5 "TTagBitSizes\|tableTagBits" src/cpu/pred/BranchPredictor.py

Repository: OpenXiangShan/GEM5

Length of output: 6577


🏁 Script executed:

# Look for the microtage params in particular
grep -r "microtage\|MicroTAGE" src/cpu/pred/*.py 2>/dev/null | head -10

Repository: OpenXiangShan/GEM5

Length of output: 390


🏁 Script executed:

# Check what the maximum value tableIndexBits could be
# If tableSizes can be up to 2^63, then tableIndexBits would be 63
# Check if there's any constraint on tableSizes
grep -B 5 -A 5 "tableSizes" src/cpu/pred/btb/microtage.py 2>/dev/null || echo "No Python file found"

Repository: OpenXiangShan/GEM5

Length of output: 82


🏁 Script executed:

# Let's check what happens with a 64-bit shift on a 64-bit type
python3 << 'EOF'
# Simulate the issue
# In C++, 1ULL << 64 is undefined behavior when Addr is uint64_t
# Let's check the bounds
addr_width = 64  # bits

# Maximum value of tableTagBits/tableIndexBits that would be safe
safe_max = addr_width - 1

print(f"Addr width: {addr_width} bits")
print(f"Safe maximum for tableTagBits/tableIndexBits: {safe_max}")
print(f"If tableTagBits[t] = {addr_width}, then 1ULL << {addr_width} is undefined behavior")
print(f"This is a valid concern IF tableTagBits/tableIndexBits can reach 64")
EOF

Repository: OpenXiangShan/GEM5

Length of output: 261


🏁 Script executed:

# Check if tableTagBits can be set to 64 through parameters
# Look at default values and parameter bounds
sed -n '1,100p' src/cpu/pred/btb/microtage.hh | grep -A 20 "params\|Params"

Repository: OpenXiangShan/GEM5

Length of output: 1224


Guard against full-width shift in getTageTag() and getTageIndex().

If tableTagBits[t] or tableIndexBits[t] ever equals 64 (the width of Addr), then 1ULL << 64 is undefined behavior in C++. Although current configurations safely use values up to 15 bits, the code lacks defensive protection. Special-case the full-width path using ~Addr(0) instead of always shifting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 776 - 804, The mask computation
in MicroTAGE::getTageTag and MicroTAGE::getTageIndex uses (1ULL <<
tableTagBits[t]) - 1 and (1ULL << tableIndexBits[t]) - 1 which invoke undefined
behavior if the bit count equals the width of Addr; change both mask
constructions to special-case full-width: if tableTagBits[t] (or
tableIndexBits[t]) == (sizeof(Addr)*8) then set mask = ~Addr(0) else set mask =
(Addr(1) << bits) - 1. Update the mask logic in getTageTag (for tableTagBits[t])
and in getTageIndex (for tableIndexBits[t]) accordingly, keeping the rest of
each function unchanged.

Comment on lines +884 to +904
if (!aheadindexFoldedHist.empty()) {
indexFoldedHist = aheadindexFoldedHist.front();
}

if (!taken) {
if (debug::TAGEHistory && !aheadindexFoldedHist.empty()) {
bool mismatch = false;
for (int t = 0; t < numPredictors; t++) {
if (indexFoldedHist[t].get() != aheadindexFoldedHist.front()[t].get()) {
mismatch = true;
break;
}
}
if (mismatch) {
DPRINTF(TAGEHistory,
"doUpdateHist: not taken, indexFoldedHist stale vs ahead queue\n");
}
}
DPRINTF(TAGEHistory, "not updating folded history, since FB not taken\n");
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Consume the delayed index snapshot before the not-taken early return.

This block promotes aheadindexFoldedHist.front() into indexFoldedHist, but when taken == false it returns without removing that queued value. After the first not-taken update, the queue stays permanently “pending”, so later snapshots and recovery paths see a duplicate next-cycle state. Pop the consumed entry first, then only push a new delayed snapshot on the taken path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.cc` around lines 884 - 904, The code promotes
aheadindexFoldedHist.front() into indexFoldedHist but returns early on !taken
without removing the consumed snapshot; fix by popping the consumed entry
immediately after assigning indexFoldedHist (i.e., after the
aheadindexFoldedHist.front() -> indexFoldedHist promotion call) so the queue
advances even on not-taken paths; ensure any later logic that pushes a new
delayed snapshot (the taken path) still runs only on taken, and reference
aheadindexFoldedHist, indexFoldedHist, and numPredictors (and the doUpdateHist
update path) when making the change.

Comment on lines +279 to +333
#ifdef UNIT_TEST
struct TageStats
{
#else
struct TageStats : public statistics::Group
{
#endif
Scalar predNoHitUseBim;
Scalar predUseAlt;
Scalar updateNoHitUseBim;
Scalar updateUseAlt;
Scalar updateUseAltCorrect;
Scalar updateUseAltWrong;
Scalar updateAltDiffers;
Scalar updateUseAltOnNaUpdated;
Scalar updateProviderNa;
Scalar updateUseAltOnNaCorrect;
Scalar updateUseAltOnNaWrong;
Scalar updateAllocFailure;
Scalar updateAllocFailureNoValidTable;
Scalar updateAllocSuccess;
Scalar updateMispred;
Scalar updateResetU;

Scalar updateUtageHit;
Scalar updateUtageHitWrong;

// Bank conflict statistics
Scalar updateBankConflict; // Number of bank conflicts detected
Scalar updateDeferredDueToConflict; // Number of updates deferred due to bank conflict (retried later)

#ifndef UNIT_TEST
// Fine-grained per-bank statistics
statistics::Vector updateBankConflictPerBank; // Conflicts per bank
statistics::Vector updateAccessPerBank; // Update accesses per bank
statistics::Vector predAccessPerBank; // Prediction accesses per bank

statistics::Distribution predTableHits;
statistics::Distribution updateTableHits;

statistics::Vector updateTableMispreds;
#endif

Scalar condPredwrong;
Scalar condMissTakens;
Scalar condCorrect;
Scalar condMissNoTakens;
Scalar predHit;
Scalar predMiss;

#ifndef UNIT_TEST
TageStats(statistics::Group* parent, int numPredictors, int numBanks);
#endif
void updateStatsWithTagePrediction(const TagePrediction &pred, bool when_pred);
} ;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the Scalar typedef definition in the microtage header
rg "typedef.*Scalar|using.*Scalar|#define.*Scalar" src/cpu/pred/btb/microtage.hh -A 2 -B 2

Repository: OpenXiangShan/GEM5

Length of output: 161


🏁 Script executed:

# Check if there's a Scalar definition elsewhere
rg "typedef.*Scalar|using.*Scalar" src/cpu/pred/ -A 1

Repository: OpenXiangShan/GEM5

Length of output: 1418


🏁 Script executed:

# Examine the full context around TageStats in the header file
sed -n '270,340p' src/cpu/pred/btb/microtage.hh

Repository: OpenXiangShan/GEM5

Length of output: 2150


🏁 Script executed:

# Check the implementation file for how TageStats members are accessed
rg "tageStats\." src/cpu/pred/btb/microtage.cc | head -20

Repository: OpenXiangShan/GEM5

Length of output: 1002


Zero-initialize TageStats scalar members in UNIT_TEST builds.

In the UNIT_TEST branch, Scalar is uint64_t and TageStats has no user-defined constructor or in-class initializers. This means all scalar members are default-initialized, leaving them indeterminate. Any subsequent increment (e.g., tageStats.updateProviderNa++) is undefined behavior. Add in-class initializers (= 0) or a default constructor to zero these fields.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/btb/microtage.hh` around lines 279 - 333, TageStats's Scalar
members are left uninitialized in UNIT_TEST builds (Scalar is uint64_t), causing
UB when incremented; fix by zero-initializing those fields in the UNIT_TEST
branch—either add in-class initializers (e.g., "Scalar updateProviderNa = 0;"
for each Scalar like predNoHitUseBim, updateUseAlt, updateProviderNa,
updateAllocFailure, updateBankConflict, etc.) or add a default TageStats()
constructor in that branch that sets all Scalar members to 0 (and leaves
non-UNIT_TEST constructor untouched); update the UNIT_TEST struct definition
(TageStats) to ensure every Scalar is explicitly initialized.

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2203 -
This PR 2.2125 📉 -0.0077 (-0.35%)

✅ Difftest smoke test passed!

@XiangShanRobot
Copy link

[Generated by GEM5 Performance Robot]
commit: 8c18550
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Master Diff(%)
Score 17.90 17.84 +0.33 🟢

[Generated by GEM5 Performance Robot]
commit: 8c18550
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Previous Commit Diff(%)
Score 17.90 17.91 -0.03 🔴

Change-Id: I9153ff6ead4c95fe01ae64aedc7942117b50e7d4
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/cpu/pred/BranchPredictor.py (1)

1063-1089: Remove or document unused Python parameters in the MicroTAGE class definition.

The following parameters are declared but not consumed by the C++ MicroTAGE constructor:

  • enableSC
  • numTablesToAlloc
  • baseTableSize
  • useAltOnNaSize
  • useAltOnNaWidth (only appears in a commented-out line in the C++ implementation)

Either remove these parameters or add clarifying comments if they are intentional placeholders for future functionality.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/BranchPredictor.py` around lines 1063 - 1089, The MicroTAGE
Param fields enableSC, numTablesToAlloc, baseTableSize, useAltOnNaSize, and
useAltOnNaWidth are declared in the MicroTAGE class but not consumed by the C++
MicroTAGE constructor; either remove these Param declarations from the MicroTAGE
Python class or clearly document why they are intentionally unused (e.g., add
inline comments in the MicroTAGE class docstring or next to each Param noting
“placeholder / not yet used by C++ constructor”), and if they are intended to
map to future/alternative C++ fields update the C++ constructor/headers to
accept them; edit the MicroTAGE class definition to remove or annotate the
specific Param symbols (enableSC, numTablesToAlloc, baseTableSize,
useAltOnNaSize, useAltOnNaWidth) so the intent is clear and linter/maintainers
aren’t left with unused parameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/cpu/pred/BranchPredictor.py`:
- Around line 1063-1089: The MicroTAGE Param fields enableSC, numTablesToAlloc,
baseTableSize, useAltOnNaSize, and useAltOnNaWidth are declared in the MicroTAGE
class but not consumed by the C++ MicroTAGE constructor; either remove these
Param declarations from the MicroTAGE Python class or clearly document why they
are intentionally unused (e.g., add inline comments in the MicroTAGE class
docstring or next to each Param noting “placeholder / not yet used by C++
constructor”), and if they are intended to map to future/alternative C++ fields
update the C++ constructor/headers to accept them; edit the MicroTAGE class
definition to remove or annotate the specific Param symbols (enableSC,
numTablesToAlloc, baseTableSize, useAltOnNaSize, useAltOnNaWidth) so the intent
is clear and linter/maintainers aren’t left with unused parameters.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d6c34ba-ba05-45fc-9170-9ec74a0798aa

📥 Commits

Reviewing files that changed from the base of the PR and between 8c18550 and 8d5b2a9.

📒 Files selected for processing (1)
  • src/cpu/pred/BranchPredictor.py

@github-actions
Copy link

github-actions bot commented Mar 9, 2026

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2354 -
This PR 2.2541 📈 +0.0186 (+0.83%)

✅ Difftest smoke test passed!

@XiangShanRobot
Copy link

[Generated by GEM5 Performance Robot]
commit: 8d5b2a9
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Master Diff(%)
Score 17.91 18.13 -1.21 🔴

[Generated by GEM5 Performance Robot]
commit: 8d5b2a9
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Previous Commit Diff(%)
Score 17.91 17.90 +0.03 🟢

Change-Id: I265e792cce049f185d16d61db5c598bfa3621f9b
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/cpu/pred/BranchPredictor.py (1)

1074-1089: Consider aligning style with existing classes.

A few minor style inconsistencies compared to BTBTAGE and other similar classes in this file:

  1. Parameter definitions: blockSize and numDelay use Param.Unsigned(...) while existing classes use direct value assignment (e.g., blockSize = 32, numDelay = 2).

  2. List spacing: VectorParam lists like [15,15,16,16] lack spaces, while existing code uses [4, 9, 17, 29, ...].

  3. String spacing: Missing space after value before description string (e.g., Param.Bool(True,"Enable...")).

♻️ Suggested style alignment
-    tableSizes = VectorParam.Unsigned([512] * 4,"the TAGE T0~Tn length")
-    TTagBitSizes = VectorParam.Unsigned([15,15,16,16],"the T0~Tn entry's tag bit size")
-    TTagPcShifts = VectorParam.Unsigned([1] * 4 ,"when the T0~Tn entry's tag generating, PC right shift")
-    blockSize = Param.Unsigned(32,"tage index function uses 32B aligned block address")
+    tableSizes = VectorParam.Unsigned([512] * 4, "the TAGE T0~Tn length")
+    TTagBitSizes = VectorParam.Unsigned([15, 15, 16, 16], "the T0~Tn entry's tag bit size")
+    TTagPcShifts = VectorParam.Unsigned([1] * 4, "when the T0~Tn entry's tag generating, PC right shift")
+    blockSize = 32  # tage index function uses 32B aligned block address
-    numDelay = Param.Unsigned(0,"Prediction latency in cycles")
+    numDelay = 0
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/BranchPredictor.py` around lines 1074 - 1089, The parameter
block in BranchPredictor.py is stylistically inconsistent with other classes
like BTBTAGE: change Param.Unsigned usage for blockSize and numDelay to direct
literal assignments (e.g., blockSize = 32, numDelay = 2), add spaces in
VectorParam lists (e.g., [15, 15, 16, 16]), and ensure there is a space after
the comma before the descriptive string in Param/VectorParam constructors (e.g.,
Param.Bool(False, "Enable...")) so formatting matches existing class
conventions; update the declarations for tableSizes, TTagBitSizes, TTagPcShifts,
histLengths, and any Param.* usages in this diff accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/cpu/pred/BranchPredictor.py`:
- Around line 1074-1089: The parameter block in BranchPredictor.py is
stylistically inconsistent with other classes like BTBTAGE: change
Param.Unsigned usage for blockSize and numDelay to direct literal assignments
(e.g., blockSize = 32, numDelay = 2), add spaces in VectorParam lists (e.g.,
[15, 15, 16, 16]), and ensure there is a space after the comma before the
descriptive string in Param/VectorParam constructors (e.g., Param.Bool(False,
"Enable...")) so formatting matches existing class conventions; update the
declarations for tableSizes, TTagBitSizes, TTagPcShifts, histLengths, and any
Param.* usages in this diff accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d0991134-234e-4d45-b75c-8d29ccb4f746

📥 Commits

Reviewing files that changed from the base of the PR and between 8d5b2a9 and d6de129.

📒 Files selected for processing (1)
  • src/cpu/pred/BranchPredictor.py

@github-actions
Copy link

github-actions bot commented Mar 9, 2026

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2354 -
This PR 2.2490 📈 +0.0135 (+0.60%)

✅ Difftest smoke test passed!

@XiangShanRobot
Copy link

[Generated by GEM5 Performance Robot]
commit: d6de129
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Master Diff(%)
Score 17.91 18.13 -1.20 🔴

[Generated by GEM5 Performance Robot]
commit: d6de129
workflow: gem5 Align BTB Performance Test(0.3c)

Align BTB Performance

Overall Score

PR Previous Commit Diff(%)
Score 17.91 17.91 +0.01 🟢

Change-Id: I8bbae34359507a81ce43977afcbd17c37d0526a1
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/cpu/pred/BranchPredictor.py`:
- Around line 1072-1079: The vector params tableSizes, TTagBitSizes,
TTagPcShifts, and histLengths currently have only one element while
numPredictors is 4, which will trigger constructor assertions; update each
VectorParam (tableSizes, TTagBitSizes, TTagPcShifts, histLengths) to contain 4
entries to match numPredictors (e.g., expand values from a single-element list
to four appropriate entries), and for histLengths use a geometrically increasing
sequence suitable for MicroTAGE (e.g., multiples of 4) so sizes are consistent
with the BTBTAGE-style definitions and avoid runtime failures.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fccec1df-f838-458d-b251-4956780fc527

📥 Commits

Reviewing files that changed from the base of the PR and between d6de129 and b89e3d1.

📒 Files selected for processing (1)
  • src/cpu/pred/BranchPredictor.py

Comment on lines +1072 to +1079
# Keep vector parameters consistent with numPredictors to avoid constructor asserts.
numPredictors = Param.Unsigned(4, "Number of TAGE predictors")
tableSizes = VectorParam.Unsigned([512],"the TAGE T0~Tn length")
TTagBitSizes = VectorParam.Unsigned([16],"the T0~Tn entry's tag bit size")
TTagPcShifts = VectorParam.Unsigned([1] ,"when the T0~Tn entry's tag generating, PC right shift")
blockSize = Param.Unsigned(32,"tage index function uses 32B aligned block address")

histLengths = [16]
numDelay = 0
histLengths = VectorParam.Unsigned([16] ,"the BTB TAGE T0~Tn history length")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for MicroTAGE constructor and check how it uses these vector parameters

# Find the MicroTAGE implementation
fd -e cc -e cpp -e hh -e hpp microtage --exec cat {} \; 2>/dev/null | head -200

# Also check BTBTAGE for comparison on how vectors are used
rg -n -A 10 'tableSizes|TTagBitSizes|histLengths' --type cpp -g '*btb_tage*'

Repository: OpenXiangShan/GEM5

Length of output: 13355


🏁 Script executed:

# Check the MicroTAGE class definition in BranchPredictor.py
sed -n '1063,1089p' src/cpu/pred/BranchPredictor.py

Repository: OpenXiangShan/GEM5

Length of output: 1827


Vector parameter sizes do not match numPredictors—fix required to avoid runtime assertion failure.

The C++ constructor checks that all vector parameters have size >= numPredictors. Currently, numPredictors = 4 but all vector parameters (tableSizes, TTagBitSizes, TTagPcShifts, histLengths) have only 1 element. This will trigger assertion failures at lines 109, 118, 120, and 123 of src/cpu/pred/btb/btb_tage.cc.

Each vector must be expanded to have 4 elements. For reference, BTBTAGE (lines 1043-1052) correctly defines all vectors with 8 elements matching its numPredictors = 8.

Proposed fix
     # Keep vector parameters consistent with numPredictors to avoid constructor asserts.
     numPredictors = Param.Unsigned(4, "Number of TAGE predictors")
-    tableSizes = VectorParam.Unsigned([512],"the TAGE T0~Tn length")
-    TTagBitSizes = VectorParam.Unsigned([16],"the T0~Tn entry's tag bit size")
-    TTagPcShifts = VectorParam.Unsigned([1] ,"when the T0~Tn entry's tag generating, PC right shift")
+    tableSizes = VectorParam.Unsigned([512]*4,"the TAGE T0~Tn length")
+    TTagBitSizes = VectorParam.Unsigned([16]*4,"the T0~Tn entry's tag bit size")
+    TTagPcShifts = VectorParam.Unsigned([1]*4,"when the T0~Tn entry's tag generating, PC right shift")
     blockSize = Param.Unsigned(32,"tage index function uses 32B aligned block address")

-    histLengths = VectorParam.Unsigned([16]  ,"the BTB TAGE T0~Tn history length")
+    histLengths = VectorParam.Unsigned([4, 8, 13, 16],"the BTB TAGE T0~Tn history length")

The histLengths values are illustrative. Use history lengths appropriate for the MicroTAGE design (typically geometrically increasing, e.g., multiples of 4).

🧰 Tools
🪛 Ruff (0.15.5)

[error] 1073-1073: Param may be undefined, or defined from star imports

(F405)


[error] 1074-1074: VectorParam may be undefined, or defined from star imports

(F405)


[error] 1075-1075: VectorParam may be undefined, or defined from star imports

(F405)


[error] 1076-1076: VectorParam may be undefined, or defined from star imports

(F405)


[error] 1077-1077: Param may be undefined, or defined from star imports

(F405)


[error] 1079-1079: VectorParam may be undefined, or defined from star imports

(F405)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cpu/pred/BranchPredictor.py` around lines 1072 - 1079, The vector params
tableSizes, TTagBitSizes, TTagPcShifts, and histLengths currently have only one
element while numPredictors is 4, which will trigger constructor assertions;
update each VectorParam (tableSizes, TTagBitSizes, TTagPcShifts, histLengths) to
contain 4 entries to match numPredictors (e.g., expand values from a
single-element list to four appropriate entries), and for histLengths use a
geometrically increasing sequence suitable for MicroTAGE (e.g., multiples of 4)
so sizes are consistent with the BTBTAGE-style definitions and avoid runtime
failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants