Преглед изворни кода

reworked multiplication module

Oliver Jaison пре 4 година
родитељ
комит
7eaf6f6ca7
1 измењених фајлова са 115 додато и 30 уклоњено
  1. 115 30
      src/FPA_module_test.sv

+ 115 - 30
src/FPA_module_test.sv

@@ -156,49 +156,134 @@ module floating_product #(parameter N=16, M=4)(input_1, input_2, product, clk, r
 	input logic [N-1:0] input_1, input_2;
 	input logic clk, reset;
 	output logic [N-1:0] product;
-
+	
+	logic [2*N-1:0] D0 [7:0];
+	logic [2*N-1:0] Q0 [7:0];
+	logic [2*N-1:0] Q1 [7:0];
+	logic [2*N-1:0] Q2 [7:0];
+	
+	always_comb
+	begin
+		D0[0][N-1:0] = input_1;
+		D0[1][N-1:0] = input_2;
+		D0[2] = 0; // product (output)
+		D0[3] = 0; // multiple for multiplying the mantissa
+		D0[4] = 0; // flag for return NaN
+		D0[5] = 0; // flag for return infinity
+		D0[6] = 0; // flag for return zero
+		D0[7][N-3-M:0] = input_1[N-3-M:0]; // for storing the mantissa of input 1
+	end
 	// sign_x = x[N-1]
 	// exponent_x = x[N-2:N-2-M]
 	// mantissa_x = x[N-3-M:0]
-
-	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
+	pipe #(.N(2*N-1), .K(7)) pipe0(.clk(clk), .reset(reset), .D(D0), .Q(Q0));
+	
 	always_comb
+	begin
+		// if input_1 or input_2 is NaN then return NaN
+		if ((Q0[0][N-2:N-2-M] == (1<<M) && Q0[0][N-3-M:0] != 0) || (Q1[0][N-2:N-2-M] == (1<<M) && Q1[0][N-3-M:0] != 0))
 		begin
-			D0[0] = input_1;
-			D0[1] = input_2;
-			D0[2] = 0; // product
-			D0[3] = 0; // sum
-			D0[4] = 0; // mult
+			Q0[2][N-1] = 1;
+			Q0[2][N-2:N-2-M] = (1 << (M+1)) - 1;
+			Q0[2][N-3-M] = 1;
+			Q0[2][N-4-M:0] = 0;
+			Q0[4][0] = 1;
 		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
-	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;
+		// if input 1 is infinity then return infinity
+		else if (Q0[0][N-2:N-2-M] == (1<<M))
+		begin
+			Q0[2][N-1] = Q0[0][N-1] ^ Q0[1][N-1];
+			Q0[2][N-2:N-2-M] = (1 << (M+1)) - 1;
+			Q0[2][N-3-M:0] = 0;
+			Q0[5] = 1;
+			// if input 2 is zero then return NaN
+			if (($signed(Q0[1][N-2:N-2-M]) == (-1*((1<<M)-1))) && (Q0[1][N-3-M:0] == 0))
+			begin
+				Q0[2][N-1] = 1;
+				Q0[2][N-2:N-2-M] = (1 << (M+1)) - 1;
+				Q0[2][N-3-M] = 1;
+				Q0[2][N-4-M:0] = 0;
+				Q0[4][0] = 1;
+			end
+		end
+		// if input 2 is infinity then return infinity
+		else if (Q0[1][N-2:N-2-M] == (1<<M))
+		begin
+			Q0[2][N-1] = Q0[0][N-1] ^ Q0[1][N-1];
+			Q0[2][N-2:N-2-M] = (1 << (M+1)) - 1;
+			Q0[2][N-3-M:0] = 0;
+			Q0[5][0] = 1;
+			// if input 1 is zero then return NaN
+			if (($signed(Q0[0][N-2:N-2-M]) == (-1*((1<<M)-1))) && (Q0[0][N-3-M:0] == 0))
+			begin
+				Q0[2][N-1] = 1;
+				Q0[2][N-2:N-2-M] = (1 << (M+1)) - 1;
+				Q0[2][N-3-M] = 1;
+				Q0[2][N-4-M:0] = 0;
+				Q0[4][0] = 1;
+			end
+		end
+		// if input 1 is zero then return zero
+		else if (($signed(Q0[0][N-2:N-2-M]) == (-1*((1<<M)-1))) && (Q0[0][N-3-M:0] == 0))
+		begin
+			Q0[2][N-1] = Q0[0][N-1] ^ Q0[1][N-1];
+			Q0[2][N-2:N-2-M] = 0;
+			Q0[2][N-3-M:0] = 0;
+			Q0[6][0] = 1;
+		end
+		// if input 2 is zero then return zero
+		else if (($signed(Q0[1][N-2:N-2-M]) == (-1*((1<<M)-1))) && (Q0[1][N-3-M:0] == 0))
+		begin
+			Q0[2][N-1] = Q0[0][N-1] ^ Q0[1][N-1];
+			Q0[2][N-2:N-2-M] = 0;
+			Q0[2][N-3-M:0] = 0;
+			Q0[6][0] = 1;
+		end
+	end
+	
+	pipe #(.N(2*N-1), .K(7)) pipe1(.clk(clk), .reset(reset), .D(Q0), .Q(Q1));
 	
