实验 6: 具有六阶段流水线和分支预测的 RISC-V 处理器

实验 6截止日期: 2016年11月7日,美东时间晚上11:59:59。

本实验的交付物为:

  • SixStage.bsvBht.bsvSixStageBHT.bsv 中完成的练习1至4的答案
  • discussion.txt 中完成的讨论问题1至9的答案

引言

本实验是你对现实中的 RISC-V 流水线和分支预测的介绍。在本实验结束时,你将拥有一个具有多种地址和分支预测器协同工作的六级 RISC-V 流水线。

注意:在本实验中,我们使用一位全局时期(而非无限分布时期)来终止错误路径指令。请学习全局时期的幻灯片:[pptx] [pdf],以理解全局时期方案。幻灯片的内容也将在教程中讲解。

实验设施的新增部分

新包含的文件

以下文件出现在 src/includes/ 中:

文件名描述
FPGAMemory.bsvFPGA上常见的块 RAM 的封装器。它的接口与上一个实验中的 DelayedMemory 相同。
SFifo.bsv三种可搜索的 FIFO 实现:基于流水线 FIFO、基于旁路 FIFO 和基于无冲突 FIFO 的实现。所有实现都假设在 enq 之前立即完成搜索。
Scoreboard.bsv基于可搜索 FIFO 的三种记分牌实现。流水线记分牌使用流水线可搜索 FIFO,旁路记分牌使用旁路可搜索 FIFO,无冲突记分牌使用无冲突可搜索 FIFO。
Bht.bsv一个空文件,在其中你将实现一个分支历史表(BHT)。

新的汇编测试

以下文件出现在 programs/assembly/src 中:

文件名描述
bpred_j_noloop.Sbpred_j.S 类似的汇编测试,但移除了外部循环。

新的源文件

以下文件出现在 src/ 中:

文件名描述
TwoStage.bsv包含一个两级流水线的 RISC-V 处理器的初始文件。此处理器使用 BTB 进行地址预测。使用 twostage 目标编译。
SixStage.bsv一个空文件,在其中你将把两级流水线扩展为六级流水线。使用 sixstage 目标编译。
SixStageBHT.bsv一个空文件,在其中你将把分支历史表(BHT)整合到六级流水线中。使用 sixstagebht 目标编译。
SixStageBonus.bsv一个空文件,在其中你可以改进前一个处理器以获得额外学分。使用 sixstagebonus 目标编译。

测试改进

在前一个实验中,使用命令 build -v <proc_name>(从 scemi/sim/ 目录运行)用于构建 bsim_duttb。在本实验中,此命令构建 <proc_name>_dut 而非 `

bsim_dut`,因此切换处理器类型时不会删除其他处理器构建。

模拟脚本现在要求您指定目标处理器:

./run_asm.sh <proc_name>
./run_bmarks.sh <proc_name>

模拟单个测试要求您运行正确的模拟可执行文件:

cp ../../programs/build/{assembly,benchmarks}/vmh/<test_name>.riscv.vmh mem.vmh
./<proc_name>_dut > out.txt &
./tb

两级流水线:TwoStage.bsv

TwoStage.bsv 包含一个两级流水线的 RISC-V 处理器。这个处理器与你在上一个实验中构建的处理器不同,因为它在第一阶段读取寄存器值,存在数据危害。

讨论问题 1(10 分): 调试实践!

如果你将 BTB 替换为简单的 pc + 4 地址预测,处理器仍然可以工作,但性能不佳。如果你用一个非常糟糕的预测器替换它,该预测器预测每个 pc 的下一个指令是 pc,它应该仍然可以工作,但性能会更差,因为每个指令都需要重定向(除非指令回到其自身)。如果你真的将预测设置为 pc,你会在汇编测试中得到错误;第一个错误将来自于 cache.riscv.vmh

  • 你得到的错误是什么?
  • 处理器中发生了什么导致这种情况?
  • 为什么你在 PC+4 和 BTB 预测器中没有得到这个错误?
  • 你将如何修复它?

你实际上不必修复这个错误,只需回答问题。(提示:查看 ExecInst 结构的 addr 字段。)

六级流水线:SixStage.bsv

六级流水线应该分为以下阶段:

  • 指令取回 —— 从 iMem 请求指令并更新 PC
  • 解码 —— 接收来自 iMem 的响应并解码指令
  • 寄存器取值 —— 从寄存器文件读取
  • 执行 —— 执行指令并在必要时重定向处理器
  • 内存 —— 向 dMem 发送内存请求
  • 写回 —— 接收来自 dMem 的内存响应(如果适用)并写入寄存器文件

应将 IMemoryDMemory 实例替换为 FPGAMemory 实例,以便在 FPGA 上实现。

练习 1(20 分):从 TwoStage.bsv 中的两级实现开始,将每个内存替换为 FPGAMemory 并在 SixStage.bsv 中扩展为六级流水线。在模拟中,基准测试 qsort 可能需要更长时间(助教的桌面上为21秒,vlsifarm 机器上可能需要更长时间)。

