cnn - 半精度浮点数乘法器

748 阅读2分钟

半精度浮点数乘法器

浮点乘除法其实很简单,

浮点数乘法:阶码相加、尾数相乘、结果规格化;

浮点数除法:尾数调整、阶码求差、尾数相除半精度浮点数乘法器

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