-	// Second pipeline stage
-	pipe#(.N(2*(N-3-M)), .K(4)) pipe1(.clk(clk), .reset(reset), .D(Q0), .Q(Q1));
-
 	always_comb
+	begin
+	// If none of the return flags have been triggered
+		if ((Q1[4][0] && Q1[5][0] && Q1[6][0]) != 1)
 		begin
-				// Setting the mantissa of the output
-				Q1[4] = Q1[0][N-3-M:0] * Q1[1][N-3-M:0];
-				if (Q1[4][N-3-M]) Q1[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];
+			// if msb of input 1 mantissa is not 1 then shift left by 1 and reduce exponent by 1
+			if (Q1[0][N-3-M] != 1)
+			begin
+				Q1[0][N-3-M:0] = Q1[0][N-3-M:0] << 1;
+				Q1[0][N-2:N-2-M] = Q1[0][N-2:N-2-M] - 1;
+			end
+			// if msb of input 2 mantissa is not 1 then shift left by 1 and reduce exponent by 1
+			if (Q1[1][N-3-M] != 1)
+			begin
+				Q1[1][N-3-M:0] = Q1[1][N-3-M:0] << 1;
+				Q1[1][N-2:N-2-M] = Q1[1][N-2:N-2-M] - 1;
+			end
+			Q1[2][N-1] = Q1[2][N-1] ^ Q1[2][N-1]; // ouput sign = input_1 sign xor input_2 sign
+			Q1[2][N-2:N-2-M] = Q1[0][N-2:N-2-M] + Q1[1][N-2:N-2-M] - (1<<M); // out exp = in1 exp + in2 exp - 2**M
+			// multiplying mantissa
+			for (int i = 0; i<N-2-M; i++)
+			begin
+				// multiplying each digit of input 2 by all of input 1 shifting the bits left each time and adding result to the array
+				if (Q1[1][i] == 1)
+				begin
+					Q1[3] = Q1[3] +(Q1[7]<<i);
+				end
+				else
+				begin
+					Q1[3] = Q1[3] + 0;
+				end
+			end
+			// Assigning the top set of bits to the mantissa of the output 
+			Q1[2][N-3-M:0] = Q1[3][2*N-1:2*N-1-N-3-M];
 		end
+	end
 	
-	//Final Pipeline stage
-	pipe#(.N(2*(N-3-M)), .K(4)) pipe2(.clk(clk), .reset(reset), .D(Q1), .Q(Q2));
+	pipe #(.N(2*N-1), .K(7)) pipe2(.clk(clk), .reset(reset), .D(Q1), .Q(Q2));
 	assign product = Q2[2][N-1:0];
+	
 endmodule : floating_product