注意,两级实现使用无冲突寄存器文件和记分牌。然而,你可以使用流水线或旁路版本的这些组件以获得更好的性能。同样,你可能想改变记分牌的大小。

讨论问题 2(5 分):你有什么证据表明所有流水线阶段可以在同一个周期内触发?

讨论问题 3(5 分):在你的六级流水线处理器中,纠正错误预测的指令需要多少个周期?

讨论问题 4(5 分):如果一条指令依赖于流水线中紧接其前的指令的结果,这条指令会延迟多少个周期?

讨论问题 5(5 分):你为每个基准测试获得了多少 IPC?

添加分支历史表:SixStageBHT.bsv

分支历史表(BHT)是一个跟踪分支历史的结构,用于方向预测。你的 BHT 应该使用从程序计数器(PC)中取得的参数化位数作为索引——通常是从第 n+1 位到第 2 位,因为第 1 和 0 位总是零。每个索引应该有一个两位的饱和计数器。不要在 BHT 中包含任何有效位或标签;我们不关心我们的预测中的别名问题。

练习 2(20 分):在 Bht.bsv 中实现一个使用参数化位数作为表索引的分支历史表。

讨论问题 6(10 分):规划!

这个实验中最困难的事情之一是正确地训练和整合 BHT 到流水线中。在仍然看到不错的结果的情况下,可以犯很多错误。通过基于方向预测的基础知识制定一个好的计划,你将避免许多这些错误。

对于这个讨论问题,说明你将 BHT 整合到流水线中的计划。以下问题应该有助于指导你:

  • BHT 将被放置在流水线的哪个位置?

  • 哪个流水线阶段执行对 BHT 的查找?

  • 在哪个流水线阶段将使用 BHT 预测?

  • BHT 预测是否需要在流水线阶段之间传递?

  • 如何使用 BHT 预测重定向 PC?

你需要添加新的 epoch 吗? >

  • 如何处理重定向消息?

  • 如果重定向,你需要改变当前指令及其数据结构吗?

  • 你将如何训练 BHT?

  • 哪个阶段产生 BHT 的训练数据?

  • 哪个阶段将使用接口方法来训练 BHT?

  • 如何发送训练数据?

  • 你将为哪些指令训练 BHT?

  • 你如何知道你的 BHT 是否有效?

练习 3(20 分):将 256 个条目(8 位索引)的 BHT 集成到 SixStage.bsv 的六级流水线中,并将结果放入 SixStageBHT.bsv 中。

讨论问题 7(5 分):与 SixStage.bsv 处理器相比,你在 bpred_bht.riscv.vmh 测试中看到了多少提升?

练习 4(10 分):将 JAL 指令的地址计算上移到解码阶段,并使用 BHT 重定向逻辑来重定向这些指令。

讨论问题 8(5 分):与 SixStage.bsv 处理器相比,你在 bpred_j.riscv.vmhbpred_j_noloop.riscv.vmh 测试中看到了多少提升?

讨论问题 9(5 分):你在每个基准测试中获得了多少 IPC?与原始六级流水线相比,这有多大提升?

讨论问题 10(选做):完成这个实验室你用了多长时间?

完成后记得使用 git push 将你的代码推送。

额外改进:SixStageBonus.bsv

这一节探讨了两种加速间接跳转到寄存器中存储的地址的方法(JALR)。

练习 5(10 附加分):JALR 指令在寄存器取值阶段已知目标地址。在寄存器取值阶段为 JALR 指令添加一个重定向路径,并将结果放入 SixStageBonus.bsv 中。bpred_ras.riscv.vmh 测试应该会有稍微更好的结果,有了这种改进。

大多数程序中找到的 JALR 指令被用作从函数调用返回。这意味着这种返回的目标地址是由先前的 JAL 或 JALR 指令写入返回地址寄存器 x1(也称为 ra)的,该指令启动了函数调用。

为了更好地预测 JALR 指令,我们可以在处理器中引入返回地址堆栈(RAS)。根据 RISC-V ISA,使用 rd=x0rs1=x1 的 JALR 指令通常用作函数调用的返回指令。此外,使用 rd=x1 的 JAL 或 JALR 指令通常用作跳转以启动函数调用。因此,我们应该为带有 rd=x1 的 JAL/JALR 指令推送 RAS,并为带有 rd=x0rs1=x1 的 JALR 指令弹出 RAS。

练习 6(10 附加分):实现一个返回地址堆栈,并将其集成到处理器的解码阶段(SixStageBonus.bsv)。8 个元素的堆栈应该足够。如果堆栈满了,你可以简单地丢弃最旧的数据。bpred_ras.riscv.vmh 测试应该会有更好的结果,有了这种改进。如果你在一个单独的 BSV 文件中实现了 RAS,请确保将其添加到 git 仓库中进行评分。


© 2016 麻省理工学院。保留所有权利。