32 位浮点数据格式: A = (- 1) S ×M ×2E-127。其中乘法器运算操作分4步进行。
浮点数据格式如下:
S:符号位 1Bit
Exp:阶码位 7Bits
Sig:尾码位 24Bits
(1) 确定结果的符号, 对A 和B 的符号位做异或操作。
(2) 计算阶码, 两数相乘, 结果的阶码是两数的阶码相加, 由于A 和B 都是偏移码, 因此需要从中减去偏移码值127,得到A 和B 的实际阶码, 然后相加, 得到的是结果的阶码, 再把他加上127, 变成偏移码。
(3) 尾数相乘,A 和B 的实际尾数分别为24位数, 即1×Ma 和1×Mb, 最高位1是隐藏位, 浮点数据格式只显示后23位, 所以尾数相乘结果应为一个48位的数据。
(4) 尾数规格化, 需要把尾数相乘的48位结果数据变成24 位的数据, 分3步进行:
① 如果乘积的整数位为01, 则尾数已经是规格化了;如果乘积的整数位为10, 11, 则需要把尾数右移1位, 同时把结果阶码加1。
② 对尾数进行舍入操作, 使尾数为24位, 包括整数的隐藏位。
③ 把结果数据处理为32位符合IEEE浮点数标准的结果。包括1位符号位, 8位结果阶码位, 结果23尾数位。
说明:
1.在Verilog实现中实现加减127可以通过第8Bit位取反并低位加1实现
2.本文不对浮点乘法运算算法说明,只描述具体实现
浮点数符号位流程图:
浮点数阶码与尾码位流程图:
贴Chisel生成的Verilog代码:
module float_mul(
input clock,
input reset,
input [31:0] io_a,
input [31:0] io_b,
input io_in_en,
output [31:0] io_c,
output io_out_en
);
reg [8:0] a_exp_r; // @[float_mul.scala 19:26]
reg [31:0] _RAND_0;
reg [8:0] b_exp_r; // @[float_mul.scala 20:26]
reg [31:0] _RAND_1;
reg _T_3; // @[Reg.scala 15:16]
reg [31:0] _RAND_2;
reg _T_4; // @[Reg.scala 15:16]
reg [31:0] _RAND_3;
reg sign; // @[Reg.scala 15:16]
reg [31:0] _RAND_4;
reg [8:0] exp_r; // @[float_mul.scala 24:24]
reg [31:0] _RAND_5;
reg [49:0] r_fra_r; // @[floa