第二章:开发环境搭建
说实话,搭建开发环境这件事,看着简单,但坑真不少。我见过太多人卡在工具链编译这一步,一卡就是好几天。今天我就把这几年的经验掰开揉碎了讲给你听。
2.1 Linux环境配置
做RISC-V开发,Linux是绕不开的。我个人习惯用Ubuntu 20.04 LTS,稳定,社区活跃,遇到问题好搜答案。当然你用CentOS、Debian也行,但包管理器的命令你得自己调整一下。
先装基础依赖包,别漏了:
sudo apt-get update
sudo apt-get install -y \
autoconf automake autotools-dev curl \
libmpc-dev libmpfr-dev libgmp-dev \
gawk build-essential bison flex \
texinfo gperf libtool patchutils \
bc zlib1g-dev libexpat-dev \
git python3 python3-pip
嗯,这里要注意,libmpc-dev、libmpfr-dev、libgmp-dev这三个是编译GCC必须的数学库,少了它们后面会报一些莫名其妙的错。我曾经有一次就是漏了libmpc-dev,编译到一半卡住,查了半天才发现。
2.2 RISC-V GNU工具链编译与安装
工具链是整个开发流程的基石。说白了,没有它,你写的C代码就变不成RISC-V机器码。RISC-V官方提供了完整的GNU工具链源码,我们得自己编译。
先克隆源码:
git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
这一步会下载很多子模块,包括binutils、gcc、glibc、newlib等。网络不好的话,建议用代理或者直接下载release包。我当年第一次克隆时,等了一个多小时才下完。
配置编译选项:
./configure --prefix=/opt/riscv --with-arch=rv64gc --with-abi=lp64d
make -j$(nproc)
这里解释一下几个关键参数:
--prefix:安装路径,我习惯放在/opt/riscv下,方便管理--with-arch=rv64gc:指定架构,rv64表示64位,g表示通用扩展(IMAFD),c表示压缩指令扩展--with-abi=lp64d:ABI接口,lp64d表示64位长指针,支持双精度浮点
编译时间取决于你的机器性能。我用的i7-10700,8核16线程,大概花了40分钟。如果你用虚拟机,建议至少分配4核8G内存。
/opt/riscv/bin加到PATH里。我习惯在~/.bashrc里加一行:export PATH=/opt/riscv/bin:$PATH。这样每次打开终端就能直接用riscv64-unknown-elf-gcc了。
验证安装是否成功:
riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (GCC) 12.2.0
# 如果能正常输出版本号,说明安装成功
写个简单的测试程序:
// test.c
int main() {
int a = 1, b = 2;
int c = a + b;
return c;
}
// 编译
riscv64-unknown-elf-gcc -O2 -march=rv64gc -o test test.c
// 反汇编看看
riscv64-unknown-elf-objdump -d test
看到RISC-V指令了吗?比如addi、lw、sw这些。这说明你的工具链已经能正常工作了。
2.3 Verilog仿真器选择
仿真器是验证环节的核心工具。市面上选择不少,但作为个人学习和开源项目,我主要推荐两个:Icarus Verilog和Verilator。
| 特性 | Icarus Verilog (iverilog) | Verilator |
|---|---|---|
| 语言支持 | Verilog-2005, 部分SystemVerilog | Verilog-2005, SystemVerilog (部分) |
| 仿真方式 | 解释执行 | 编译成C++再执行 |
| 速度 | 较慢 | 极快(比iverilog快10-100倍) |
| 调试能力 | 强,支持VCD波形 | 中等,支持VCD/FST波形 |
| 学习曲线 | 平缓 | 较陡,需要懂C++ |
| 适用场景 | 小规模设计、教学 | 大规模设计、性能要求高 |
我个人建议:刚开始学RISC-V处理器设计时,先用Icarus Verilog。为什么?因为调试方便,出错了能快速定位。等你把核心逻辑跑通了,再切换到Verilator做性能测试和回归验证。
2.3.1 安装Icarus Verilog
sudo apt-get install iverilog gtkwave
就这么简单。gtkwave是波形查看工具,配合iverilog使用,能看到信号随时间的变化。
写个简单的测试:
// counter.v
module counter (
input clk,
input rst_n,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'b0;
else
count <= count + 1;
end
endmodule
// testbench
module tb_counter;
reg clk, rst_n;
wire [3:0] count;
counter u0 (.clk(clk), .rst_n(rst_n), .count(count));
initial begin
clk = 0;
forever #5 clk = ~clk; // 100MHz时钟
end
initial begin
rst_n = 0;
#20 rst_n = 1;
#200 $finish;
end
initial begin
$dumpfile("counter.vcd");
$dumpvars(0, tb_counter);
end
endmodule
// 编译仿真
iverilog -o counter_tb counter.v tb_counter.v
vvp counter_tb
gtkwave counter.vcd // 查看波形
2.3.2 安装Verilator
Verilator安装稍微麻烦一点,建议从源码编译:
# 安装依赖
sudo apt-get install -y perl python3 make g++ \
libfl-dev libfl2
# 克隆源码
git clone https://github.com/verilator/verilator
cd verilator
# 编译安装
autoconf
./configure --prefix=/opt/verilator
make -j$(nproc)
sudo make install
# 设置环境变量
export PATH=/opt/verilator/bin:$PATH
Verilator的仿真方式跟iverilog不同,它会把Verilog代码编译成C++,然后你写一个C++的testbench来驱动:
// 先编译Verilog为C++
verilator --cc counter.v --exe sim_main.cpp
// 编译C++并生成可执行文件
make -j$(nproc) -C obj_dir -f Vcounter.mk Vcounter
// 运行仿真
./obj_dir/Vcounter
说实话,Verilator的学习曲线确实陡一些。但它的速度优势太明显了。我在做RISC-V处理器验证时,用iverilog跑一个完整的测试用例要3分钟,换成Verilator后只要10秒。你想想看,做回归测试时,这个差距意味着什么。
- 学习阶段:用Icarus Verilog + GTKWave,调试方便
- 项目阶段:用Verilator,性能是关键
- 两者都装,不冲突。我电脑上两个都有,根据场景切换
好了,环境搭建就讲到这里。下一章我们开始真正动手写RISC-V处理器的核心模块。记住,环境搭好了,后面才能顺风顺水。别嫌麻烦,这一步值得花时间。