F扩展浮点加减正确
F扩展(Float)为RISC-V添加IEEE 754单精度(32位)浮点运算支持,包括浮点加载/存储、算术运算、比较、转换等指令。F扩展引入了32个浮点寄存器(f0-f31)和独立的fcsr控制寄存器。
| F扩展指令组 | 指令 | 数量 |
|---|---|---|
| 加载/存储 | FLW, FSW | 2 |
| 算术 | FADD.S, FSUB.S, FMUL.S, FDIV.S | 4 |
| 融合乘加 | FMADD.S, FMSUB.S, FNMSUB.S, FNMADD.S | 4 |
| 比较 | FEQ.S, FLT.S, FLE.S | 3 |
| 转换 | FCVT.W.S, FCVT.S.W, FMV.X.W, FMV.W.X | 4 |
| 其他 | FSGNJ.S, FMIN.S, FMAX.S, FCLASS.S | 5 |
RISC-V使用NaN-Boxing将32位浮点值扩展到64位:高32位全1,低32位是实际的float值。这样F和D扩展可以使用相同的寄存器文件。
// Lesson 25: RVF Single-Precision Float Add/Sub
module rvf_add_sub(input wire clk, rst_n, start, is_sub,
input wire [31:0] fp_a, fp_b, output reg [31:0] fp_result, output reg done);
wire sign_a=fp_a[31]; wire [7:0] exp_a=fp_a[30:23];
wire [23:0] man_a=(exp_a!=0)?{1'b1,fp_a[22:0]}:{1'b0,fp_a[22:0]};
wire sign_b_eff=is_sub?~fp_b[31]:fp_b[31]; wire [7:0] exp_b=fp_b[30:23];
wire [23:0] man_b=(exp_b!=0)?{1'b1,fp_b[22:0]}:{1'b0,fp_b[22:0]};
wire a_larger=(exp_a>exp_b)||(exp_a==exp_b&&man_a>=man_b);
wire [7:0] exp_big=a_larger?exp_a:exp_b, exp_small=a_larger?exp_b:exp_a;
wire [23:0] man_big=a_larger?man_a:man_b, man_small=a_larger?man_b:man_a;
wire [7:0] shift_amt=exp_big-exp_small;
wire [24:0] man_aligned={1'b0,man_small}>>shift_amt;
wire same_sign=(sign_a==sign_b_eff);
wire [24:0] man_result=same_sign?({1'b0,man_big}+man_aligned):({1'b0,man_big}-man_aligned);
wire result_sign=same_sign?sign_a:(a_larger?sign_a:sign_b_eff);
wire [24:0] man_norm1=man_result[24]?(man_result>>1):man_result;
wire [7:0] exp_norm1=man_result[24]?(exp_big+1):exp_big;
reg [4:0] lz; reg [24:0] man_final; reg [7:0] exp_final; reg sign_final;
always @(*) begin lz=0; man_final=man_norm1; exp_final=exp_norm1; sign_final=result_sign;
if(!man_final[23]) begin if(man_final[22])lz=1; else if(man_final[21])lz=2;
else if(man_final[20])lz=3; else if(man_final[19])lz=4; else if(man_final[18])lz=5;
else if(man_final[17])lz=6; else if(man_final[16])lz=7; else if(man_final[15])lz=8; else lz=9; end
if(lz>0) begin man_final=man_final<<lz; exp_final=exp_final-lz; end
if(man_final==0) begin sign_final=0; exp_final=0; end end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin fp_result<=0; done<=0; end
else if(start) begin fp_result<={sign_final,exp_final,man_final[22:0]}; done<=1; end
else done<=0; end
endmodule
| 领域 | 精度需求 | F扩展是否足够 |
|---|---|---|
| 图形渲染 | 单精度 | 是(F扩展足够) |
| 机器学习推理 | FP16/BF16 | F扩展+自定义 |
| 科学计算 | 双精度 | 需要D扩展 |
| 信号处理 | 单精度 | 是 |
| 游戏物理 | 单精度 | 是 |
大多数AI/ML推理工作负载使用FP16或BF16精度,RVF扩展提供了基础,结合自定义指令可以实现更高效的推理。
掌握本课内容需要结合理论学习和动手实践:
| 工具 | 用途 | 安装 |
|---|---|---|
| Verilator 5.020 | Verilog编译仿真 | sudo apt install verilator |
| iverilog | 轻量仿真 | sudo apt install iverilog |
| GTKWave | 波形查看 | sudo apt install gtkwave |
| RISC-V GCC | 交叉编译 | apt install gcc-riscv64-unknown-elf |
| QEMU | 系统仿真 | apt install qemu-system-misc |
本课程推荐以下开发工具链:
| 工具 | 用途 | 安装命令 |
|---|---|---|
| Verilator | Verilog编译/仿真 | sudo apt install verilator |
| iverilog | 轻量Verilog仿真 | sudo apt install iverilog |
| GTKWave | 波形查看 | sudo apt install gtkwave |
| RISC-V GCC | 交叉编译 | apt install gcc-riscv64-unknown-elf |
| QEMU | 系统仿真 | apt install qemu-system-misc |
| Spike | ISA模拟器 | 从源码编译 |
# 编译本课Verilog代码
cd verilog/
iverilog -o tb_test *.v
vvp tb_test
# Verilator lint检查
verilator --lint-only -Wno-BLKLOOPINIT *.v
# 应无Error输出
本课是第25课,在整体课程中承上启下。每一课都构建在前一课的基础上,建议按顺序学习。