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