实验 3:单周期处理器设计
任务 1:完成单周期数据通路搭建
Task 1
依据简化的单周期数据通路,实现对 RV32I 大部分指令的支持。
本次实验需要实现的指令包括:
- 移位指令 sll、slli、srl、srli、sra、srai
- 算数与逻辑指令 add、addi、sub、xor、xori、or、ori、and、andi
- 置数指令 slt、slti、slti、sltiu、auipc、lui
- 分支指令 beq、blt、bne、bge、bltu、bgeu、jal、jalr(思考该指令的实现)
- 访存指令 lw、lb、lh、lbu、lhu、sw、sb、sh(注意非整字访存指令的实现)
提示
- 单周期的寄存器堆应当设置为读优先,否则仿真时会出现组合环,影响结果正确性。寄存器堆的读取需要是时钟异步的,否则会造成时序错误;
- 在译码器中添加对于
ebreak
指令的支持 ———— 处理器执行到该指令时,能正确产生halt
信号; -
非整字访存指令需要设计专用的访存控制单元。一种实现方案是先读后写。例如:如果我们想要带符号地读取 0x5 地址上的字节的值,我们就需要先读取 0x4 开始的四个字节上的数据,再取出其中的第 8~15 位,右移 8 位并符号扩展之后写入目标寄存器,总结起来就是:
x[rd] = {{24{(M[0x4])[15]}}, (M[0x4])[15:8]}
如果我们想要向 0x5 地址上写入一个字节的数据 0x12,为了不影响其余字节的数据,就需要先将它们读出,与待写入的数据拼接之后再写回。因此,实际执行的操作就是:
M[0x4] = {(M[0x4])[31:16], (x[rd])[7:0], (M[0x4])[7:0]}
另一种实现方案是存储器拆分:将数据存储器拆分成 4 个不同的小存储器,每个存储器为 1024*8bit。所有的数据访问操作被分解到对应的子存储器上进行。这种设计的时序会更好。
在正常情况下,CPU 要求半字访问指令 lh、lhu、sh 仅会访问一个字中的低半字(0、1 字节)或高半字(2、3 字节),不会出现跨字访问或中间访问(1、2 字节)。因此,你可以假定所有的访问都是合法的,对于不合法的数据可以自行指定其功能;
-
本次实验实际上是普通班 Lab3、Lab4 的整合,因此遇到困难可以阅读普通班的实验文档。
任务 2:验证通路正确性
Task 2
基于仿真框架验证单周期处理器的正确性。本次实验仿真框架和上板框架的详细介绍请参考项目框架介绍、仿真框架使用手册 和 PDU 使用手册。
Rars 的设置
本次实验需要将 rars 的内存空间设置为默认类型,因为仿真框架规定了程序段的地址范围为 0x00400000 ~ 0x0ffffffc。
需要注意的是,使用仿真框架时需要设定所选的指令集以及处理器类型(完整单周期处理器),并在 CPU 内部 commit
信号产生时生成 DMEM 相关的信号,即将
commit_dmem_we_reg <= 0;
commit_dmem_wa_reg <= 0;
commit_dmem_wd_reg <= 0;
改为
commit_dmem_we_reg <= dmem_we; // 你 CPU 中数据存储器的对应信号
commit_dmem_wa_reg <= dmem_wa; // 你 CPU 中数据存储器的对应信号
commit_dmem_wd_reg <= dmem_wd; // 你 CPU 中数据存储器的对应信号
我们准备了一些测试文件,用于检测处理器执行指令的正确性。
你可以使用 Vivado 的波形图,对比处理器运行完成后寄存器堆的数值是否与 rars 一致;也可以将上面的指令载入仿真框架,由框架自动评测正确性(推荐后者)。
任务 3:上板运行
Task 3-1
使用 PDU 上板框架在开发板上部署单周期处理器。PDU 的源文件在这里,约束文件请基于 Lab1 的约束文件进行修改,添加对于串口的约束:
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart_txd }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
需要注意的是,PDU 文件内部的数码管模块为 FPGAOL 版本,用于显示当前的 commit_inst
。如果需要在开发板上使用,请将 Segment
模块替换为开发板版本,并调整内部连线位宽。
物理开发板的串口交互可以使用 PuTTY 工具。默认的波特率为 9600,如果需要修改波特率,请自行调整 PDU 中 uart_rx、uart_tx 两个文件中的计数器。串口通信相关的知识可以参考这里。
提醒
如果你始终无法在物理开发板上部署处理器,可以在 FPGAOL 的 zynq 开发板上进行部署,但会损失小部分分数。此外,我们强烈建议大家在仿真阶段确定 CPU 功能正确性后,再上板验证时序正确性。
Task 3-2
上板运行汇编排序程序、指令测试程序,并与 rars 的结果进行对比。
选做任务:乘除法扩展
Task X
在实现上述指令的基础上,额外实现 mul, mulh, mulh, div, divu, rem, remu 指令。请自行设计指令测试程序验证其正确性,并进行仿真与上板测试。
实验检查与提交
本次实验布置时间为 2025-04-02,持续两周。相应的 DDL 节点如下:
检查 DDL | 报告提交 DDL |
---|---|
2025-04-16 21:00 | 2025-04-23 23:59 |
检查与报告延迟一周以内(含)的,至多只能得到 80% 分数;延迟一周以上、两周以内(含)的,至多只能得到 60% 分数;延迟超过两周的不得分。
提醒
实验的 DDL 为当天晚上 21:00。助教有权利在 21:00 准时停止检查,请大家合理安排好自己的时间。
关于实验报告
实验报告需要大家提交 PDF 格式。我们推荐大家使用 Markdown 或者 Latex 撰写实验报告,这样可以直接导出为 PDF。大家也可以使用 Word、WPS 等进行报告撰写,最后转换为 PDF 格式。我们不推荐也不拒绝大家手写实验报告,但请将其拍照扫描成 PDF 文件后再上传。我们不接受任何因为文件格式错误而导致成绩异常的申诉请求!
在实验报告中,你需要给出每一项任务的答案,并附上必要的说明过程(或截图)。
特别地:实验报告的字数和排版与最终得分无关。影响得分的仅有内容正确性与完整性。
实验报告请提交至 BB 平台。