|
@@ -13,56 +13,48 @@ module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
|
|
|
output reg [N-1:0] output_z;
|
|
output reg [N-1:0] output_z;
|
|
|
|
|
|
|
|
reg [K-1:0] a_m0, b_m0; // mantissa
|
|
reg [K-1:0] a_m0, b_m0; // mantissa
|
|
|
- reg [K-1:0] a_m1, b_m1, z_m2;
|
|
|
|
|
|
|
+ reg [K-1:0] a_m1, b_m1, z_m2, z_m3;
|
|
|
|
|
|
|
|
reg [K*2-1:0] z_m1a, z_m1b, z_m1z; // Double mantissa
|
|
reg [K*2-1:0] z_m1a, z_m1b, z_m1z; // Double mantissa
|
|
|
- reg z_m1s;
|
|
|
|
|
|
|
+ reg z_m1s, z_m2s;
|
|
|
|
|
|
|
|
reg [M-1:0] a_e0, b_e0; // exponent
|
|
reg [M-1:0] a_e0, b_e0; // exponent
|
|
|
- reg [M-1:0] z_e1, z_e2;
|
|
|
|
|
|
|
+ reg [M-1:0] z_e1, z_e2, z_e3;
|
|
|
|
|
|
|
|
reg a_s0, b_s0; // sign
|
|
reg a_s0, b_s0; // sign
|
|
|
- reg a_s1, b_s1, z_s1, z_s2;
|
|
|
|
|
|
|
+ reg a_s1, b_s1, z_s1, z_s2, z_s3;
|
|
|
|
|
|
|
|
grater_state greater; // 01 for a, 10 for b, 11 for both and 00 for neither
|
|
grater_state greater; // 01 for a, 10 for b, 11 for both and 00 for neither
|
|
|
reg [M:0] abs; // For the absolute difference between exponents
|
|
reg [M:0] abs; // For the absolute difference between exponents
|
|
|
|
|
|
|
|
always_comb begin
|
|
always_comb begin
|
|
|
- output_z = {z_s2, z_e2, z_m2};
|
|
|
|
|
|
|
+ output_z = {z_s3, z_e3, z_m3};
|
|
|
z_m1a = {a_m1, {K{1'b0}}};
|
|
z_m1a = {a_m1, {K{1'b0}}};
|
|
|
z_m1b = {b_m1, {K{1'b0}}};
|
|
z_m1b = {b_m1, {K{1'b0}}};
|
|
|
|
|
|
|
|
- // If a has the bigger exponent
|
|
|
|
|
- if (greater == greater_a)
|
|
|
|
|
- begin
|
|
|
|
|
- // If the signs are the same then add
|
|
|
|
|
- if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1a+(z_m1b >> abs - 2);
|
|
|
|
|
- // If they are different then subtract
|
|
|
|
|
- else {z_m1s, z_m1z} = z_m1a-(z_m1b >> abs - 2);
|
|
|
|
|
|
|
+ case (greater)
|
|
|
|
|
+ greater_a: begin
|
|
|
|
|
+ if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1a + (z_m1b >> (abs - 1));
|
|
|
|
|
+ else {z_m1s, z_m1z} = z_m1a - (z_m1b >> (abs - 1));
|
|
|
end
|
|
end
|
|
|
- // If b has the bigger exponent
|
|
|
|
|
- else if (greater == greater_b)
|
|
|
|
|
- begin
|
|
|
|
|
- // If the signs are the same then add
|
|
|
|
|
- if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1b+(z_m1a >> abs - 2);
|
|
|
|
|
- // If they are different then subtract
|
|
|
|
|
- else {z_m1s, z_m1z} = z_m1b-(z_m1a >> abs - 2);
|
|
|
|
|
|
|
+ greater_b: begin
|
|
|
|
|
+ if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1b + (z_m1a >> (abs - 1));
|
|
|
|
|
+ else {z_m1s, z_m1z} = z_m1b - (z_m1a >> (abs - 1));
|
|
|
end
|
|
end
|
|
|
- // If the exponents are equal
|
|
|
|
|
- else
|
|
|
|
|
- begin
|
|
|
|
|
|
|
+ equal_ab: begin
|
|
|
// If the signs are the same then add
|
|
// If the signs are the same then add
|
|
|
if (a_s1 == b_s1) {z_m1s, z_m1z} = (z_m1a + z_m1b) >> 1;
|
|
if (a_s1 == b_s1) {z_m1s, z_m1z} = (z_m1a + z_m1b) >> 1;
|
|
|
|
|
+ // If the signs are different then subtract
|
|
|
|
|
+ else begin
|
|
|
|
|
+ // First checking which has the bigger mantissa
|
|
|
|
|
+ if (a_m1 > b_m1) {z_m1s, z_m1z} = z_m1a - z_m1b;
|
|
|
// If the signs are different then subtract
|
|
// If the signs are different then subtract
|
|
|
- else
|
|
|
|
|
- begin
|
|
|
|
|
- // First checking which has the bigger mantissa
|
|
|
|
|
- if (a_m1 > b_m1) {z_m1s, z_m1z} = z_m1a-z_m1b;
|
|
|
|
|
- else if (b_m1 > a_m1) {z_m1s, z_m1z} = z_m1b-z_m1a;
|
|
|
|
|
- // If the mantissa are the same as well then the result should be 0
|
|
|
|
|
- else {z_m1s, z_m1z} = 0;
|
|
|
|
|
- end
|
|
|
|
|
|
|
+ else if (b_m1 > a_m1) {z_m1s, z_m1z} = z_m1b - z_m1a;
|
|
|
|
|
+ // If the mantissa are the same as well then the result should be 0
|
|
|
|
|
+ else {z_m1s, z_m1z} = 0;
|
|
|
|
|
+ end
|
|
|
end
|
|
end
|
|
|
|
|
+ endcase
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
always_ff @(posedge clk)
|
|
always_ff @(posedge clk)
|
|
@@ -91,18 +83,18 @@ module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
|
|
|
if (a_e0 > b_e0)
|
|
if (a_e0 > b_e0)
|
|
|
begin
|
|
begin
|
|
|
greater <= greater_a;
|
|
greater <= greater_a;
|
|
|
- abs <= a_e0 - b_e0 - 1;
|
|
|
|
|
|
|
+ abs <= a_e0 - b_e0;
|
|
|
z_s1 <= a_s0;
|
|
z_s1 <= a_s0;
|
|
|
- z_e1 <= a_e0;
|
|
|
|
|
|
|
+ z_e1 <= a_e0 + 1;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
// If input_a has the bigger exponent then flag it with greater and find the absolute difference
|
|
// If input_a has the bigger exponent then flag it with greater and find the absolute difference
|
|
|
else if (b_e0 > a_e0)
|
|
else if (b_e0 > a_e0)
|
|
|
begin
|
|
begin
|
|
|
greater <= greater_b;
|
|
greater <= greater_b;
|
|
|
- abs <= b_e0 - a_e0 - 1;
|
|
|
|
|
|
|
+ abs <= b_e0 - a_e0;
|
|
|
z_s1 <= b_s0;
|
|
z_s1 <= b_s0;
|
|
|
- z_e1 <= b_e0;
|
|
|
|
|
|
|
+ z_e1 <= b_e0 + 1;
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
// If the inputs have equal exponent
|
|
// If the inputs have equal exponent
|
|
@@ -110,7 +102,7 @@ module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
|
|
|
begin
|
|
begin
|
|
|
greater <= equal_ab;
|
|
greater <= equal_ab;
|
|
|
abs <= 0;
|
|
abs <= 0;
|
|
|
- z_e1 <= a_e0;
|
|
|
|
|
|
|
+ z_e1 <= a_e0 + 1;
|
|
|
// Assigning the overall sign based on the difference between the mantissa
|
|
// Assigning the overall sign based on the difference between the mantissa
|
|
|
if (a_m0 > b_m0) z_s1 <= a_s0;
|
|
if (a_m0 > b_m0) z_s1 <= a_s0;
|
|
|
else if (b_m0 > a_m0) z_s1 <= b_s0;
|
|
else if (b_m0 > a_m0) z_s1 <= b_s0;
|
|
@@ -120,26 +112,26 @@ module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
|
|
|
// Condition for overflow is that it sets the output to the larger input
|
|
// Condition for overflow is that it sets the output to the larger input
|
|
|
if (abs > K) // Shifting by N-1-M would give 0
|
|
if (abs > K) // Shifting by N-1-M would give 0
|
|
|
begin
|
|
begin
|
|
|
- z_m2 <= (greater == greater_a) ? a_m1 : b_m1;
|
|
|
|
|
-
|
|
|
|
|
- // Input a is larger and is translated to the output
|
|
|
|
|
- // if (greater == greater_a) z_m0 <= a_m1;
|
|
|
|
|
-
|
|
|
|
|
- // Input b is larger and is translated to the output
|
|
|
|
|
- // else if (greater == greater_b) z_m0 <= b_m1;
|
|
|
|
|
-
|
|
|
|
|
- // Shouldn't happen as abs should be 0 for this to occur
|
|
|
|
|
- // else begin
|
|
|
|
|
- // if (a_m1 >= b_m1) z_m0 <= a_m1; // Equal exponents but a has the larger mantissa
|
|
|
|
|
- // else if (b_m1 > a_m1) z_m0 <= b_m1; // Equal exponents but b has the larger mantissa
|
|
|
|
|
- // end
|
|
|
|
|
|
|
+ case (greater)
|
|
|
|
|
+ greater_a: z_m2 <= a_m1;
|
|
|
|
|
+ greater_b: z_m2 <= b_m1;
|
|
|
|
|
+ endcase
|
|
|
end
|
|
end
|
|
|
-
|
|
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
- z_m2 <= z_m1z[K*2-1:K];
|
|
|
|
|
|
|
+ z_m2 <= z_m1z[K*2-1:K];
|
|
|
|
|
+ z_m2s <= z_m1s;
|
|
|
end
|
|
end
|
|
|
- end
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if(z_m2s) begin
|
|
|
|
|
+ z_e3 <= z_e2 + 1;
|
|
|
|
|
+ end else begin
|
|
|
|
|
+ z_e3 <= z_e2;
|
|
|
|
|
+ end
|
|
|
|
|
+ z_m3 <= z_m2;
|
|
|
|
|
+ z_s3 <= z_s2;
|
|
|
|
|
+
|
|
|
|
|
+ end // end ~reset
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
a_m0 <= 0;
|
|
a_m0 <= 0;
|
|
@@ -152,14 +144,17 @@ module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
|
|
|
|
|
|
|
|
a_m1 <= 0;
|
|
a_m1 <= 0;
|
|
|
b_m1 <= 0;
|
|
b_m1 <= 0;
|
|
|
- z_e2 <= 0;
|
|
|
|
|
- z_s2 <= 0;
|
|
|
|
|
-
|
|
|
|
|
z_s1 <= 0;
|
|
z_s1 <= 0;
|
|
|
z_e1 <= 0;
|
|
z_e1 <= 0;
|
|
|
- z_s2 <= 0;
|
|
|
|
|
|
|
+
|
|
|
z_e2 <= 0;
|
|
z_e2 <= 0;
|
|
|
|
|
+ z_s2 <= 0;
|
|
|
z_m2 <= 0;
|
|
z_m2 <= 0;
|
|
|
|
|
+ z_m2s <= 0;
|
|
|
|
|
+
|
|
|
|
|
+ z_s3 <= 0;
|
|
|
|
|
+ z_e3 <= 0;
|
|
|
|
|
+ z_m3 <= 0;
|
|
|
|
|
|
|
|
greater <= equal_ab;
|
|
greater <= equal_ab;
|
|
|
abs <= 0;
|
|
abs <= 0;
|