riscv-boom's bp

预测器的组合逻辑级联

代码实现

所有预测器的连接(config-mixins.scala:603-609):

1
2
3
4
5
6
7
8
9
10
11
12
// 初始输入(全0预测)
val resp_in = (0.U).asTypeOf(new BranchPredictionBankResponse)

// 组合逻辑链
ubtb.io.resp_in(0) := resp_in
bim.io.resp_in(0) := ubtb.io.resp // 组合逻辑
btb.io.resp_in(0) := bim.io.resp // 组合逻辑
tage.io.resp_in(0) := btb.io.resp // 组合逻辑
loop.io.resp_in(0) := tage.io.resp // 组合逻辑

// 最终输出
final_resp = loop.io.resp

每个预测器的覆盖策略

预测器 覆盖字段 条件
uBTB predicted_pc, is_br, is_jal, taken 标签匹配
BIM taken 总是(基于PC)
BTB predicted_pc 标签匹配且置信度高
TAGE taken provider命中且置信度高
Loop taken 检测到循环边界且conf=7

组合逻辑路径

在F1阶段(最长路径):

1
2
3
4
5
6
7
8
9
10
11
resp_in (0ns)
uBTB读SRAM (SRAM access)
uBTB标签比较 + Mux选择 (~0.5ns)
→ BIM读SRAM (SRAM access)
→ BIM计数器比较 + Mux选择 (~0.3ns)
→ BTB读SRAM (SRAM access)
→ BTB标签比较 + Mux选择 (~0.5ns)
→ TAGE读所有表 (parallel SRAM access)
→ TAGE找provider + 计算预测 (~1ns)
→ Loop表查找 + 边界检测 (~0.5ns)
final output (~总共3-4ns + SRAM延迟)

关键路径优化

  • SRAM访问在F0就开始(投机性)
  • 某些预测器可以配置在不同阶段输出(如BIM的slow模式)
  • 使用bypass逻辑减少RAW hazard

完整预测示例

假设我们要预测以下代码:

1
2
3
4
5
6
int sum = 0;
for (int i = 0; i < 100; i++) { // 分支A: PC=0x1000
if (i % 2 == 0) { // 分支B: PC=0x1004
sum += i;
}
}

第一次执行

分支A (PC=0x1000), i=0

阶段 预测器 动作 结果
F1 uBTB Miss(首次) 无预测
F1 BIM 读取,初始值=2(弱taken) Taken
F2 BTB Miss 保持BIM结果
F3 TAGE T0命中,ctr=4 Taken
F3 Loop Miss 保持TAGE结果
最终 - - Taken

分支B (PC=0x1004), i=0, i%2==0

阶段 预测器 动作 结果
F1 uBTB Miss 无预测
F1 BIM 初始值=2 Taken
F3 TAGE T1命中(hist=2bit) Taken
最终 - - Taken

第50次执行

分支A (PC=0x1000), i=49

阶段 预测器 动作 结果
F1 uBTB 命中,ctr=3(饱和) Taken
F1 BIM ctr=3 Taken
F3 TAGE T5命中(64bit hist),ctr=7 Taken
F3 Loop 命中,s_cnt=49, p_cnt=100, conf=5 保持Taken
最终 - - Taken

第100次执行(循环边界)

分支A (PC=0x1000), i=99

阶段 预测器 动作 结果
F1 uBTB 命中,ctr=3 Taken
F1 BIM ctr=3 Taken
F3 TAGE T5命中,ctr=7(强taken) Taken
F3 Loop 命中,s_cnt=99, p_cnt=100, conf=7 反转!Not Taken
最终 - - Not Taken

没有Loop预测器,TAGE会预测Taken → 错误

第101次执行(循环结束后)

下一条指令 (PC=0x1008)

分支A不再执行,成功退出循环。


总结

关键要点

  1. 4级流水 vs 5个预测器

    • 4级是时间维度(F0→F1→F2→F3)
    • 5个预测器在每级内部通过组合逻辑级联
  2. 级联而非投票

    • 每个预测器可以选择保持或覆盖前级预测
    • 后级预测器(TAGE)通常更准确
  3. 分工明确

    • uBTB: 快速但不准
    • BIM: 简单基础预测
    • BTB: 准确目标地址
    • TAGE: 高精度方向预测
    • Loop: 处理特殊模式

