|
@@ -1,127 +1,153 @@
|
|
|
-module floating_add #(parameter N=16, M=4)(input_1, input_2, sum, diff);
|
|
|
|
|
|
|
+module floating_add #(parameter N=16, M=4)(input_1, input_2, sum, diff, clk, reset);
|
|
|
input logic [N-1:0] input_1, input_2;
|
|
input logic [N-1:0] input_1, input_2;
|
|
|
|
|
+ input logic clk, reset;
|
|
|
output logic [N-1:0] sum;
|
|
output logic [N-1:0] sum;
|
|
|
output logic [M:0] diff;
|
|
output logic [M:0] diff;
|
|
|
|
|
|
|
|
- logic flag_a;
|
|
|
|
|
- logic flag_b;
|
|
|
|
|
- logic [M:0] abs;
|
|
|
|
|
- logic [N-3-M:0] res;
|
|
|
|
|
|
|
+// logic flag_a;
|
|
|
|
|
+// logic flag_b;
|
|
|
|
|
+// logic [M:0] abs;
|
|
|
|
|
+// logic [N-3-M:0] res;
|
|
|
|
|
+
|
|
|
|
|
+ logic [N-1:0] D0 [7:0];
|
|
|
|
|
+ logic [N-1:0] Q0 [7:0];
|
|
|
|
|
+ logic [N-1:0] Q1 [7:0];
|
|
|
|
|
+ logic [N-1:0] Q2 [7:0];
|
|
|
|
|
|
|
|
// 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]
|
|
|
|
|
|
|
|
|
|
+ //First pipeline stage
|
|
|
|
|
+ always_comb
|
|
|
|
|
+ begin
|
|
|
|
|
+ D0[0] = input_1;
|
|
|
|
|
+ D0[1] = input_2;
|
|
|
|
|
+ D0[2] = 0; // sum
|
|
|
|
|
+ D0[3] = 0; // diff
|
|
|
|
|
+ D0[4] = 0; // flag_a
|
|
|
|
|
+ D0[5] = 0; // flag_b
|
|
|
|
|
+ D0[6] = 0; // abs
|
|
|
|
|
+ D0[7] = 0; // res
|
|
|
|
|
+ end
|
|
|
|
|
+ pipe#(.N(N-1), .K(7)) pipe0(.clk(clk), .reset(reset), .D(D0), .Q(Q0));
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
always_comb
|
|
always_comb
|
|
|
begin
|
|
begin
|
|
|
- if (input_1[N-2:N-2-M] > input_2[N-2:N-2-M]) // If input 1 has the bigger exponent
|
|
|
|
|
|
|
+ if (Q0[0][N-2:N-2-M] > Q0[1][N-2:N-2-M]) // If input 1 has the bigger exponent
|
|
|
begin
|
|
begin
|
|
|
// Flags input a as larger and calculates the absolute difference
|
|
// Flags input a as larger and calculates the absolute difference
|
|
|
- flag_a = 1;
|
|
|
|
|
- flag_b = 0;
|
|
|
|
|
- abs = input_1[N-2:N-2-M] - input_2[N-2:N-2-M];
|
|
|
|
|
|
|
+ Q0[4] = 1;
|
|
|
|
|
+ Q0[5] = 0;
|
|
|
|
|
+ Q0[6] = Q0[0][N-2:N-2-M] - Q0[1][N-2:N-2-M];
|
|
|
// ASsigning overall sign of the output
|
|
// ASsigning overall sign of the output
|
|
|
- sum[N-1] = input_1[N-1];
|
|
|
|
|
|
|
+ Q0[2][N-1] = Q0[0][N-1];
|
|
|
// Sets output to have the same exponent
|
|
// Sets output to have the same exponent
|
|
|
- sum[N-2:N-2-M] = input_1[N-2:N-2-M];
|
|
|
|
|
|
|
+ Q0[2][N-2:N-2-M] = Q0[0][N-2:N-2-M];
|
|
|
end
|
|
end
|
|
|
- else if (input_2[N-2:N-2-M] > input_1[N-2:N-2-M]) // If input 2 has the bigger exponent
|
|
|
|
|
|
|
+ else if (Q0[1][N-2:N-2-M] > Q0[0][N-2:N-2-M]) // If input 2 has the bigger exponent
|
|
|
begin
|
|
begin
|
|
|
// Similarly flags input b as larger and calculates the absolute difference
|
|
// Similarly flags input b as larger and calculates the absolute difference
|
|
|
- flag_a = 0;
|
|
|
|
|
- flag_b = 1;
|
|
|
|
|
- abs = input_2[N-2:N-2-M] - input_1[N-2:N-2-M];
|
|
|
|
|
|
|
+ Q0[4] = 0;
|
|
|
|
|
+ Q0[5] = 1;
|
|
|
|
|
+ Q0[6] = Q0[1][N-2:N-2-M] - Q0[0][N-2:N-2-M];
|
|
|
// ASsigning overall sign of the output
|
|
// ASsigning overall sign of the output
|
|
|
- sum[N-1] = input_2[N-1];
|
|
|
|
|
|
|
+ Q0[2][N-1] = Q0[1][N-1];
|
|
|
// Sets ouput to have the same exponent
|
|
// Sets ouput to have the same exponent
|
|
|
- sum[N-2:N-2-M] = input_2[N-2:N-2-M];
|
|
|
|
|
|
|
+ Q0[2][N-2:N-2-M] = Q0[1][N-2:N-2-M];
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
// THe condition that both inputs have the same exponent
|
|
// THe condition that both inputs have the same exponent
|
|
|
- flag_a = 1;
|
|
|
|
|
- flag_b = 1;
|
|
|
|
|
- abs = 0;
|
|
|
|
|
|
|
+ Q0[4] = 1;
|
|
|
|
|
+ Q0[5] = 1;
|
|
|
|
|
+ Q0[6] = 0;
|
|
|
// ASsigning overall sign of the output based on size of the mantissa
|
|
// ASsigning overall sign of the output based on size of the mantissa
|
|
|
- if (input_1[N-3-M:0] >= input_2[N-3-M:0]) sum[N-1] = input_1[N-1];
|
|
|
|
|
- else sum[N-1] = input_2[N-1];
|
|
|
|
|
- sum[N-2:N-2-M] = input_1[N-2:N-2-M];
|
|
|
|
|
|
|
+ if (Q0[0][N-3-M:0] >= Q0[1][N-3-M:0]) Q0[2][N-1] = Q0[0][N-1];
|
|
|
|
|
+ else Q0[2][N-1] = Q0[1][N-1];
|
|
|
|
|
+ Q0[2][N-2:N-2-M] = Q0[0][N-2:N-2-M];
|
|
|
end
|
|
end
|
|
|
- diff = abs;
|
|
|
|
|
|
|
+ Q0[3] = Q0[6];
|
|
|
end
|
|
end
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
//Second pipeline stage 1
|
|
//Second pipeline stage 1
|
|
|
- pipe pipe1(.clk(clk), .reset(reset), .D(Q0), .Q(Q1));
|
|
|
|
|
-
|
|
|
|
|
|
|
+ pipe#(.N(N-1), .K(7)) pipe1(.clk(clk), .reset(reset), .D(Q0), .Q(Q1));
|
|
|
|
|
+
|
|
|
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 > 9) // Because size of mantissa is 10 bits and shifting by 10 would give 0
|
|
|
|
|
|
|
+ if (Q1[6] > N-2-M) // Because size of mantissa is 10 bits and shifting by 10 would give 0
|
|
|
begin
|
|
begin
|
|
|
- if (flag_a & ~flag_b) sum = input_1; // input 1 is larger and is translated to output
|
|
|
|
|
- else if (~flag_a & flag_b) sum = input_2; // input 2 is larger and is translated to output
|
|
|
|
|
|
|
+ if (Q1[4] & ~Q1[5]) Q1[2] = Q1[0]; // input 1 is larger and is translated to output
|
|
|
|
|
+ else if (~Q1[4] & Q1[5]) Q1[2] = Q1[1]; // input 2 is larger and is translated to output
|
|
|
else // exponents are the same
|
|
else // exponents are the same
|
|
|
begin
|
|
begin
|
|
|
- if (input_1[N-3-M:0] >= input_2[N-3-M:0]) sum = input_1;// input 1 has the bigger mantissa
|
|
|
|
|
- else sum = input_2; // input 2 has the bigger mantissa
|
|
|
|
|
|
|
+ if (Q1[6][N-3-M:0] >= Q1[1][N-3-M:0]) Q1[2] = Q1[0];// input 1 has the bigger mantissa
|
|
|
|
|
+ else Q1[2] = Q1[1]; // input 2 has the bigger mantissa
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
// Shifts the smaller input's mantissa to the right based on abs
|
|
// Shifts the smaller input's mantissa to the right based on abs
|
|
|
- if (flag_a & ~flag_b)// If input 1 has the larger exponent
|
|
|
|
|
|
|
+ if (Q1[4] & ~Q1[5])// If input 1 has the larger exponent
|
|
|
begin
|
|
begin
|
|
|
// If the signs of both inputs are the same you add, otherwise you subtract
|
|
// If the signs of both inputs are the same you add, otherwise you subtract
|
|
|
- if (input_1[N-1] == input_2[N-1])
|
|
|
|
|
|
|
+ if (Q1[0][N-1] == Q1[1][N-1])
|
|
|
begin
|
|
begin
|
|
|
- res = input_1[N-3-M:0] + (input_2[N-3-M:0] >> abs-1); // Sum the mantissa
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[0][N-3-M:0] + (Q1[1][N-3-M:0] >> Q1[6]-1); // Sum the mantissa
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
- res = input_1[N-3-M:0] - (input_2[N-3-M:0] >> abs-1); // Subtract the mantissas
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[0][N-3-M:0] - (Q1[1][N-3-M:0] >> Q1[6]-1); // Subtract the mantissas
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
- else if (~flag_a & flag_b)
|
|
|
|
|
|
|
+ else if (~Q1[4] & Q1[5])
|
|
|
begin
|
|
begin
|
|
|
// If the signs of both inputs are the same you add, otherwise you subtract
|
|
// If the signs of both inputs are the same you add, otherwise you subtract
|
|
|
- if (input_1[N-1] == input_2[N-1])
|
|
|
|
|
|
|
+ if (Q1[0][N-1] == Q1[1][N-1])
|
|
|
begin
|
|
begin
|
|
|
- res = (input_1[N-3-M:0] >> abs-1) + input_2[N-3-M:0]; // Sum the mantissa
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = (Q1[0][N-3-M:0] >> Q1[6]-1) + Q1[1][N-3-M:0]; // Sum the mantissa
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
- res = input_2[N-3-M:0] - (input_1[N-3-M:0] >> abs-1); // Subtract the mantissas
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[1][N-3-M:0] - (Q1[0][N-3-M:0] >> Q1[6]-1); // Subtract the mantissas
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
|
- if (input_1[N-1] == input_2[N-1]) // If exponents and signs equal
|
|
|
|
|
|
|
+ if (Q1[0][N-1] == Q1[1][N-1]) // If exponents and signs equal
|
|
|
begin
|
|
begin
|
|
|
- res = input_1[N-3-M:0] + input_2[N-3-M:0]; // Sum the mantissa
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[0][N-3-M:0] + Q1[1][N-3-M:0]; // Sum the mantissa
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
else // In this case it will be a subtraction
|
|
else // In this case it will be a subtraction
|
|
|
begin
|
|
begin
|
|
|
- if (input_1[N-3-M:0] > input_2[N-3-M:0]) // Which has the larger mantissa
|
|
|
|
|
|
|
+ if (Q1[0][N-3-M:0] > Q1[1][N-3-M:0]) // Which has the larger mantissa
|
|
|
begin
|
|
begin
|
|
|
- res = input_1[N-3-M:0] - input_2[N-3-M:0]; // Subtract the mantissa
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[0][N-3-M:0] - Q1[1][N-3-M:0]; // Subtract the mantissa
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
- else if (input_1[N-3-M:0] < input_2[N-3-M:0])
|
|
|
|
|
|
|
+ else if (Q1[0][N-3-M:0] < Q1[1][N-3-M:0])
|
|
|
begin
|
|
begin
|
|
|
- res = input_2[N-3-M:0] - input_1[N-3-M:0]; // Subtract the mantissa
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ Q1[7] = Q1[1][N-3-M:0] - Q1[0][N-3-M:0]; // Subtract the mantissa
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
- else res = 0; // Both the exponent and the mantissa are equal so subtraction leads to 0
|
|
|
|
|
- sum[N-3-M:0] = res;
|
|
|
|
|
|
|
+ else Q1[7] = 0; // Both the exponent and the mantissa are equal so subtraction leads to 0
|
|
|
|
|
+ Q1[2][N-3-M:0] = Q1[7];
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
end
|
|
end
|
|
|
|
|
+
|
|
|
|
|
+ // Final pipeline stage
|
|
|
|
|
+ pipe#(.N(N-1), .K(7)) pipe2(.clk(clk), .reset(reset), .D(Q1), .Q(Q2));
|
|
|
|
|
+ assign sum = Q2[2];
|
|
|
|
|
+ assign diff = Q2[3];
|
|
|
endmodule : floating_add
|
|
endmodule : floating_add
|
|
|
|
|
|
|
|
|
|
|
|
@@ -134,41 +160,65 @@ module floating_product #(parameter N=16, M=4)(input_1, input_2, product);
|
|
|
// 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 [N-2:N-2-M] sum;
|
|
|
|
|
- logic [2*(N-3-M):0] mult;
|
|
|
|
|
|
|
+// logic [N-2:N-2-M] sum;
|
|
|
|
|
+// logic [2*(N-3-M):0] mult;
|
|
|
|
|
+ logic [2*(N-3-M):0] D0 [4:0];
|
|
|
|
|
+ logic [2*(N-3-M):0] Q0 [4:0];
|
|
|
|
|
+ logic [2*(N-3-M):0] Q1 [4:0];
|
|
|
|
|
+ logic [2*(N-3-M):0] Q2 [4:0];
|
|
|
|
|
+
|
|
|
|
|
+ //First pipeline stage
|
|
|
|
|
+ always_comb
|
|
|
|
|
+ begin
|
|
|
|
|
+ D0[0] = input_1;
|
|
|
|
|
+ D0[1] = input_2;
|
|
|
|
|
+ D0[2] = 0; // product
|
|
|
|
|
+ D0[3] = 0; // sum
|
|
|
|
|
+ D0[4] = 0; // mult
|
|
|
|
|
+ end
|
|
|
|
|
+ pipe#(.N(2*N-3-M), .K(4)) pipe0(.clk(clk), .reset(reset), .D(D0), .Q(Q0));
|
|
|
|
|
|
|
|
// 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 = input_1[N-2:N-2-M] + input_2[N-2:N-2-M];
|
|
|
|
|
- assign product[N-2:N-2-M] = sum - (1'b1 << M) + 2;
|
|
|
|
|
|
|
+ assign Q0[3] = Q0[0][N-2:N-2-M] + Q0[1][N-2:N-2-M];
|
|
|
|
|
+ assign Q0[2][N-2:N-2-M] = Q0[3] - (1'b1 << M) + 2;
|
|
|
|
|
+
|
|
|
|
|
+ //Second Pipeline stage
|
|
|
|
|
+ pipe#(.N(2*N-3-M), .K(4)) pipe1(.clk(clk), .reset(reset), .D(Q0), .Q(Q1));
|
|
|
|
|
|
|
|
always_comb
|
|
always_comb
|
|
|
begin
|
|
begin
|
|
|
// Setting the mantissa of the output
|
|
// Setting the mantissa of the output
|
|
|
- mult = input_1[N-3-M:0] * input_2[N-3-M:0];
|
|
|
|
|
- if (mult[N-3-M]) product[N-3-M:0] = mult[2*(N-3-M):2*(N-3-M)-9];
|
|
|
|
|
- else product[N-3-M:0] = mult[2*(N-3-M):2*(N-3-M)-9] << 1;
|
|
|
|
|
- product[N-1] = input_1[N-1] ^ input_2[N-1];
|
|
|
|
|
|
|
+ Q1[4] = Q1[0][N-3-M:0] * Q1[1][N-3-M:0];
|
|
|
|
|
+ if (Q1[4][N-3-M]) Q0[2][N-3-M:0] = Q1[4][2*(N-3-M):2*(N-3-M)-9];
|
|
|
|
|
+ else Q1[2][N-3-M:0] = Q1[4][2*(N-3-M):2*(N-3-M)-9] << 1;
|
|
|
|
|
+ Q1[2][N-1] = Q1[0][N-1] ^ Q1[1][N-1];
|
|
|
end
|
|
end
|
|
|
|
|
+
|
|
|
|
|
+ //Final Pipeline stage
|
|
|
|
|
+ pipe#(.N(2*N-3-M), .K(4)) pipe2(.clk(clk), .reset(reset), .D(Q1), .Q(Q2));
|
|
|
|
|
+ assign product = Q2[4][N-1:0];
|
|
|
endmodule : floating_product
|
|
endmodule : floating_product
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-module pipe #(parameter N=16)(clk, reset, Q, D);
|
|
|
|
|
|
|
+module pipe #(parameter N, K)(clk, reset, Q, D);
|
|
|
input logic clk, reset;
|
|
input logic clk, reset;
|
|
|
- input logic [N-1:0] D;
|
|
|
|
|
- output reg [N-1:0] Q;
|
|
|
|
|
- reg [N-1:0] in_pipe;
|
|
|
|
|
-
|
|
|
|
|
- always @(posedge clk or negedge reset)
|
|
|
|
|
- begin
|
|
|
|
|
- if(reset) in_pipe = 0;
|
|
|
|
|
- else in_pipe = D;
|
|
|
|
|
- end
|
|
|
|
|
|
|
+ input reg [N:0] D [K:0];
|
|
|
|
|
+ output reg [N:0] Q [K:0];
|
|
|
|
|
+ logic [N:0] in_pipe [K:0];
|
|
|
|
|
|
|
|
- always @(posedge clk or negedge reset)
|
|
|
|
|
|
|
+ always_ff @(posedge clk)
|
|
|
begin
|
|
begin
|
|
|
- if(reset) Q = 0;
|
|
|
|
|
- else Q = in_pipe;
|
|
|
|
|
|
|
+ if(reset)
|
|
|
|
|
+ begin
|
|
|
|
|
+ in_pipe <= 0;
|
|
|
|
|
+ Q <= 0;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ in_pipe <= D;
|
|
|
|
|
+ Q <= in_pipe;
|
|
|
|
|
+ end
|
|
|
end
|
|
end
|
|
|
endmodule : pipe
|
|
endmodule : pipe
|
|
|
|
|
|
|
@@ -179,9 +229,9 @@ module floating_tb;
|
|
|
logic [15:0] input_a, input_b, result_add, result_mult;
|
|
logic [15:0] input_a, input_b, result_add, result_mult;
|
|
|
logic [4:0] diff;
|
|
logic [4:0] diff;
|
|
|
|
|
|
|
|
- floating_add adder1(.input_1(input_a), .input_2(input_b), .sum(result_add), .diff(diff));
|
|
|
|
|
|
|
+ floating_add adder1(.input_1(input_a), .input_2(input_b), .sum(result_add), .diff(diff), .clk(clk), .reset(reset));
|
|
|
|
|
|
|
|
- floating_product multiplier1(.input_1(input_a), .input_2(input_b), .product(result_mult));
|
|
|
|
|
|
|
+ floating_product multiplier1(.input_1(input_a), .input_2(input_b), .product(result_mult), .clk(clk), .reset(reset));
|
|
|
|
|
|
|
|
|
|
|
|
|
reg [15:0] test_mem [29:0][3:0];
|
|
reg [15:0] test_mem [29:0][3:0];
|