fpga系列 HDL:全连接层的浮点数加法器FADD实现

32 位 float 型的二进制存储

Layer 1 22 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 23 30 31 指数位E 符号位S 有效数字M(实际计算时会包含前边的“1”,存储时省略“1”) (-1)^S*M*2^E

FADD

  • 代码实现了两个 32 位浮点数的相加操作,遵循 IEEE 754 单精度浮点数标准。
// https://github.com/omarelhedaby/CNN-FPGA/blob/master/CNN-FPGA-Vivado/CNN-FPGA-Vivado.srcs/sources_1/imports/Integration%20first%20part/floatAdd.v
module floatAdd (floatA,floatB,sum);
	
input [31:0] floatA, floatB; // 两个 32 位的输入浮点数
output reg [31:0] sum; // 输出 32 位的结果

reg sign;                            // 结果的符号位
reg [7:0] exponent;                  // 结果的指数位
reg [22:0] mantissa;                 // 结果的尾数位(有效位)
reg [7:0] exponentA, exponentB;      // 分别存储两个浮点数的指数
reg [23:0] fractionA, fractionB, fraction; // 尾数(包括隐含的 1)
reg [7:0] shiftAmount; // 指数差,用于对齐             
reg cout;         

always @ (floatA or floatB) begin
	exponentA = floatA[30:23];
	exponentB = floatB[30:23];
	fractionA = {1'b1,floatA[22:0]};
	fractionB = {1'b1,floatB[22:0]}; 
	
	exponent = exponentA;

	if (floatA == 0) begin						//special case (floatA = 0)
		sum = floatB;
	end else if (floatB == 0) begin					//special case (floatB = 0)
		sum = floatA;
	end else if (floatA[30:0] == floatB[30:0] && floatA[31]^floatB[31]==1'b1) begin 
		sum=0; // 如果 A 和 B 的数值相同但符号不同,结果为 0
	end else begin
	    // 1.指数对齐
		if (exponentB > exponentA) begin
			shiftAmount = exponentB - exponentA;
			fractionA = fractionA >> (shiftAmount); // 将较小的指数对应的尾数右移
			exponent = exponentB; // 更新指数为较大的那个
		end else if (exponentA > exponentB) begin 
			shiftAmount = exponentA - exponentB;
			fractionB = fractionB >> (shiftAmount);
			exponent = exponentA;
		end
		// 2.尾数相加或相减(如果两个数的符号相同,则尾数相加。如果符号不同,则进行尾数相减。)
		if (floatA[31] == floatB[31]) begin			//same sign
			{cout,fraction} = fractionA + fractionB;
			if (cout == 1'b1) begin // 如果有进位,尾数右移并增加指数
				{cout,fraction} = {cout,fraction} >> 1;
				exponent = exponent + 1;
			end
			sign = floatA[31];
		end else begin						//different signs
			if (floatA[31] == 1'b1) begin
				{cout,fraction} = fractionB - fractionA;
			end else begin
				{cout,fraction} = fractionA - fractionB;
			end
			sign = cout;
			if (cout == 1'b1) begin
				fraction = -fraction;
			end else begin
			end
			// 3.规范化结果,找出有效数字M的第一个“1”
			if (fraction [23] == 0) begin
				if (fraction[22] == 1'b1) begin
					fraction = fraction << 1;
					exponent = exponent - 1;
				end else if (fraction[21] == 1'b1) begin
					fraction = fraction << 2;
					exponent = exponent - 2;
				end else if (fraction[20] == 1'b1) begin
					fraction = fraction << 3;
					exponent = exponent - 3;
				end else if (fraction[19] == 1'b1) begin
					fraction = fraction << 4;
					exponent = exponent - 4;
				end else if (fraction[18] == 1'b1) begin
					fraction = fraction << 5;
					exponent = exponent - 5;
				end else if (fraction[17] == 1'b1) begin
					fraction = fraction << 6;
					exponent = exponent - 6;
				end else if (fraction[16] == 1'b1) begin
					fraction = fraction << 7;
					exponent = exponent - 7;
				end else if (fraction[15] == 1'b1) begin
					fraction = fraction << 8;
					exponent = exponent - 8;
				end else if (fraction[14] == 1'b1) begin
					fraction = fraction << 9;
					exponent = exponent - 9;
				end else if (fraction[13] == 1'b1) begin
					fraction = fraction << 10;
					exponent = exponent - 10;
				end else if (fraction[12] == 1'b1) begin
					fraction = fraction << 11;
					exponent = exponent - 11;
				end else if (fraction[11] == 1'b1) begin
					fraction = fraction << 12;
					exponent = exponent - 12;
				end else if (fraction[10] == 1'b1) begin
					fraction = fraction << 13;
					exponent = exponent - 13;
				end else if (fraction[9] == 1'b1) begin
					fraction = fraction << 14;
					exponent = exponent - 14;
				end else if (fraction[8] == 1'b1) begin
					fraction = fraction << 15;
					exponent = exponent - 15;
				end else if (fraction[7] == 1'b1) begin
					fraction = fraction << 16;
					exponent = exponent - 16;
				end else if (fraction[6] == 1'b1) begin
					fraction = fraction << 17;
					exponent = exponent - 17;
				end else if (fraction[5] == 1'b1) begin
					fraction = fraction << 18;
					exponent = exponent - 18;
				end else if (fraction[4] == 1'b1) begin
					fraction = fraction << 19;
					exponent = exponent - 19;
				end else if (fraction[3] == 1'b1) begin
					fraction = fraction << 20;
					exponent = exponent - 20;
				end else if (fraction[2] == 1'b1) begin
					fraction = fraction << 21;
					exponent = exponent - 21;
				end else if (fraction[1] == 1'b1) begin
					fraction = fraction << 22;
					exponent = exponent - 22;
				end else if (fraction[0] == 1'b1) begin
					fraction = fraction << 23;
					exponent = exponent - 23;
				end
			end
		end
		mantissa = fraction[22:0];  // 提取尾数的低 23 位作为有效尾数
		sum = {sign, exponent, mantissa};  // 将符号、指数和尾数组合成最终结果		
	end		
end

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值