Verilog搭建神经网络学习记录,Day2:16位浮点加法

该文详细介绍了浮点数乘法的处理过程,包括符号位处理、指数位对齐和尾数计算的逻辑。在符号相同的情况下,直接相加;符号不同时,通过正负数尾数相减得到结果。文章还提供了Verilog代码实现,用于调整指数和处理进位,确保浮点数的正确运算。
摘要由CSDN通过智能技术生成

Day1:浮点数乘法

1.解决思路

1.1 符号位

若相加的两数符号相同:符号位保持不变
若相加的两数符号不同:先把两数的指数变一样后,再来比较尾数的大小,若正数的尾数大,符号为正;若负数的尾数大,符号为负

1.2指数位

首先将两数的指数变一样,这里采用的方式是取大的。接下来再根据两数尾数位的计算有无进位,以及结果第一个‘1’出现的位置来调整指数位的大小。

1.3尾数位

首先将两数的指数变一样,然后再来计算尾数。计算的过程中分成两种情况,符号相同和符号不同。若符号相同,直接将两数的 1.尾数 相加,如果计算结果没有产生进位,保留该结果;如果计算结果产生了进位,结果右移一位,指数加1 。若符号不同,用正数的1.尾数-负数的1.尾数,若够减,保留该结果;若不够减,将该结果取反。最后再根据结果中第一个‘1’出现的位置来调整结果左移的位数。

2.完整代码

`timescale 100 ns / 10 ps

module floatAdd (floatA,floatB,sum);
	
input [15:0] floatA, floatB;
output reg [15:0] sum;

reg sign;
reg signed [5:0] exponent; //fifth bit is sign
reg [9:0] mantissa;
reg [4:0] exponentA, exponentB;
reg [10:0] fractionA, fractionB, fraction;	//fraction = {1,mantissa}
reg [7:0] shiftAmount;
reg cout;

always @ (floatA or floatB) begin
	exponentA = floatA[14:10];//提取指数部分
	exponentB = floatB[14:10];
	fractionA = {1'b1,floatA[9:0]};
	fractionB = {1'b1,floatB[9:0]}; //提取尾数部分,并在左边添加个‘1’
	
	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[14:0] == floatB[14:0] && floatA[15]^floatB[15]==1'b1) begin //互为相反数的情况
		sum=0;
	end else begin
		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
		if (floatA[15] == floatB[15]) begin			//same sign
			{cout,fraction} = fractionA + fractionB;//符号相同直接加
			if (cout == 1'b1) begin
				{cout,fraction} = {cout,fraction} >> 1;//如果相加有进位,结果右移一位,指数加1
				exponent = exponent + 1;
			end
			sign = floatA[15];//符号不变
		end else begin						//different signs
			if (floatA[15] == 1'b1) begin
				{cout,fraction} = fractionB - fractionA;//如果A负数,B正数,用正数的尾数-负数的尾数
			end else begin
				{cout,fraction} = fractionA - fractionB;//如果B负数,A正数,用正数的尾数-负数的尾数
			end
			sign = cout;//够减,最终结果为正;不够减,最终结果为负
			if (cout == 1'b1) begin
				fraction = -fraction;
			end else begin
			end
            //判断第一个1出现的位置,并按此来调整指数
			if (fraction [10] == 0) begin
				if (fraction[9] == 1'b1) begin
					fraction = fraction << 1;
					exponent = exponent - 1;
				end else if (fraction[8] == 1'b1) begin
					fraction = fraction << 2;
					exponent = exponent - 2;
				end else if (fraction[7] == 1'b1) begin
					fraction = fraction << 3;
					exponent = exponent - 3;
				end else if (fraction[6] == 1'b1) begin
					fraction = fraction << 4;
					exponent = exponent - 4;
				end else if (fraction[5] == 1'b1) begin
					fraction = fraction << 5;
					exponent = exponent - 5;
				end else if (fraction[4] == 1'b1) begin
					fraction = fraction << 6;
					exponent = exponent - 6;
				end else if (fraction[3] == 1'b1) begin
					fraction = fraction << 7;
					exponent = exponent - 7;
				end else if (fraction[2] == 1'b1) begin
					fraction = fraction << 8;
					exponent = exponent - 8;
				end else if (fraction[1] == 1'b1) begin
					fraction = fraction << 9;
					exponent = exponent - 9;
				end else if (fraction[0] == 1'b1) begin
					fraction = fraction << 10;
					exponent = exponent - 10;
				end 
			end
		end
		mantissa = fraction[9:0];
		if(exponent[5]==1'b1) begin //exponent is negative
			sum = 16'b0000000000000000;
		end
		else begin
			sum = {sign,exponent[4:0],mantissa};
		end		
	end		
end

endmodule

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值