BOOM v4 分支预测器协作架构详解

1. 整体层次结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Frontend (前端) │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ BranchPredictor (顶层) │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ComposedBranchPredictorBank (组合预测器) │ │ │
│ │ │ │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ 预测器级联链 │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ │
│ │ │ │ │ uBTB │───►│ BIM │───►│ BTB │───►│ TAGE │───►│ Loop │───► 最终输出 │ │ │ │
│ │ │ │ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ 基础预测 ──────────────────────────────────────────────────► 精细预测 │ │ │ │
│ │ │ │ (快速) (准确) │ │ │ │
│ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ LocalBranchPredictorBank (本地历史) │ │ │
│ │ └───────────────────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────┘

2. 预测器级联连接 (核心!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 预测器级联连接详解 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

来自 config-mixins.scala:603-609 的核心代码:

ubtb.io.resp_in(0) := resp_in // uBTB 接收空输入
bim.io.resp_in(0) := ubtb.io.resp // BIM 接收 uBTB 输出
btb.io.resp_in(0) := bim.io.resp // BTB 接收 BIM 输出
tage.io.resp_in(0) := btb.io.resp // TAGE 接收 BTB 输出
loop.io.resp_in(0) := tage.io.resp // Loop 接收 TAGE 输出

级联图示:

resp_in (全0初始值)


┌─────────────────────────────────────────────────────────────────────────────────────┐
│ μBTB (Micro BTB) │
│ │
│ 功能: 超小型全相联 BTB,提供最快的目标地址预测 │
│ 输入: resp_in (空) │
│ 输出: predicted_pc, is_br, is_jal │
│ 特点: F1 阶段就能输出 (最快) │
└─────────────────────────────────────────────────────────────┬───────────────────────┘

│ resp

┌─────────────────────────────────────────────────────────────────────────────────────┐
│ BIM (Bimodal Predictor) │
│ │
│ 功能: 2-bit 饱和计数器,提供基础方向预测 │
│ 输入: uBTB 的 resp (透传 predicted_pc, is_br, is_jal) │
│ 输出: 覆盖/设置 taken 预测 │
│ 特点: 简单快速,适合大多数分支 │
└─────────────────────────────────────────────────────────────┬───────────────────────┘

│ resp

┌─────────────────────────────────────────────────────────────────────────────────────┐
│ BTB (Branch Target Buffer) │
│ │
│ 功能: 更大的组相联 BTB,提供更准确的目标地址 │
│ 输入: BIM 的 resp (继承 taken) │
│ 输出: 覆盖 predicted_pc, is_br, is_jal (如果命中) │
│ 特点: 支持更大范围的跳转目标 (EBTB) │
└─────────────────────────────────────────────────────────────┬───────────────────────┘

│ resp

┌─────────────────────────────────────────────────────────────────────────────────────┐
│ TAGE (Tagged Geometric) │
│ │
│ 功能: 多表历史预测器,基于全局历史提供高精度方向预测 │
│ 输入: BTB 的 resp (使用 taken 作为备选预测) │
│ 输出: 覆盖 taken (如果有表命中且置信度足够) │
│ 特点: 6 个不同历史长度的表,捕捉复杂分支模式 │
└─────────────────────────────────────────────────────────────┬───────────────────────┘

│ resp

┌─────────────────────────────────────────────────────────────────────────────────────┐
│ Loop (Loop Predictor) │
│ │
│ 功能: 专用循环预测器,预测循环退出 │
│ 输入: TAGE 的 resp │
│ 输出: 在检测到循环结束时翻转 taken │
│ 特点: 只有高置信度时才覆盖,保守但精确 │
└─────────────────────────────────────────────────────────────┬───────────────────────┘

│ resp (最终输出)

┌───────────────┐
│ Frontend 使用 │
└───────────────┘

3. 信号透传与覆盖机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ resp_in 透传与覆盖机制 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

每个预测器的默认行为 (来自 BranchPredictorBank 基类):

io.resp := io.resp_in(0) // 默认透传上游的预测结果

覆盖示例 (以 BTB 为例):

// 默认透传
io.resp.f1(w) := io.resp_in(0).f1(w)
io.resp.f2(w) := io.resp_in(0).f2(w)
io.resp.f3(w) := io.resp_in(0).f3(w)

// 当 BTB 命中时,覆盖特定字段
when (RegNext(s1_hits(w))) {
io.resp.f2(w).predicted_pc := RegNext(s1_resp(w)) // 覆盖目标地址
io.resp.f2(w).is_br := RegNext(s1_is_br(w)) // 覆盖类型
io.resp.f2(w).is_jal := RegNext(s1_is_jal(w))
when (RegNext(s1_is_jal(w))) {
io.resp.f2(w).taken := true.B // JAL 强制 taken
}
}


信号流动可视化:

BranchPrediction 结构:
┌────────────────────────────────────────────────────────────────────────────────────┐
│ taken │ is_br │ is_jal │ predicted_pc │
│ 是否跳转 │ 是否是分支 │ 是否是 JAL │ 目标地址 │
└────────────────────────────────────────────────────────────────────────────────────┘

各预测器的贡献:

字段 uBTB BIM BTB TAGE Loop
────
taken - 设置 (JAL时) 覆盖 翻转(循环结束)
is_br 设置 透传 覆盖 透传 透传
is_jal 设置 透传 覆盖 透传 透传
predicted_pc 设置 透传 覆盖 透传 透传
────

"透传" = 保持上游的值不变
"设置" = 首次提供该值
"覆盖" = 用更准确的值替换
"翻转" = 取反

4. 流水线时序与多阶段输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 流水线时序 (F0 → F3) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

周期 F0 F1 F2 F3
(请求) (访问) (比较) (输出)
─────────────────

μBTB 索引计算 SRAM读取 ───────────► resp.f1 输出 (最快!)
────────► ────────►

BIM 索引计算 SRAM读取 数据返回 ───────────► resp.f2/f3 输出
────────► ────────► ────────►

BTB 索引计算 SRAM读取 标签比较 ───────────► resp.f2/f3 输出
────────► ────────► ────────►

TAGE 索引/标签 SRAM读取 Provider选择 预测输出 ──► resp.f3 输出
计算 ────────► ────────►

Loop ───────── 寄存器读取 标签比较 翻转决策 ──► resp.f3 输出
────────► ────────►

─────────────────

Frontend 使用:

F1 resp: μBTB 提供的快速预测 (可用于下一周期重定向)
F2 resp: BIM + BTB 的预测 (更准确)
F3 resp: TAGE + Loop 的最终预测 (最准确)

5. 更新路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 更新信号流 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

后端执行单元

│ 分支解析结果

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│ BranchPredictionUpdate │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────────────┐│
│ │ is_mispredict │ │ is_repair │ │ is_commit │ │ btb_mispredicts ││
│ │ _update │ │ _update │ │ _update │ │ ││
│ │ (投机误预测) │ │ (恢复更新) │ │ (提交更新) │ │ (BTB误预测) ││
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────────────────────┘│
│ │
│ ┌──────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ pc, br_mask, cfi_idx, cfi_taken, cfi_mispredicted, target, ghist, meta │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────┬────────────────────────────────────────────────────┘

┌────────────────────────────┼────────────────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ μBTB │ │ BIM │ ... │ Loop │
│ │ │ │ │ │
│ 更新条目 │ │ 更新 2-bit 计数器 │ │ 更新 s_cnt, conf │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘


更新类型说明:
────────────────
is_commit_update: 分支已提交,确定性更新 (TAGE, BIM 主要使用)
is_mispredict_update: 投机路径误预测,需要恢复状态 (Loop 使用)
is_repair_update: 修复推测状态 (Loop 用于恢复 s_cnt)
btb_mispredicts: BTB 预测错误的目标,需要清除条目

6. 元数据 (Meta) 传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Meta 数据流 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

预测时 (打包):

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ μBTB meta│ │ BIM meta │ │ BTB meta │ │TAGE meta │ │Loop meta │
│ (Xbits) │ │ (Ybits) │ │ (Zbits) │ │ (Wbits) │ │ (10bits) │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │ │
└──────────────┴──────────────┴──────────────┴──────────────┘

▼ 拼接
┌─────────────────────────────────────────┐
│ io.f3_meta (合并后) │
│ [Loop | TAGE | BTB | BIM | μBTB] │
└─────────────────────────────────────────┘

▼ 存入 FTQ (Fetch Target Queue)
┌─────────────────────────────────────────┐
│ FTQ Entry │
│ meta 字段保存预测元数据 │
└─────────────────────────────────────────┘

更新时 (解包):

┌─────────────────────────────────────────┐
│ update.bits.meta │
│ 来自 FTQ 的保存的元数据 │
└─────────────────────────────────────────┘

▼ 解包 (从右向左)
┌──────────────┬──────────────┬──────────────┬──────────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ μBTB │ │ BIM │ │ BTB │ │ TAGE │ │ Loop │
│ 接收自己 │ │ 接收自己 │ │ 接收自己 │ │ 接收自己 │ │ 接收自己 │
│ 的 meta │ │ 的 meta │ │ 的 meta │ │ 的 meta │ │ 的 meta │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘

composer.scala 中的解包代码:

var update_meta = io.update.bits.meta
for (c <- components.reverse) { // 反向遍历!
c.io.update.bits.meta := update_meta
update_meta = update_meta >> c.metaSz // 右移剥离
}

7. 各预测器职责分工

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 预测器职责分工表 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────┬────────────────────────────────────────────────────────────────────────────────────────┐
│ 预测器 │ 职责与特点 │
├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ │ ■ 提供: 最快的目标地址预测 │
│ μBTB │ ■ 时机: F1 阶段输出 (仅 1 周期延迟) │
│ (Micro BTB) │ ■ 容量: 很小 (全相联,约 16-32 条目) │
│ │ ■ 用途: 快速重定向,减少气泡 │
├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ │ ■ 提供: 基础方向预测 (taken/not-taken) │
│ BIM │ ■ 时机: F2/F3 阶段 │
│ (Bimodal) │ ■ 容量: 中等 (2048 条目) │
│ │ ■ 用途: 简单分支的快速预测,TAGE 的后备 │
├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ │ ■ 提供: 准确的目标地址预测 │
│ BTB │ ■ 时机: F2/F3 阶段 │
│ │ ■ 容量: 较大 (128 sets × 2 ways) │
│ │ ■ 用途: 替代 μBTB 的预测 (如果命中),支持远跳转 (EBTB) │
├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ │ ■ 提供: 高精度方向预测 │
│ TAGE │ ■ 时机: F3 阶段 │
│ │ ■ 容量: 6 个表,不同历史长度 (2/4/8/16/32/64) │
│ │ ■ 用途: 复杂分支模式识别,覆盖 BIM 预测 │
├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤
│ │ ■ 提供: 循环退出预测 │
│ Loop │ ■ 时机: F3 阶段 │
│ │ ■ 容量: 小 (16 条目 × bankWidth 列) │
│ │ ■ 用途: 翻转 TAGE 的预测 (当检测到循环即将结束) │
└──────────────┴────────────────────────────────────────────────────────────────────────────────────────┘

8. 完整信号流图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 完整信号流图 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────┐
│ Frontend (前端) │
│ │
│ PC, ghist ──────────────────┐ │
│ │ │
│ f3_fire (预测被使用) ────┐ │ │
│ │ │ │
└────────────────────────────┼──┼────┘
│ │
┌───────────────────────────────────────────────────────────┘ │
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ BranchPredictor │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ ComposedBranchPredictorBank │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 预测路径 │ │ │
│ │ │ │ │ │
│ │ │ f0_pc, f0_valid, f1_ghist, f3_fire │ │ │
│ │ │ │ │ │ │
│ │ │ ┌─────────────────────────────┼─────────────────────────────┐ │ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ │ ▼ ▼ ▼ ▼ ▼ │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ μBTB │ │ BIM │ │ BTB │ │ TAGE │ │ Loop │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ F1输出 │ │ F2输出 │ │ F2输出 │ │ F3输出 │ │ F3输出 │ │ │ │
│ │ │ │ target │ │ taken │ │ target │ │ taken │ │ taken │ │ │ │
│ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ │ │ resp_in │ resp_in │ resp_in │ resp_in │ │ │ │
│ │ │ └────────────►│─────────────►│─────────────►│────────────►│ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ resp │ │ │
│ │ │ │ │ │ ├───────────────────────────►│ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ ┌────────────────────┴──────────────┴──────────────┴─────────────┴─────────┐ │ │ │
│ │ │ │ meta 打包 │ │ │ │
│ │ │ │ metas = (metas << c.metaSz) | c.io.f3_meta │ │ │ │
│ │ │ └─────────────────────────────────────────────────────────────┬────────────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ▼ io.f3_meta │ │ │
│ │ └─────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 更新路径 │ │ │
│ │ │ │ │ │
│ │ │ update.bits.meta │ │ │
│ │ │ │ │ │ │
│ │ │ ┌──────────────┬─────────────────────┼─────────────────────┬──────────────┐ │ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ │ ▼ ▼ ▼ ▼ ▼ │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ Loop │ │ TAGE │ │ BTB │ │ BIM │ │ μBTB │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ meta解包│ │ meta解包 │ │ meta解包│ │ meta解包│ │ meta解包│ │ │ │
│ │ │ │ update │ │ update │ │ update │ │ update │ │ update │ │ │ │
│ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ◄──────────────────────────────── update_meta >>= c.metaSz ────────────────────────────── │ │ │
│ │ │ (反向遍历解包) │ │ │
│ │ └─────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ 输出: io.resp.f1/f2/f3 ──────────────────────────────────────────────────────────────────────────────────────►│
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
│ ▲
│ │
▼ │
┌───────────────┐ ┌───────────────┐
│ ICache │ │ 后端 │
│ 取指 │ │ 执行单元 │
└───────────────┘ │ (更新来源) │
└───────────────┘

9. takan 信号流动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ taken 字段的流动 │
└─────────────────────────────────────────────────────────────────────────────────────────┘

初始: taken = false (resp_in 全 0)


┌──────────────────────────────────────────────────────────────────────────────────┐
│ μBTB: 不修改 taken │
│ (μBTB 主要提供 predicted_pc) │
└──────────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────────┐
│ BIM: taken = counter[1] ← 根据 2-bit 计数器设置 │
│ (BIM 是第一个真正设置 taken 的预测器) │
└──────────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────────┐
│ BTB: if (is_jal) taken = true ← JAL 强制跳转 │
│ else taken = 透传 ← 分支保持 BIM 的预测 │
│ │
│ 同时覆盖: predicted_pc, is_br, is_jal │
└──────────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────────┐
│ TAGE: if (命中 && 强预测) taken = TAGE 预测 │
│ elif (命中 && 弱预测) taken = 备选预测 或 上游(BTB) │
│ else (未命中) taken = 上游(BTB) ← 这里使用了 BTB/BIM! │
│ │
│ TAGE 未命中时,BIM 的预测通过 BTB 透传过来被使用 │
└──────────────────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────────┐
│ Loop: if (循环结束条件) taken = !上游(TAGE) ← 翻转 │
│ else taken = 上游(TAGE) ← 透传 │
└──────────────────────────────────────────────────────────────────────────────────┘


最终输出

10. 总结:预测器协作的核心思想

1
2
3
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ 设计哲学总结 │
└───────────────────────────────────────────────────────────────────────────────────────┘
  1. 级联覆盖 (Cascaded Override)

    每个预测器接收上游的预测,在自己更有把握时覆盖,否则透传。

    uBTB → BIM → BTB → TAGE → Loop
    │ │ │ │ │
    └──────┴──────┴──────┴──────┘
    越往右越准确

  2. 专业分工 (Specialization)

    • 目标预测: μBTB (快), BTB (准)
    • 方向预测: BIM (基础), TAGE (复杂模式), Loop (循环)

    每个预测器只做自己擅长的事

  3. 速度与精度权衡 (Speed-Accuracy Trade-off)

    • F1 输出: 快但可能不准 (μBTB)
    • F2 输出: 中等 (BIM, BTB)
    • F3 输出: 准但慢 (TAGE, Loop)

    Frontend 可以根据需要使用不同阶段的预测

  4. 元数据保存与恢复 (Meta Preservation)

    预测时的内部状态 (meta) 被保存到 FTQ,
    更新时解包回各个预测器,
    确保更新使用的是预测时的状态,而不是当前状态。

  5. 推测更新与确定更新分离

    • f3_fire: 预测被前端采用,推测更新 (Loop 的 s_cnt)
    • update: 后端确认,确定性训练 (所有预测器)

    两条路径相互配合,既保证响应速度,又保证正确性。

这就是 BOOM v4 分支预测器的完整协作机制。核心是级联覆盖设计:简单预测器提供基础预测,复杂预测器在有把握时覆盖,最终形成一个既快速又准确的预测系统。


riscv-boom's bp
http://blog.luliang.online/2025/12/02/分支预测器boom/
作者
Luyoung
发布于
2025年12月2日
许可协议