本项目实现了一个支持 RISC-V 指令集的简单单周期 CPU,能够执行多种基础指令并完成完整的指令周期。通过模块化设计,将 CPU 划分为多个功能单元,实现了从指令取指、解码、执行到结果写回的完整流程。项目采用 Verilog HDL 语言开发,基于 Vivado 2019.2 工具进行设计与仿真。 PS:本仓库包含2024年秋季复旦大学数字逻辑设计(DCD)课程的project与日常lab
-
R 型指令:add, sub, or, slt
-
I 型指令:addi, ori, slti, lw
-
S 型指令:sw
-
B 型指令:beq(扩展功能)
-
程序计数器 (PC):管理指令地址的更新与跳转
-
指令存储器:存储 RISC-V 指令(小端模式)
-
控制单元:解析指令并生成控制信号
-
寄存器堆:实现 32 个通用寄存器(含 x0 固定为 0)
-
ALU:支持加法、减法、逻辑或、小于比较等运算
-
数据存储器:支持 lw/sw 指令的数据读写
-
立即数生成器:根据指令类型生成符号扩展的立即数
技术栈
-
硬件描述语言:Verilog HDL
-
设计工具:Vivado 2019.2
-
操作系统:Windows 11
-
功能:管理当前指令地址,支持顺序执行和分支跳转
-
接口:
module pc (
  input wire clk,
  input wire rst,
  input wire \[31:0] pc\_next,
  output reg \[31:0] pc
);
-
功能:存储 32 位 RISC-V 指令(256 字节空间)
-
设计:小端模式存储,预加载 10 条测试指令
-
接口:
module instruction\_memory (
  input wire \[31:0] Address,
  output wire \[31:0] Instr
);
-
功能:根据指令操作码生成控制信号
-
输出信号:RegWrite, ALUSrc, MemRead, MemWrite, MemtoReg, Branch, ALUOp
-
接口:
module control (
  input wire \[6:0] opcode,
  input wire \[2:0] funct3, 
  input wire \[6:0] funct7, 
  output reg RegWrite,
  output reg ALUSrc,
  output reg MemRead,
  output reg MemWrite,
  output reg MemtoReg,
  output reg Branch,
  output reg \[1:0] ALUOp
);
-
功能:实现 32 个 32 位通用寄存器(x0 固定为 0)
-
特性:同步写、异步读,支持寄存器读写控制
-
接口:
module register\_file (
  input wire clk,
  input wire rst,
  input wire reg\_write,
  input wire \[4:0] rs1,
  input wire \[4:0] rs2,
  input wire \[4:0] rd,
  input wire \[31:0] write\_data,
  output wire \[31:0] read\_data1,
  output wire \[31:0] read\_data2
);
-
安装 Vivado 2019.2 或更高版本
-
确保 Verilog 编译环境正常
.
├── top.v # 顶层模块
├── pc.v # 程序计数器
├── instruction\_memory.v # 指令存储器
├── data\_memory.v # 数据存储器
├── control.v # 控制单元
├── immediate\_gen.v # 立即数生成器
├── register\_file.v # 寄存器堆
├── alu\_control.v # ALU控制器
├── alu.v # ALU运算单元
├── top\_tb.v # 测试平台
└── constraints.xdc # 约束文件
-
在 Vivado 中创建新工程
-
导入所有 Verilog 文件
-
运行行为仿真(Functional Simulation)
-
查看波形图验证指令执行结果
// 预加载的测试指令(小端模式)
addi x1, x0, 8 // 0x00800093
lw x2, 4(x1) // 0x0040a103
add x3, x1, x2 // 0x002081b3
sub x4, x3, x1 // 0x40318233
or x5, x1, x4 // 0x0041e2b3
ori x6, x5, 1 // 0x00012E13
sw x6, 0(x2) // 0x00612023
slt x7, x2, x4 // 0x004241b3
slti x8, x2, 8 // 0x00812213
beq x3, x5, -12 // 0xfe8518e3
实验结果
所有目标指令均通过功能仿真验证:
-
算术指令:add/sub/addi 正确实现数值运算
-
逻辑指令:or/ori/slt/slti 正确实现逻辑操作
-
访存指令:lw/sw 正确完成数据读写
-
分支指令:beq 正确实现条件跳转
图 1:关键信号仿真波形(pc、instr、ALUResult 等)
性能分析
-
最差建立时间裕量 (WNS):-0.858 ns(存在时序问题)
-
保持时间裕量 (WHS):0.222 ns(满足要求)
-
失败端点数量:1308 个(主要为建立时间违规)
-
关键路径延迟过长,主要集中在控制信号生成和 ALU 运算路径
-
单周期设计限制了最高时钟频率,复杂指令影响整体性能
-
流水线设计:改为 5 阶段流水线(取指、译码、执行、访存、写回)
-
关键路径优化:
-
拆分复杂组合逻辑
-
优化 ALU 结构
-
采用多级控制信号生成
- 存储器优化:
-
分离指令和数据存储器
-
引入高速缓存机制
- 时序约束调整:
-
优化时钟频率
-
调整路径约束
遇到的问题与解决方法
- 波形图无信号显示:
-
问题:内部信号未正确添加到波形观察列表
-
解决:通过 Vivado 的 "Add Wave" 功能手动添加关键信号
- 时序违规问题:
-
问题:复杂组合逻辑导致建立时间不满足
-
解决:拆分组合逻辑,增加寄存器级流水线
- 指令解析错误:
-
问题:操作码与控制信号映射错误
-
解决:重新核对 RISC-V 指令集规范,修正控制单元逻辑
-
主要设计与实现:张彦鹏
-
技术支持:感谢 课程助教 在模块设计和仿真调试中的指导
