第二章:开发环境搭建

说实话,搭建开发环境这件事,看着简单,但坑真不少。我见过太多人卡在工具链编译这一步,一卡就是好几天。今天我就把这几年的经验掰开揉碎了讲给你听。

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-devlibmpfr-devlibgmp-dev这三个是编译GCC必须的数学库,少了它们后面会报一些莫名其妙的错。我曾经有一次就是漏了libmpc-dev,编译到一半卡住,查了半天才发现。

⚠️ 避坑指南: 别用Ubuntu 18.04以下的版本,GCC版本太老,编译RISC-V工具链时会遇到各种兼容性问题。我建议至少用20.04。

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指令了吗?比如addilwsw这些。这说明你的工具链已经能正常工作了。

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对SystemVerilog的支持有限。如果你用了很多SV的语法(比如interface、class),可能会编译不过。我遇到过几次这种情况,最后只能改回纯Verilog。所以写RTL时,尽量用可综合的Verilog子集。

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处理器的核心模块。记住,环境搭好了,后面才能顺风顺水。别嫌麻烦,这一步值得花时间。