1. 课程导入
欢迎进入《RISC-V CPU从RTL仿真到FPGA原型验证项目》课程。本课程不是单纯讲解 RISC-V 指令集,也不是只教某个 EDA 工具的操作,而是围绕一个可运行、可验证、可上板的 RISC-V CPU 项目,把 RTL 设计、功能仿真、波形调试、综合实现、FPGA 原型验证 串成一条完整工程链路。学完本课程,你应当能够独立完成一个小型 RISC-V 处理器的仿真验证,并把它部署到 FPGA 开发板上运行测试程序。
一、学习目标:从“会写模块”到“能交付原型”
很多学习者能写 Verilog 模块,却无法回答“这个 CPU 到底能不能跑通程序”。本课程的目标是建立端到端的交付能力,具体分为四个层次:
- 理解架构:掌握 RV32I 指令格式、寄存器堆、ALU、取指译码执行访存写回等基本数据通路。
- 掌握仿真:能编写 testbench,使用 Verilator 或 Icarus Verilog 进行 RTL 仿真,并通过波形定位问题。
- 完成实现:能编写约束文件,完成综合、布局布线,生成比特流并下载到 FPGA。
- 原型验证:能通过 UART、LED、ILA 等片上资源观察 CPU 运行状态,验证指令执行结果。
二、核心概念:RTL、仿真与原型验证的关系
RTL(Register Transfer Level)是用硬件描述语言描述寄存器之间数据传输与逻辑运算的抽象层次。RTL 仿真是在软件环境中对设计施加激励并观察响应,它速度快、可观测性强,但不等同于真实硬件。FPGA 原型验证则是把 RTL 综合映射到可编程逻辑阵列中,以接近真实时序的方式运行。
三者关系可以概括为:RTL 是源,仿真是第一道筛子,FPGA 原型是最终试金石。仿真能发现绝大多数功能错误,但无法完全覆盖时序、复位、跨时钟域和板级电气问题;FPGA 原型能暴露真实问题,但调试可观测性弱于仿真。因此本课程强调“先仿真后上板、仿真与上板结果对齐”的方法论。
三、整体框架:课程知识模块与工具链
课程按“设计—验证—实现—原型”四段推进,每段都配有可操作任务。下表给出模块划分与关键工具,便于你建立全局认知。
| 阶段 | 核心内容 | 关键工具/文件 | 交付物 |
|---|---|---|---|
| RTL 设计 | RV32I 取指、译码、执行、访存、写回 | Verilog/SystemVerilog、编辑器 | 可综合 RTL 源码 |
| 功能仿真 | 指令级测试、波形调试、覆盖率 | Verilator、Icarus、GTKWave | 仿真日志与波形 |
| 综合实现 | 时序约束、资源映射、布局布线 | Vivado/Quartus、XDC/SDC | 比特流与资源报告 |
| FPGA 原型 | 下载、UART 输出、ILA 抓取 | 开发板、串口助手、ILA | 板级运行结果 |
四、方法流程:一个最小可运行闭环
为了避免“学完不知道做了什么”,本课程始终围绕一个最小闭环推进。你可以把它理解为项目的主循环:
- 编写或修改 RTL 模块,例如 ALU 或寄存器堆。
- 编写 testbench,施加激励并检查输出。
- 运行仿真,观察波形与日志,定位错误。
- 修正 RTL,重复仿真直到通过。
- 添加约束,综合实现并生成比特流。
- 下载到 FPGA,运行测试程序,比对结果。
下面是一个典型的仿真命令示例,后续章节会反复使用类似流程:
# 使用 Verilator 进行 RTL 仿真
verilator --cc --exe --build top.v tb_top.cpp -o sim_cpu
./obj_dir/sim_cpu
# 使用 Icarus Verilog + GTKWave 查看波形
iverilog -o cpu_sim top.v tb_top.v
vvp cpu_sim
gtkwave dump.vcd
五、案例场景:从一条 add 指令看全链路
假设我们要验证 add x3, x1, x2 这条指令。在 RTL 仿真中,testbench 会初始化 x1=5、x2=7,执行后检查 x3 是否等于 12。若仿真通过,我们再把同样的测试程序烧录到 FPGA,通过 UART 打印 x3 的值。如果仿真得到 12,而板级得到 0 或随机值,就说明问题可能出在复位、时钟、存储器初始化或约束上,而不是指令语义本身。
这个案例说明:仿真和原型验证不是重复劳动,而是互相印证的两个视角。仿真帮你确认逻辑正确,原型帮你确认硬件可用。
六、常见误区与复盘
- 误区一:只写 RTL 不做仿真。 结果上板后无法定位问题,只能盲目改代码。
- 误区二:仿真通过就认为上板一定通过。 忽略时序、复位和跨时钟域问题。
- 误区三:不保存波形和日志。 问题复现困难,无法回溯。
- 误区四:测试程序过于简单。 只跑一条指令,无法覆盖分支、访存和流水线冲突。
本课程后续将沿着这条路线,从 RV32I 最小核开始,逐步加入仿真验证、综合约束和 FPGA 原型测试。你不需要一开始就拥有高端开发板,但需要保持“每写一段代码就验证一次”的工程习惯。掌握这条链路后,你不仅能完成一个 RISC-V CPU 原型,也能把同样的方法迁移到其他数字系统设计中。