3. RISC-V软核架构总览

好,咱们正式开始动手。这一章说白了就是“把枪擦亮”。你架构设计得再漂亮,没有一套顺手的工具链,一切都是纸上谈兵。我个人习惯是先把环境搞利索了,再开始写代码,不然调试的时候会非常痛苦。

咱们这门课用的是RISC-V软核,所以工具链分三块:FPGA厂商的IDE(Vivado或Quartus)、RISC-V的GCC交叉编译器、以及仿真工具。下面我挨个说。

3.1 FPGA开发环境:Vivado与Quartus

选哪个?看你的FPGA芯片。Xilinx(AMD)的用Vivado,Intel(Altera)的用Quartus。我两边都用过,说实话,Vivado的时序分析更强大,Quartus的编译速度有时候更快。但咱们做RISC-V软核,两者都能胜任。

3.1.1 Vivado安装要点

  • 版本选择:我个人建议用2020.1到2022.2之间的版本。太新的版本对操作系统要求高,太老的版本对RISC-V IP支持不好。
  • 安装包:去AMD官网下载“Vivado HLx”完整版。别下WebPACK,那个功能受限。
  • 磁盘空间:至少预留80GB。嗯,你没看错,Vivado安装完就30多GB,加上后续工程,80GB是底线。
  • License:申请免费的WebPACK License就够了,咱们做软核用不到那些高级IP。
避坑指南:我曾经在Windows上安装Vivado 2021.1,结果死活打不开。后来发现是路径里有中文。Vivado对中文路径支持极差,建议全部用英文路径,包括用户名。

3.1.2 Quartus安装要点

  • 版本选择:Quartus Prime Pro版支持最新的Agilex系列,但咱们用Standard版就够了,兼容Cyclone V、Arria 10这些主流芯片。
  • 安装流程:比Vivado简单,一路Next就行。注意要勾选“Device”对应的芯片系列,不然综合时会报错。
  • ModelSim集成:Quartus自带免费的ModelSim Starter版,但功能有限。我建议单独装ModelSim SE或Questa。
对比项 Vivado Quartus
厂商 AMD (Xilinx) Intel (Altera)
主流版本 2020.1 - 2022.2 Prime Standard 20.1+
仿真器集成 XSIM (自带) ModelSim (自带Starter版)
时序引擎 强大,支持多模式分析 够用,但多角分析稍弱
脚本支持 Tcl (非常完善) Tcl (基本够用)
安装包大小 ~30GB ~15GB

3.2 RISC-V GCC工具链搭建

这是关键。咱们的软核跑的是RISC-V指令,普通x86的GCC编译出来的程序它不认识。必须用交叉编译器。

3.2.1 预编译工具链(推荐新手)

去SiFive官网或者GitHub上搜“riscv-gnu-toolchain”,下载预编译好的版本。我推荐用riscv64-unknown-elf-gcc这个系列。

  • Linux:下载后解压到/opt/riscv,然后配置环境变量。
  • Windows:用MSYS2或者WSL。我个人强烈建议在Linux或WSL下开发,Windows下的工具链坑比较多。
# 解压到指定目录
sudo tar -xvf riscv64-unknown-elf-gcc-xxx.tar.gz -C /opt/riscv

# 配置环境变量(加到 ~/.bashrc 里)
export PATH=$PATH:/opt/riscv/bin

# 验证安装
riscv64-unknown-elf-gcc --version

3.2.2 源码编译(进阶)

如果你需要定制优化选项,或者想支持更多扩展指令集(比如乘除法M扩展、原子操作A扩展),那就自己编译。

git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv --with-arch=rv32imc --with-abi=ilp32
make -j$(nproc)

这里--with-arch=rv32imc表示生成32位RISC-V,支持整数、乘除法和压缩指令。咱们的软核如果只跑基础指令,用rv32i就够了。

小技巧:编译一次大概要1-2小时,取决于你的机器。我建议用make -j4并行编译,能快不少。另外,记得先装好依赖库:sudo apt-get install autoconf automake libmpc-dev libmpfr-dev libgmp-dev。

3.3 仿真工具:VCS与ModelSim

仿真,是数字IC设计的生命线。你想想看,代码直接烧到FPGA里调试,效率多低?一个bug改一天。仿真环境搭好了,几分钟就能跑一轮。

3.3.1 ModelSim/Questa(FPGA常用)

ModelSim是Mentor(现属Siemens)的产品,在FPGA领域用得最多。Quartus自带的是Starter版,有代码行数限制(一般10万行以内)。咱们的RISC-V软核代码量不大,Starter版够用。

  • 启动方式:命令行模式最灵活。图形界面用于看波形。
  • 常用命令:vlib建库,vlog编译Verilog,vsim启动仿真。
# 基本流程
vlib work
vlog -sv core.sv tb_core.sv
vsim -c -do "run -all; quit" work.tb_core

3.3.2 VCS(ASIC/高端FPGA常用)

VCS是Synopsys的旗舰仿真器,速度快,容量大。但它是商业软件,License很贵。咱们课程里用ModelSim为主,但我会提一下VCS的用法,毕竟很多公司用这个。

# VCS编译与仿真
vcs -full64 -sverilog core.sv tb_core.sv -o simv
./simv -l run.log
核心区别:VCS编译速度比ModelSim快,尤其是大型设计。但ModelSim的波形调试更直观。我个人习惯:写代码时用ModelSim快速迭代,做回归测试时用VCS跑批量。

3.4 本章知识体系总览

下面这张图,把咱们这一章的核心逻辑串起来了。你搭建环境时,心里要有这个框架。

开发环境搭建知识体系 FPGA IDE RISC-V GCC 仿真工具 Vivado Quartus 预编译工具链 源码编译 ModelSim VCS 安装配置 安装配置 下载/解压/环境变量 configure/make vlib/vlog/vsim vcs/simv 最终产出:可综合的RISC-V软核 + 仿真验证环境

3.5 环境验证:跑通第一个Hello World

环境搭好了,怎么知道对不对?写个最简单的C程序,编译成RISC-V机器码,然后用仿真器加载到咱们的软核里跑。

// hello.c
int main() {
    volatile int *uart = (int *)0x10000000;
    *uart = 'H';
    *uart = 'e';
    *uart = 'l';
    *uart = 'l';
    *uart = 'o';
    return 0;
}
# 编译
riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -nostdlib -T link.ld hello.c -o hello.elf

# 反汇编,看看生成的指令对不对
riscv64-unknown-elf-objdump -d hello.elf

如果能看到lui、sw这些RISC-V指令,说明工具链没问题。下一步就是把hello.elf转成内存初始化文件(.hex或.mif),加载到FPGA的Block RAM里,跑仿真看波形。

小提示:第一次跑通Hello World的时候,那种成就感是很爽的。我记得我第一次在ModelSim里看到UART口输出'Hello'的波形时,激动得差点拍桌子。这就是硬件工程师的浪漫吧。

3.6 常见问题与解决

  • Vivado编译报错“CRITICAL WARNING”:多半是时序约束没加。咱们后面专门有一章讲时序约束,先忽略这些警告,能综合通过就行。
  • GCC编译报错“cannot find -lgcc”:链接脚本里少了libgcc。在链接脚本里加上-lgcc就行。
  • ModelSim仿真卡死:检查代码里有没有死循环,或者时钟有没有正确翻转。我曾经有一次忘了写#10的时钟周期,仿真器直接卡在0时刻。