半精度浮点数乘法器
浮点乘除法其实很简单,
浮点数乘法:阶码相加、尾数相乘、结果规格化;
浮点数除法:尾数调整、阶码求差、尾数相除半精度浮点数乘法器
1 阶码相加减
最高位异或得到符号位,指数位相加,阶码相加。 尾数和隐藏1进行拼接。
2 尾数相乘
相乘后位数为 乘数位数的两倍
3 规格化并进行舍入运算
判断尾数最高位进行判断,只存在左规格化,不存在右规格化。
尾数最高位为1,则左移相应位数,以此类推。对应的阶码进行减法。
尾数最高位为1的浮点数称为规格化数,如:0.110101×210。 此外,浮点数的规格化还和基数有关。 规格化数的特点,当尾数溢出大于1,需要进行右移。
4 判断溢出
浮点数的乘法运算的尾数不存在溢出,而只存在浮点数的阶码确定。
最后尽心拼接,只取尾数10位。
timescale 100 ns / 10 ps
module floatMult16 (floatA,floatB,product);
input [15:0] floatA, floatB;
output reg [15:0] product;
reg sign;
reg signed [5:0] exponent; //6th bit is the sign最高位为符号位
reg [9:0] mantissa; //有效精度,尾数
reg [10:0] fractionA, fractionB; //fraction = {1,mantissa}
reg [21:0] fraction; // 尾数相乘后变为22位,两倍
//特殊情况的处理
always @ (floatA or floatB) begin
if (floatA == 0 || floatB == 0) begin
product = 0;
end else begin
//最高位异或得到符号位
sign = floatA[15] ^ floatB[15];
//指数位相加 阶码相加
exponent = floatA[14:10] + floatB[14:10] - 5'd15 + 5'd2;
// 拼接, 加上最高的隐藏位1.
fractionA = {1'b1,floatA[9:0]};
fractionB = {1'b1,floatB[9:0]};
//尾数相乘
fraction = fractionA * fractionB;
//规格化浮点数的尾数形式为**00.1××…××**或**11.0××…××**。
// 规格化。 最高位为1,则左移。
if (fraction[21] == 1'b1) begin
fraction = fraction << 1;
exponent = exponent - 1;
end else if (fraction[20] == 1'b1) begin
fraction = fraction << 2;
exponent = exponent - 2;
end else if (fraction[19] == 1'b1) begin
fraction = fraction << 3;
exponent = exponent - 3;
end else if (fraction[18] == 1'b1) begin
fraction = fraction << 4;
exponent = exponent - 4;
end else if (fraction[17] == 1'b1) begin
fraction = fraction << 5;
exponent = exponent - 5;
end else if (fraction[16] == 1'b1) begin
fraction = fraction << 6;
exponent = exponent - 6;
end else if (fraction[15] == 1'b1) begin
fraction = fraction << 7;
exponent = exponent - 7;
end else if (fraction[14] == 1'b1) begin
fraction = fraction << 8;
exponent = exponent - 8;
end else if (fraction[13] == 1'b1) begin
fraction = fraction << 9;
exponent = exponent - 9;
end else if (fraction[12] == 1'b0) begin
fraction = fraction << 10;
exponent = exponent - 10;
end
// 取规格化后,10位。
mantissa = fraction[21:12];
if(exponent[5]==1'b1) begin //exponent is negative
product=16'b0000000000000000;
end
else begin
product = {sign,exponent[4:0],mantissa};
end
end
end
endmodule