Quellcode durchsuchen

new pipeline method

Oliver Jaison vor 4 Jahren
Ursprung
Commit
0417484054
1 geänderte Dateien mit 203 neuen und 0 gelöschten Zeilen
  1. 203 0
      src/fpu16/fp_adder.sv

+ 203 - 0
src/fpu16/fp_adder.sv

@@ -0,0 +1,203 @@
+module fp_adder #(parameter N=16, M=4)(input_a, input_b, output_z, diff, clk, reset);
+	input logic [N-1:0] input_a, input_a;
+	input logic clk, reset;
+	output logic [N-1:0] output_z;
+	
+	reg [N-1:0] a, b, z;
+	reg [N-M-4:0] a_m, b_m, z_m; // mantissa
+	reg [M:0] a_e, b_e, z_e; // exponent
+	reg a_s, b_s, z_s; // sign
+	
+	reg [1:0] greater; // 01 for a, 10 for b, 11 for both and 00 for neither
+	reg [M:0] abs; // For the absolute difference
+	logic [N-3-M:0] res; // For the addition result
+	
+	always_ff @(posedge clk)
+	begin
+		if (reset)
+		begin
+			a <= 0;
+			b <= 0;
+			a_m <= 0;
+			b_m <= 0;
+			a_e <= 0;
+			b_e <= 0;
+			a_s <= 0;
+			b_s <= 0;
+		end
+		
+		else
+		begin
+			// Unpacking the inputs
+			a <= input_a;
+			a_m <= a[N-M-3:0];
+			a_e <= a[N-2:N-2-M];
+			a_s <= a[N-1];
+			
+			b <= input_b;
+			b_m <= b[N-M-3:0];
+			b_e <= b[N-2:N-2-M];
+			b_s <= b[N-1];
+		end
+	end
+	
+	always_ff @(posedge clk)
+	begin
+		if(~reset)
+		begin
+			// If input_a has the bigger exponent then flag it with greater and find the absolute difference
+			if (a_e > b_e)
+			begin
+				greater <= 2'b01;
+				abs <= a_e - b_e;
+				z_s <= a_s;
+			end
+			// If input_a has the bigger exponent then flag it with greater and find the absolute difference
+			else if (b_e > a_e)
+			begin
+				greater <= 2'b10;
+				abs <= b_e - a_e;
+				z_s <= b_s;
+			end
+			// If the inputs have equal exponent
+			else
+			begin
+				greater <= 2'b00;
+				abs <= 0;
+				// Assigning the overall sign based on the difference between the mantissa
+				if(a_m > b_m)
+				begin
+					z_s <= a_s;
+				end
+				else if(b_m > a_m)
+				begin
+					z_s <= b_s;
+				end
+				else
+				begin
+					z_s <= 0;
+				end
+			end
+		end
+		
+		else
+		begin
+			greater <= 2'b00;
+			abs <= 0;
+			z_s <= 0;
+		end
+	end
+	
+	always_ff @(posedge clk)
+	begin
+		if(~reset)
+		begin
+			// Condition for overflow is that it sets the output to the larger input
+			if (abs > N-2-M) // Shifting by N-2-M would give 0
+			begin
+				if (greater == 2'b01)
+				begin
+					z <= a; // Input a is larger and is translated to the output
+				end
+				else if (greater == 2'b10)
+				begin
+					z <= b; // Input b is larger and is translated to the output
+				end
+				else
+				begin
+					if (a_m >= b_m)
+					begin
+						z <= a; // Equal exponents but a has the larger mantissa
+					end
+					else if (b_m > a_m)
+					begin
+						z <= b; // Equal exponents but b has the larger mantissa
+					end
+				end
+			end
+			
+			else
+			begin
+			   // If a has the bigger exponent
+				if (greater == 2'b01)
+				begin
+					// If the signs are the same then add
+					if (a_s == b_s)
+					begin
+						res <= a_m + (b_m >> (abs-1));
+					end
+					// If they are different then subtract
+					else
+					begin
+						res <= a_m - (b_m >> (abs-1));
+					end
+				end
+				// If b has the bigger exponent
+				else if (greater == 2'b10)
+				begin
+				// If the signs are the same then add
+					if (a_s == b_s)
+					begin
+						res <= b_m + (a_m >> (abs-1));
+					end
+					// If they are different then subtract
+					else
+					begin
+						res <= b_m - (a_m >> (abs-1));
+					end
+				end
+				// If the exponents are equal
+				else
+				begin
+					// If the signs are the same then add
+					if (a_s == b_s)
+					begin
+						res <= a_m + b_m;
+					end
+					// If the signs are different then subtract
+					else
+					begin
+						// First checking which has the bigger mantissa
+						if (a_m > b_m)
+						begin
+							res <= a_m - b_m;
+						end
+						else if (b_m > a_m)
+						begin
+							res <= b_m - a_m;
+						end
+						// If the mantissa are the same as well then the result should be 0
+						else
+						begin
+							res <= 0;
+						end
+					end
+				end
+				// Assigning the mantissa of output the the sum of input mantissa
+				z_m <= res;
+			end
+		end
+		
+		else
+		begin
+			z <= 0;
+			z_m <= 0;
+			res <= 0;
+		end
+	end
+	
+	always_ff @(posedge clk)
+	begin
+		if (~reset)
+		// Packing the output back together
+		begin
+			z[N-1] <= z_s;
+			z[N-2:N-2-M] <= z_e;
+			z[N-3-M:0] <= z_m;
+		end
+		else
+		begin
+			z <= 0;
+		end
+	end
+endmodule : fp_adder