· 5 min read

BTB Branch Prediction for a Pipelined RISC-V CPU

Designing a 32-entry direct-mapped Branch Target Buffer for a 5-stage RISC-V pipeline — with tag comparison, train-on-taken update policy, and IF-stage bubble handling.

#risc-v #branch-prediction #btb #deep-dive

TL;DR

32-entry 直接映射 BTB,tag 比较命中时预测跳转,未命中时预测不跳转。训练策略:EX 阶段更新。

1. Why Branch Prediction

5 级流水线中,分支指令在 EX 阶段才知道结果。如果不预测,每次分支都停顿 2 周期(IF + ID 被浪费)。BTB 可以在 IF 阶段就给出预测目标,消除大部分停顿。

2. BTB Architecture

if_pc[6:2] ──▶ 5-bit Index


┌──────────────────────────────────────┐
│              BTB (32 entries)         │
│  ┌───────┬───────────┬────────────┐  │
│  │ valid │   tag     │   target   │  │
│  │  1b   │   25b     │    32b     │  │
│  └───────┴───────────┴────────────┘  │
└──────────────────────────────────────┘


        if_tag == btb_tag? ──▶ pred_jump, pred_target
  • valid:该 slot 是否存有有效条目
  • tag:PC 高位,用于区分映射到同一 index 的不同 PC
  • target:预测的跳转目标地址

3. Prediction Logic (Combinational)

// IF 阶段:组合逻辑查询
if (btb_valid[if_idx] && (btb_tag[if_idx] == if_tag)) begin
    pred_jump   = 1'b1;
    pred_target = btb_target[if_idx];
end

组合逻辑,零延迟。在 IF 阶段的同一周期内完成查询并驱动 PC mux。

4. Update Policy

// EX 阶段:同步更新
if (ex_is_branch) begin
    if (ex_branch_taken) begin
        btb_valid[ex_idx]  <= 1'b1;
        btb_tag[ex_idx]    <= ex_tag;
        btb_target[ex_idx] <= ex_branch_target;
    end else begin
        if (btb_valid[ex_idx] && (btb_tag[ex_idx] == ex_tag))
            btb_valid[ex_idx] <= 1'b0;
    end
end

训练策略:只在 EX 阶段确认跳转时才写入 BTB。未命中的非跳转指令不修改 BTB。

5. Pipeline Bubble on Mispredict

Cycle 1 ──▶ IF: Fetch branch PC        ◀─ BTB miss → predict not taken
Cycle 2 ──▶ ID: Decode branch
Cycle 3 ──▶ EX: Branch resolved → taken!
             └── flush IF/ID, redirect PC to branch_target
Cycle 4 ──▶ IF: Fetch from correct target   ◀─ 1-cycle bubble penalty
Cycle 5 ──▶ ID: Decode next
Cycle 6 ──▶ EX: ...

预测失败时,IF/ID 两级的指令被清空,PC 重定向。惩罚为 2 个周期。

6. Limitations & Improvements

  • 直接映射冲突:两个 PC 映射同一 index 时互相驱逐,可用组相联缓解
  • 无方向预测:只存跳转目标,不区分 taken/not-taken,可加 2-bit Saturating Counter
  • 无返回地址栈:函数调用/返回场景下 miss 率高,可加 RAS
  • 无间接跳转预测:JALR 的目标地址每次不同,需要间接分支目标缓冲 (ITBTB)

Related Articles:

🔙 Back to Projects