瀏覽代碼

new modules and vectors

Oliver Jaison 4 年之前
父節點
當前提交
e8a7ddfb11
共有 3 個文件被更改,包括 150 次插入22 次删除
  1. 57 0
      fpa/FPA_module_test.sv
  2. 1 1
      scripts/fpu_test_gen.py
  3. 92 21
      src/FPA_module_test.sv

+ 57 - 0
fpa/FPA_module_test.sv

@@ -0,0 +1,57 @@
+module floating_add #(parameter N=16)(a, b, c);
+	input logic [N-1:0] a, b; 
+	output logic [N-1:0] c;
+
+	logic flag_a;
+	logic flag_b;
+	logic abs;
+	
+	// sign_x = x[N-1]
+	// exponent_x = x[N-2:N-6]
+	// mantissa_x = x[N-7:0]
+	
+	assign c[N-1] = a[N-1] ^ b[N-1];
+	
+	always_comb
+		begin
+			if (a[N-2:N-6] > b[N-2:N-6])
+				begin
+					flag_a = 1;
+					flag_b = 0;
+					abs = a[N-2:N-6] - b[N-2:N-6];
+					c[N-2:N-6] = a[N-2:N-6];
+				end
+			else if (b[N-2:N-6] > a[N-2:N-6])
+				begin
+					flag_a = 0;
+					flag_b = 1;
+					abs = b[N-2:N-6] - a[N-2:N-6];
+					c[N-2:N-6] = b[N-2:N-6];
+				end
+			else 
+				begin
+					flag_a = 1;
+					flag_b = 1;
+					abs <= 0;
+					c[N-2:N-6] = a[N-2:N-6];
+				end
+		end
+		
+	always_comb
+		begin 
+			if (abs > 4'b1000)
+				begin
+					if (flag_a & ~flag_b) c = a;
+					else if (~flag_a & flag_b) c = b;
+					else c <= a;
+				end
+			else
+				begin
+					if (flag_a & ~flag_b) 
+						c[N-7:0] = a[N-7:0] + (b[N-7:0] >> abs);
+					else if (~flag_a & flag_b) 
+						c[N-7:0] = b[N-7:0] + (a[N-7:0] >> abs);
+					else c[N-7:0] <= b[N-7:0] << 1;
+				end
+		end
+endmodule	

+ 1 - 1
scripts/fpu_test_gen.py

@@ -29,4 +29,4 @@ def generate_fp_vector(cases, filename, dtype=np.float16):
 
 
 if __name__ == '__main__':
-    generate_fp_vector(30, 'fp32_test.hex', dtype=np.float32)
+    generate_fp_vector(30, 'fp16_test.hex', dtype=np.float16)

+ 92 - 21
src/FPA_module_test.sv

@@ -1,10 +1,12 @@
 module floating_add #(parameter N=16, M=4)(a, b, c);
 	input logic [N-1:0] a, b; 
 	output logic [N-1:0] c;
+	output logic flag_double;
 
 	logic flag_a;
 	logic flag_b;
 	logic abs;
+	logic res;
 	
 	// sign_x = x[N-1]
 	// 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_b = 1;
 					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];
 				end
 		end
@@ -49,7 +52,7 @@ module floating_add #(parameter N=16, M=4)(a, b, c);
 	always_comb
 		begin
 			// 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
 					if (flag_a & ~flag_b) c = a;
 					else if (~flag_a & flag_b) c = b;
@@ -59,21 +62,43 @@ module floating_add #(parameter N=16, M=4)(a, b, c);
 				begin
 					// Shifts the lower mantissa right based on the absolute difference
 					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)
-						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
-						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
 endmodule : floating_add
@@ -83,14 +108,14 @@ endmodule : floating_add
 module floating_product #(parameter N=16, M=4)(a, b, c);
 	input logic [N-1:0] a, b;
 	output logic [N-1:0] c;
+	output logic underflow, zero_flag;
 
 	// sign_x = x[N-1]
 	// exponent_x = x[N-2:N-2-M]
 	// mantissa_x = x[N-3-M:0]
 
 	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
 	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
 					c[N-1:0] = 0;
 					underflow = 1;
+					zero_flag = 0;
 				end
 			// 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
 				begin
 					// 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;
 					// Setting the sign of the output
 					c[N-1] = a[N-1]^b[N-1];
+					underflow = 0;
+					zero_flag = 0;
 				end
 		end
-
 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;
 	logic [15:0] a, b, c;
 	floating_add adder1(a, b, c);
@@ -144,6 +213,8 @@ module floating_add_tb;
 	end
 endmodule : floating_add_tb
 
+
+
 module floating_product_tb;
 	logic [15:0] a, b, c;
 	floating_product multiplier1(a, b, c);