第二讲:开发环境搭建——工欲善其事,必先利其器
各位同学,咱们今天不急着写代码。先聊聊环境搭建。
说实话,我见过太多人一上来就撸Verilog,结果仿真跑不通、编译报错、工具链没配好,折腾半天连个“Hello World”都出不来。嗯,这种挫败感我太懂了。所以这一讲,咱们把地基打牢。
2.1 仿真工具的选择:Icarus Verilog vs Verilator
仿真工具,说白了就是让你在电脑上“跑”你的Verilog代码。我个人习惯用两套工具:
- Icarus Verilog(iverilog):轻量、易上手,适合小模块验证。配合GTKWave看波形,绝配。
- Verilator:高性能,能把Verilog转成C++再编译,跑大型SoC仿真飞快。但语法检查更严格,新手容易碰壁。
我的建议是:刚开始用Icarus,等你要做复杂CPU验证时再切Verilator。别一上来就挑战高难度。
安装Icarus Verilog(Ubuntu为例)
sudo apt-get update
sudo apt-get install iverilog gtkwave
装完验证一下:
iverilog -V
看到版本号就对了。Windows用户可以去官网下载安装包,记得勾上GTKWave。
安装Verilator
sudo apt-get install verilator
或者从源码编译(我推荐这种方式,能拿到最新版):
git clone https://github.com/verilator/verilator
cd verilator
autoconf
./configure
make -j$(nproc)
sudo make install
⚠️ 注意:Verilator对SystemVerilog的支持有限。如果你用了`always_ff`、`interface`等语法,可能会报错。我曾经在这上面栽过跟头,后来老老实实改回`always @(posedge clk)`。
2.2 RISC-V工具链配置:GCC还是LLVM?
你要做自定义扩展指令,光有仿真工具不够。还得有编译器,能把你的C代码编译成RISC-V机器码。
这里有两个选择:
| 工具链 | 优点 | 缺点 |
|---|---|---|
| RISC-V GNU GCC | 成熟稳定,文档多,社区支持好 | 编译速度慢,二进制体积大 |
| LLVM/Clang | 模块化设计,容易添加自定义指令支持 | 对RISC-V支持还在完善中 |
我个人建议:初学者先用GCC。等你要做自定义指令的编译器后端时,再研究LLVM。
安装RISC-V GCC工具链
sudo apt-get install gcc-riscv64-linux-gnu
或者从源码编译(时间长,但可控):
git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv
make -j$(nproc)
装完测试一下:
riscv64-linux-gnu-gcc --version
💡 小技巧:如果你只是做指令仿真,不需要完整的Linux工具链。装个
riscv64-unknown-elf-gcc就够了,它只生成裸机代码,编译速度快很多。
2.3 测试平台框架搭建
环境搭好了,怎么验证你的扩展指令对不对?你需要一个测试平台(testbench)。
我习惯用这种结构:
project/
├── rtl/ # Verilog源文件
│ ├── core.v
│ └── custom_alu.v
├── sim/ # 仿真文件
│ ├── tb.v
│ └── run.sh
├── software/ # 测试程序
│ ├── test.S
│ └── link.ld
└── Makefile
一个最简单的testbench长这样:
// tb.v
`timescale 1ns/1ps
module tb;
reg clk;
reg rst_n;
// 实例化你的CPU核心
core u_core (
.clk(clk),
.rst_n(rst_n)
);
// 生成时钟
initial begin
clk = 0;
forever #5 clk = ~clk; // 100MHz
end
// 复位和测试
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, tb);
rst_n = 0;
#20 rst_n = 1;
#1000;
$finish;
end
endmodule
运行仿真:
iverilog -o sim.vvp tb.v ../rtl/*.v
vvp sim.vvp
gtkwave wave.vcd
核心要点:
- 用
$dumpfile和$dumpvars生成波形文件 - 时钟周期设为10ns(100MHz)比较通用
- 复位至少保持20ns,确保所有寄存器初始化
2.4 用SVG画一张环境搭建流程图
下面这张图,是我自己画的环境搭建流程。你照着走,基本不会出错。
2.5 避坑指南
最后,分享几个我踩过的坑:
- 路径问题:工具链安装后,记得把
/opt/riscv/bin加到PATH里。我曾经忘了这步,折腾了半小时。 - 版本兼容:Icarus Verilog 12.0以上版本对某些语法更严格。如果你用的是旧代码,建议锁定版本。
- 波形文件太大:仿真时间设太长,VCD文件能到几个GB。用
$dumpvars(0, tb)只dump顶层信号,别全dump。 - Makefile是必需品:别手敲命令。写个Makefile,一键仿真、一键清理,省心省力。
💡 我的个人习惯:每次新建项目,先跑一个最简单的testbench——就一个寄存器、一个时钟。确认仿真环境没问题了,再开始写核心逻辑。这叫“最小可行验证”,能帮你快速定位是环境问题还是代码问题。
好了,环境搭建就聊到这儿。下一讲咱们开始写真正的RISC-V核心,到时候你会感谢今天认真搭环境的自己。