1. RISC-V与FPGA概述
各位同学好,我是老李。做FPGA开发十几年了,从早期的Xilinx Virtex系列一路做到现在的Versal。这几年RISC-V火得一塌糊涂,我自己的团队也在几个项目里把RISC-V软核跑到了FPGA上。今天咱们就聊聊这个组合——RISC-V浮点运算单元在FPGA上的实现。
说实话,我第一次接触RISC-V是在2018年。当时一个客户要求用开源指令集做定制加速器,我还有点抵触。后来真做进去了才发现,这东西的简洁性和可扩展性,确实比ARM和x86更适合FPGA场景。
本章核心:搞懂RISC-V是什么、FPU为什么重要、FPGA开发怎么玩、以及怎么把开发环境搭起来。这四个点搞明白了,后面29章你才能跟得上。
1.1 RISC-V指令集架构简介
RISC-V,说白了就是一个开放的指令集标准。它不像ARM那样需要授权费,也不像x86那样闭源。你可以在任何芯片上实现它,甚至自己魔改。
为什么选RISC-V做FPU课程?我个人觉得有几点:
- 模块化设计——基础指令集(RV32I/RV64I)只有几十条指令,扩展指令集(M、F、D、Q等)按需添加。做FPU只需要关注F和D扩展。
- 简洁优雅——没有历史包袱,指令编码规整。我在项目中对比过RISC-V和ARM的浮点指令,RISC-V的译码逻辑能省30%左右的LUT。
- 生态成熟——GCC、LLVM、Linux、FreeRTOS都支持。你写个C程序,编译出来就能在FPGA上跑。
嗯,这里要注意:RISC-V的浮点扩展分为单精度(F扩展)和双精度(D扩展)。咱们这门课主要讲F扩展,因为单精度在FPGA上资源消耗更可控,适合教学。双精度的原理是一样的,只是位宽翻倍。
我的经验:刚开始学RISC-V时,别急着看特权架构手册。先把非特权架构手册的第二章(整数指令)和第六章(浮点指令)啃下来,就够用了。我当年就是被那几百页手册吓到了,其实核心内容就那几十页。
1.2 浮点运算单元(FPU)的作用
FPU是干啥的?简单说就是处理小数的加减乘除、开方、比较这些运算。CPU里的整数单元只能处理整数,遇到3.14×2.718这种计算就抓瞎了。
你想想看,如果没有FPU,用软件模拟浮点运算是什么体验?一个浮点乘法可能要几十条整数指令,跑起来慢得让人抓狂。我在一个图像处理项目里试过,纯软件浮点处理一帧图像要200ms,加上FPU硬件加速后直接降到5ms——40倍的差距。
FPU在RISC-V里的位置是这样的:
+------------------+
| RISC-V Core |
| (RV32IMAFD) |
| +------------+ |
| | Integer | |
| | Pipeline | |
| +------------+ |
| +------------+ |
| | FPU | | <-- 咱们要实现的
| | (F/D ext) | |
| +------------+ |
+------------------+
FPU的核心功能包括:
- 浮点加减法——对阶、尾数运算、规格化、舍入
- 浮点乘除法——尾数乘法/除法、指数相加/相减
- 浮点开方——牛顿迭代法或数字递归算法
- 浮点比较与转换——整数↔浮点、单精度↔双精度
我曾经踩过的坑:FPU的舍入模式处理。IEEE 754定义了5种舍入模式,很多初学者只实现了就近舍入。结果在某个科学计算项目里,客户要求必须支持向零舍入,我不得不返工。建议一开始就把舍入模式接口留好。
1.3 FPGA开发流程概述
FPGA开发跟软件完全不一样。软件是写代码→编译→运行,出了问题改代码再编译。FPGA是写代码→综合→实现→生成比特流→下载→调试,一个周期下来可能几个小时。
我习惯把FPGA开发流程分成这几步:
- 架构设计——确定模块划分、接口定义、时序目标。这一步花的时间越多,后面返工越少。
- RTL编码——用Verilog或VHDL描述硬件逻辑。咱们这门课用Verilog,因为RISC-V生态里Verilog居多。
- 功能仿真——用testbench验证逻辑正确性。记住,仿真通过不代表上板没问题。
- 逻辑综合——把RTL代码映射到FPGA的LUT、FF、DSP等资源上。
- 布局布线——把综合后的网表放到FPGA的物理位置上,连好线。
- 时序分析——检查能不能跑在目标频率上。不满足就回去改代码或约束。
- 生成比特流——最后一步,生成配置文件烧录到FPGA里。
下面这张图展示了FPGA开发的核心流程,我特意把时序分析标红了——这是最容易出问题的地方:
我的建议:初学者最容易犯的错误是跳过仿真直接上板。我曾经带过一个实习生,写了三天代码,综合通过就直接下载到板子上,结果LED死活不亮。查了两天才发现是复位逻辑写反了。如果先做仿真,10分钟就能发现这个问题。
1.4 开发环境搭建(Vivado/Quartus)
工欲善其事,必先利其器。FPGA开发环境主要有两家:Xilinx的Vivado和Intel的Quartus。咱们这门课以Vivado为主,因为RISC-V生态里Xilinx的FPGA用得最多。但Quartus的流程大同小异,学会了Vivado,Quartus上手也快。
环境搭建分几步:
1.4.1 安装Vivado
去Xilinx官网下载Vivado HLx版本。我个人建议装WebPACK版,免费且功能够用。注意选对版本——Vivado 2023.1之后的版本对RISC-V工具链支持更好。
安装时记得勾选这些组件:
- Vivado HL System Edition
- Devices(选你手头板子的型号,比如Artix-7、Kintex-7)
- Vitis(可选,做嵌入式开发时有用)
注意:Vivado安装包很大,20GB起步。硬盘空间留够,我建议至少100GB空闲。另外Windows下安装路径不要有中文和空格,否则综合时会报一些莫名其妙的错误。
1.4.2 安装RISC-V工具链
咱们需要GCC交叉编译器来编译RISC-V的测试程序。推荐用官方的riscv-gnu-toolchain:
# 克隆仓库
git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
# 配置(只编译64位,带浮点扩展)
./configure --prefix=/opt/riscv --with-arch=rv64imafd
# 编译(这步很慢,去喝杯咖啡)
make -j$(nproc)
编译完成后,把/opt/riscv/bin加到PATH里。验证一下:
riscv64-unknown-elf-gcc --version
# 应该能看到版本信息
嗯,这里要提醒一下:第一次编译工具链大概需要1-2小时,取决于你的机器性能。我建议用预编译的二进制包,省时间。SiFive官网有提供。
1.4.3 搭建仿真环境
Vivado自带仿真器(xsim),但说实话不太好用。我个人习惯用Verilator或ModelSim。Verilator速度快,适合跑大型测试;ModelSim调试方便,适合单步跟踪。
如果你用ModelSim,记得在Vivado里设置好路径:
Tools → Settings → Tool Settings → 3rd Party Simulators → ModelSim Simulator
# 填上ModelSim的安装路径
我的经验:刚开始别追求完美环境。Vivado自带的xsim足够完成咱们课程的所有实验。等后面做复杂SoC验证时,再考虑换Verilator。我见过太多同学花了两天搭环境,结果代码一行没写——本末倒置了。
1.4.4 验证环境
环境搭好后,写个最简单的Verilog模块测试一下:
module test_fpu(
input wire clk,
input wire rst_n,
input wire [31:0] a,
input wire [31:0] b,
output reg [31:0] result
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
result <= 32'd0;
else
result <= a + b; // 简单的加法
end
endmodule
在Vivado里新建工程,添加这个文件,跑一下综合和仿真。如果都能通过,恭喜你,环境搭好了。
最后,我把常用工具整理成了一张表,方便你对照:
| 工具 | 用途 | 推荐版本 | 备注 |
|---|---|---|---|
| Vivado | 综合、实现、生成比特流 | 2023.1+ | WebPACK版免费 |
| ModelSim/Questa | RTL仿真 | 2020.4+ | Intel版免费 |
| riscv-gnu-toolchain | RISC-V交叉编译 | 最新master | 编译较慢,可用预编译包 |
| Verilator | 高性能仿真 | 5.0+ | 适合回归测试 |
| GTKWave | 波形查看 | 最新版 | 轻量级,免费 |
好了,第一章的内容就这些。记住:RISC-V的简洁性让它天生适合FPGA实现,FPU是提升浮点性能的关键,FPGA开发流程要严格遵守,环境搭建一次搞定后面省心。把这些基础打牢,后面咱们就开始动手写FPU的RTL代码了。
公众号:蓝海资料掘金营,微信deep3321