姓名:朱梓涵
学号:24325356

1. 实验目的

本实验旨在深入理解 RISC-V 指令集架构 (ISA) 与单周期 CPU 的工作原理。实验目标包括:

  1. 设计并实现一个支持部分 RV32I 指令集的单周期 CPU。
  2. 掌握 CPU 经典五阶段(取指、译码、执行、访存、写回)在单周期模型下的数据通路和控制逻辑设计。
  3. 学习使用 Chisel 硬件描述语言进行模块化硬件设计。
  4. 通过编写单元测试和集成测试,利用 chiseltest 和 GTKWave 波形图验证 CPU 各模块及整体功能的正确性。

2. 实验环境

3. 阶段功能划分

  1. 取指 (IF): 程序计数器 (PC) 提供指令地址,指令存储器根据该地址输出 32 位指令。PC 在每个时钟周期默认加 4,若遇跳转或分支成功,则更新为目标地址。
  2. 译码 (ID): 译码单元解析指令,提取操作数(寄存器地址 rs1, rs2)、目标寄存器地址 (rd) 和立即数。主控制器根据指令操作码生成后续阶段所需的所有控制信号。
  3. 执行 (EX): 算术逻辑单元 (ALU) 根据译码阶段生成的控制信号,对来自寄存器文件或立即数生成器的操作数进行计算。同时,分支跳转的地址计算和条件判断也在此阶段完成。
  4. 访存 (MEM): 根据译码阶段生成的访存控制信号,与数据存储器进行交互。Load 指令从此阶段读取数据,Store 指令则向此阶段写入数据。
  5. 写回 (WB): 将执行结果或从数据存储器中读取的数据写回寄存器文件。写回的数据来源由控制信号决定。

4. 模块实现与分析

4.1 取指

b1

4.2 译码

b2

4.3 执行

b3

4.4 CPU

5. 测试与结果分析

5.1 单元测试:InstructionDecoderTest 分析

5.2 整体测试:CPUTest (以FibonacciTest 为例)

6. 遇到的问题与改进建议

  1. 问题:立即数生成规则复杂,指导文档未详细展开。
    在实现译码模块时,RISC-V 不同指令格式(I/S/B/U/J)的立即数拼接方式各不相同,实验指导对此描述较为简略,导致初期实现困难。

    • 建议:在实验指导中为每种指令格式提供一个具体的立即数拼接图示或示例代码,能极大帮助理解。
  2. 问题:缺少对波形图调试的引导案例。
    初次使用 GTKWave 进行硬件调试时,面对海量的信号线,难以快速定位关键信号。

    • 建议:实验文档中可以附加一个简单的调试案例,例如追踪一条 add 指令的数据流,展示如何从取指 PC 开始,逐步添加 instruction, reg_read_data, alu_result, reg_write_data 等信号,并解释它们在波形图上的时序关系。
  3. 问题:部分模块接口和控制信号的设计意图不够明确。
    例如,ALUOp1SourceALUOp2Source 这类控制信号的设计初衷,需要通过阅读多个模块的代码才能完全理解其作用。

    • 建议:在代码框架的注释中,对关键的 objectEnum(如 ALUOp1Source),增加注释来说明每个选项的用途和对应的指令场景。

7. 实验结论

通过本次实验,我成功设计并实现了一个功能基本完备的 RISC-V 单周期 CPU。在实现过程中,我深入理解了数据通路与控制信号在指令执行过程中的协同作用,并掌握了模块化的硬件设计思想。通过编写和分析单元测试与集成测试,我学会了如何利用 chiseltest 和波形图对硬件设计进行验证和调试。本次实验极大地加深了我对计算机组成原理中理论知识的实践理解,为后续更复杂的处理器设计打下了坚实的基础。

e=mc2e=mc^2