2. 开发环境搭建:Verilog/SystemVerilog 工具链、RISC-V GCC 工具链、仿真环境配置
说实话,很多同学刚开始学 RISC-V 处理器设计,最头疼的不是架构本身,而是环境搭不起来。我见过太多人卡在「装完工具跑不通第一个 testbench」这一步,一卡就是一两天。所以这一章,咱们先把地基打牢。
我会带你装三样东西:硬件描述语言工具链(Verilog/SystemVerilog 的编译器)、RISC-V 软件工具链(GCC 交叉编译器)、以及仿真环境(Verilator 和 Icarus Verilog)。这三样配齐了,你才能写代码、编译、仿真、看波形,一个完整的开发闭环。
2.1 Verilog/SystemVerilog 工具链
硬件描述语言这边,主流选择其实不多。我个人习惯用 Icarus Verilog (iverilog) 做快速验证,配合 GTKWave 看波形。这套组合轻量、开源、跨平台,非常适合教学和原型验证。
安装方式很简单,Linux 下一条命令搞定:
# Ubuntu/Debian
sudo apt-get install iverilog gtkwave
# macOS (Homebrew)
brew install icarus-verilog gtkwave
装完之后,验证一下能不能用:
iverilog -V
如果输出版本号,说明装好了。嗯,这里要注意:iverilog 对 SystemVerilog 的支持是有限的。如果你要用 SV 的 interface、assertion 这些高级特性,建议上 Verilator 或者商业工具。我在项目中遇到过,用 iverilog 跑 SV 的断言,结果直接报语法错误,后来换成 Verilator 才搞定。
| 工具 | 支持语言 | 速度 | 适用场景 |
|---|---|---|---|
| Icarus Verilog | Verilog-2005, 部分 SV | 中等 | 教学、小规模验证 |
| Verilator | Verilog, SystemVerilog | 快(编译型) | 大规模仿真、性能验证 |
| VCS / NC-Verilog | 全支持 | 快 | 工业级项目 |
2.2 RISC-V GCC 工具链
RISC-V 的软件工具链,说白了就是交叉编译器。你需要在 x86 的电脑上编译出能在 RISC-V 处理器上跑的机器码。这个工具链叫 riscv-gnu-toolchain,它包含 GCC、binutils、glibc/newlib 等一整套东西。
安装方式有两种:
- 直接下载预编译包(推荐新手)
- 从源码编译(适合进阶玩家)
预编译包可以从 SiFive 或者 RISC-V International 的官方仓库下载。我个人习惯用 SiFive 的 Freedom Studio 里面自带的工具链,省事。
如果你要从源码编译,流程如下:
git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv --with-arch=rv32imc
make -j$(nproc)
这里 --with-arch=rv32imc 指定了目标架构:RV32I(基础整数指令集)+ M(乘除法扩展)+ C(压缩指令扩展)。咱们这个课程主要用 RV32IMC,够用了。
装完之后,验证一下:
riscv32-unknown-elf-gcc --version
如果输出版本号,恭喜你,工具链就绪了。你可以试着编译一个简单的 C 程序:
riscv32-unknown-elf-gcc -march=rv32imc -o test.elf test.c
然后反汇编看看生成的指令:
riscv32-unknown-elf-objdump -d test.elf
看到 RISC-V 指令了吧?这就是你将来要设计的处理器要执行的代码。
2.3 仿真环境配置
仿真环境是验证你设计的处理器是否正确的关键。咱们用两个工具:Verilator 和 Icarus Verilog,各有各的用处。
2.3.1 Verilator 安装与配置
Verilator 是一个高性能的 Verilog/SystemVerilog 仿真器。它把 HDL 代码转换成 C++ 代码,然后编译成可执行文件。速度比 iverilog 快一个数量级,适合跑大型测试。
安装方式:
# Ubuntu/Debian
sudo apt-get install verilator
# 或者从源码安装(推荐最新版)
git clone https://github.com/verilator/verilator
cd verilator
autoconf
./configure
make -j$(nproc)
sudo make install
验证安装:
verilator --version
Verilator 的使用方式和 iverilog 不太一样。它需要你写一个 C++ 的 wrapper 来驱动仿真。举个例子:
// 你的 Verilog 模块: top.v
module top;
initial begin
$display("Hello, RISC-V!");
$finish;
end
endmodule
// 编译命令
verilator --cc top.v --exe sim_main.cpp
make -j -C obj_dir -f Vtop.mk Vtop
// 运行
./obj_dir/Vtop
输出 "Hello, RISC-V!" 就说明环境通了。
$readmemh 的代码,结果发现 Verilator 默认不支持这个系统函数。需要在编译时加 --x-assign unique 和 --x-initial unique 参数才能正确处理 X 态。这个坑我踩过,你记一下。
2.3.2 Icarus Verilog 配置
Icarus Verilog 的配置就简单多了。装好之后,写一个 testbench,直接编译运行:
iverilog -o testbench.vvp testbench.v
vvp testbench.vvp
看波形的话,在 testbench 里加上:
initial begin
$dumpfile("waveform.vcd");
$dumpvars(0, testbench);
end
然后用 GTKWave 打开:
gtkwave waveform.vcd
波形出来了,你就可以开始调试你的处理器设计了。
2.4 整体工具链工作流程
下面这张图展示了咱们整个开发流程中,各个工具是怎么配合的:
你看,左边是硬件设计流程,右边是软件编译流程。中间的交汇点就是仿真器——你把编译好的 RISC-V 程序加载到处理器模型里,跑仿真,看波形,验证指令执行是否正确。
2.5 环境验证:跑一个最小系统
工具都装好了,咱们跑一个最小系统验证一下。写一个最简单的 RISC-V 汇编程序,让处理器计算 1+1:
# test.S
.text
.globl _start
_start:
li x1, 1
li x2, 1
add x3, x1, x2
ebreak
编译:
riscv32-unknown-elf-gcc -march=rv32imc -nostdlib -o test.elf test.S
然后写一个 Verilog testbench,把 test.elf 加载到指令存储器里,跑仿真。如果 x3 的值在仿真结束时是 2,说明整个工具链都通了。
- iverilog / Verilator 能编译你的 Verilog 代码
- riscv32-unknown-elf-gcc 能编译 C/汇编程序
- 仿真器能加载 ELF 文件并正确执行指令
- GTKWave 能打开 VCD 波形文件
这四步都走通了,你的开发环境就彻底配好了。后面咱们就可以专心搞微架构设计了。