|
@@ -1,10 +1,12 @@
|
|
|
module floating_add #(parameter N=16, M=4)(a, b, c);
|
|
module floating_add #(parameter N=16, M=4)(a, b, c);
|
|
|
input logic [N-1:0] a, b;
|
|
input logic [N-1:0] a, b;
|
|
|
output logic [N-1:0] c;
|
|
output logic [N-1:0] c;
|
|
|
|
|
+ output logic flag_double;
|
|
|
|
|
|
|
|
logic flag_a;
|
|
logic flag_a;
|
|
|
logic flag_b;
|
|
logic flag_b;
|
|
|
logic abs;
|
|
logic abs;
|
|
|
|
|
+ logic res;
|
|
|
|
|
|
|
|
// sign_x = x[N-1]
|
|
// sign_x = x[N-1]
|
|
|
// exponent_x = x[N-2:N-2-M]
|
|
// exponent_x = x[N-2:N-2-M]
|
|
@@ -40,8 +42,9 @@ module floating_add #(parameter N=16, M=4)(a, b, c);
|
|
|
flag_a = 1;
|
|
flag_a = 1;
|
|
|
flag_b = 1;
|
|
flag_b = 1;
|
|
|
abs <= 0;
|
|
abs <= 0;
|
|
|
- // ASsigning overall sign of the output
|
|
|
|
|
- assign c[N-1] = 0;
|
|
|
|
|
|
|
+ // ASsigning overall sign of the output based on size of the mantissa
|
|
|
|
|
+ if (a[N-3-M:0] >= b[N-3-M:0]) assign c[N-1] = a[N-1];
|
|
|
|
|
+ else assign c[N-1] = b[N-1];
|
|
|
c[N-2:N-2-M] = a[N-2:N-2-M];
|
|
c[N-2:N-2-M] = a[N-2:N-2-M];
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
@@ -49,7 +52,7 @@ module floating_add #(parameter N=16, M=4)(a, b, c);
|
|
|
always_comb
|
|
always_comb
|
|
|
begin
|
|
begin
|
|
|
// 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 > 4'b1000)
|
|
|
|
|
|
|
+ if (abs > 3'b100) // Because size of exponent is 4 bits
|
|
|
begin
|
|
begin
|
|
|
if (flag_a & ~flag_b) c = a;
|
|
if (flag_a & ~flag_b) c = a;
|
|
|
else if (~flag_a & flag_b) c = b;
|
|
else if (~flag_a & flag_b) c = b;
|
|
@@ -59,21 +62,43 @@ module floating_add #(parameter N=16, M=4)(a, b, c);
|
|
|
begin
|
|
begin
|
|
|
// Shifts the lower mantissa right based on the absolute difference
|
|
// Shifts the lower mantissa right based on the absolute difference
|
|
|
if (flag_a & ~flag_b)
|
|
if (flag_a & ~flag_b)
|
|
|
- // If the signs of both inputs are the same you add, otherwise you subtract
|
|
|
|
|
- if (a[N-1] == b[N-1])
|
|
|
|
|
- c[N-3-M:0] = a[N-3-M:0] + (b[N-3-M:0] >> abs);
|
|
|
|
|
- else
|
|
|
|
|
- c[N-3-M:0] = a[N-3-M:0] - (b[N-3-M:0] >> abs);
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ // If the signs of both inputs are the same you add, otherwise you subtract
|
|
|
|
|
+ if (a[N-1] == b[N-1])
|
|
|
|
|
+ c[N-3-M:0] = a[N-3-M:0] + (b[N-3-M:0] >> abs);
|
|
|
|
|
+ else
|
|
|
|
|
+ c[N-3-M:0] = a[N-3-M:0] - (b[N-3-M:0] >> abs);
|
|
|
|
|
+ flag_double = 0;
|
|
|
|
|
+ end
|
|
|
else if (~flag_a & flag_b)
|
|
else if (~flag_a & flag_b)
|
|
|
- if (a[N-1] == b[N-1])
|
|
|
|
|
- c[N-3-M:0] = b[N-3-M:0] + (a[N-3-M:0] >> abs);
|
|
|
|
|
- else
|
|
|
|
|
- c[N-3-M:0] = b[N-3-M:0] - (a[N-3-M:0] >> abs);
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ if (a[N-1] == b[N-1])
|
|
|
|
|
+ c[N-3-M:0] = b[N-3-M:0] + (a[N-3-M:0] >> abs);
|
|
|
|
|
+ else
|
|
|
|
|
+ c[N-3-M:0] = b[N-3-M:0] - (a[N-3-M:0] >> abs);
|
|
|
|
|
+ flag_double = 0;
|
|
|
|
|
+ end
|
|
|
else
|
|
else
|
|
|
- if (a[N-1] == b[N-1])
|
|
|
|
|
- c[N-3-M:0] = b[N-3-M:0] << 1;
|
|
|
|
|
- else
|
|
|
|
|
- c[N-3-M:0] = 0;
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ if (a[N-1] == b[N-1])
|
|
|
|
|
+ begin
|
|
|
|
|
+ res = a[N-3-M:0] + b[N-3-M:0];
|
|
|
|
|
+ if (res > 1)
|
|
|
|
|
+ begin
|
|
|
|
|
+ c[N-3-M:0] = res >> 1;
|
|
|
|
|
+ c[N-2:N-2-M] = c[N-2:N-2-M] + 1;
|
|
|
|
|
+ end
|
|
|
|
|
+ else c[N-3-M:0] = res;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ if (a[N-3-M:0] > b[N-3-M:0]) res = a[N-3-M:0] - b[N-3-M:0];
|
|
|
|
|
+ else if (a[N-3-M:0] < b[N-3-M:0]) res = b[N-3-M:0] - a[N-3-M:0];
|
|
|
|
|
+ else res = 0;
|
|
|
|
|
+ c[N-3-M:0] = res;
|
|
|
|
|
+ end
|
|
|
|
|
+ flag_double = 1;
|
|
|
|
|
+ end
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
endmodule : floating_add
|
|
endmodule : floating_add
|
|
@@ -83,14 +108,14 @@ endmodule : floating_add
|
|
|
module floating_product #(parameter N=16, M=4)(a, b, c);
|
|
module floating_product #(parameter N=16, M=4)(a, b, c);
|
|
|
input logic [N-1:0] a, b;
|
|
input logic [N-1:0] a, b;
|
|
|
output logic [N-1:0] c;
|
|
output logic [N-1:0] c;
|
|
|
|
|
+ output logic underflow, zero_flag;
|
|
|
|
|
|
|
|
// sign_x = x[N-1]
|
|
// sign_x = x[N-1]
|
|
|
// exponent_x = x[N-2:N-2-M]
|
|
// exponent_x = x[N-2:N-2-M]
|
|
|
// mantissa_x = x[N-3-M:0]
|
|
// mantissa_x = x[N-3-M:0]
|
|
|
|
|
|
|
|
logic sum;
|
|
logic sum;
|
|
|
- logic underflow;
|
|
|
|
|
- logic [N-3-M:0] product;
|
|
|
|
|
|
|
+ logic [2*N-6-2*M:0] product;
|
|
|
|
|
|
|
|
// We have assigned an {M+1} bit exponent so we must have a 2^{M} offset
|
|
// We have assigned an {M+1} bit exponent so we must have a 2^{M} offset
|
|
|
assign sum = a[N-2:N-2-M] + b[N-2:N-2-M];
|
|
assign sum = a[N-2:N-2-M] + b[N-2:N-2-M];
|
|
@@ -103,10 +128,15 @@ module floating_product #(parameter N=16, M=4)(a, b, c);
|
|
|
begin
|
|
begin
|
|
|
c[N-1:0] = 0;
|
|
c[N-1:0] = 0;
|
|
|
underflow = 1;
|
|
underflow = 1;
|
|
|
|
|
+ zero_flag = 0;
|
|
|
end
|
|
end
|
|
|
// If either input number has a high-order bit of zero, then that input is zero and the product is zero
|
|
// If either input number has a high-order bit of zero, then that input is zero and the product is zero
|
|
|
- else if (!a[N-3-M] || !b[N-3-M])
|
|
|
|
|
- c[N-1:0] = 0;
|
|
|
|
|
|
|
+ else if (!a[N-2] || !b[N-2])
|
|
|
|
|
+ begin
|
|
|
|
|
+ c[N-1:0] = 0;
|
|
|
|
|
+ zero_flag = 1;
|
|
|
|
|
+ underflow = 0;
|
|
|
|
|
+ end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
// Setting the mantissa of the output
|
|
// Setting the mantissa of the output
|
|
@@ -117,13 +147,52 @@ module floating_product #(parameter N=16, M=4)(a, b, c);
|
|
|
c[N-3-M:0] = product[N-3-M:0] << 1;
|
|
c[N-3-M:0] = product[N-3-M:0] << 1;
|
|
|
// Setting the sign of the output
|
|
// Setting the sign of the output
|
|
|
c[N-1] = a[N-1]^b[N-1];
|
|
c[N-1] = a[N-1]^b[N-1];
|
|
|
|
|
+ underflow = 0;
|
|
|
|
|
+ zero_flag = 0;
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
-
|
|
|
|
|
endmodule : floating_product
|
|
endmodule : floating_product
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+module Integer2FP #(parameter N = 16, M = 4)(in, out);
|
|
|
|
|
+// Considering we have a 10 bit mantissa, I assume 11 bit integer input
|
|
|
|
|
+ input logic [N-2-M:0] in;
|
|
|
|
|
+ output logic [N-1:0] out;
|
|
|
|
|
+
|
|
|
|
|
+ logic shift_counter = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // Saving the sign
|
|
|
|
|
+ assign out[N-1] = in[N-2-M];
|
|
|
|
|
+
|
|
|
|
|
+ always_comb
|
|
|
|
|
+ begin
|
|
|
|
|
+ // Shifting the absolute value until MSB is 1 and keeping track of the number of shifts
|
|
|
|
|
+ while (!in[N-3-M])
|
|
|
|
|
+ begin
|
|
|
|
|
+ shift_counter = shift_counter + 1;
|
|
|
|
|
+ in[N-3-M] = in[N-3-M:0] << 1;
|
|
|
|
|
+ end
|
|
|
|
|
+ // Assigning the mantissa as the shifted absolute value
|
|
|
|
|
+ // Assigning the exponent as the number of shifts - a constant 137
|
|
|
|
|
+ out[N-3-M:0] = in[N-3-M:0];
|
|
|
|
|
+ out[N-2:N-2-M] = shift_counter - 137;
|
|
|
|
|
+ end
|
|
|
|
|
+endmodule : Integer2FP
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+module FP2Integer #(parameter N = 16, M = 4)(in, out);
|
|
|
|
|
+ input logic [N-1:0]in;
|
|
|
|
|
+ output logic [N-2-M:0]out;
|
|
|
|
|
+
|
|
|
|
|
+ assign out[N-2-M] = in[N-1];
|
|
|
|
|
+ assign out[N-3-M:0] = in[N-3-M:0] << (137 - in[N-2:N-2-M]);
|
|
|
|
|
+
|
|
|
|
|
+endmodule : FP2Integer
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
module floating_add_tb;
|
|
module floating_add_tb;
|
|
|
logic [15:0] a, b, c;
|
|
logic [15:0] a, b, c;
|
|
|
floating_add adder1(a, b, c);
|
|
floating_add adder1(a, b, c);
|
|
@@ -144,6 +213,8 @@ module floating_add_tb;
|
|
|
end
|
|
end
|
|
|
endmodule : floating_add_tb
|
|
endmodule : floating_add_tb
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
module floating_product_tb;
|
|
module floating_product_tb;
|
|
|
logic [15:0] a, b, c;
|
|
logic [15:0] a, b, c;
|
|
|
floating_product multiplier1(a, b, c);
|
|
floating_product multiplier1(a, b, c);
|