| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- module fp_adder #(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
- input logic [N-1:0] input_a, input_b;
- input logic clk, reset;
- output logic [N-1:0] output_z;
-
- reg [N-2-M:0] a_m, b_m, z_m; // mantissa
- reg [M-1: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 between exponents
- logic [N-2-M:0] res; // For the addition result
-
-
- always_ff @(posedge clk)
- begin
- if(~reset)
- begin
- // Unpacking the inputs
- a_m <= input_a[N-M-2:0];
- a_e <= input_a[N-2:N-M-1];
- a_s <= input_a[N-1];
-
- b_m <= input_b[N-M-2:0];
- b_e <= input_b[N-2:N-M-1];
- b_s <= input_b[N-1];
-
- // 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;
- z_e <= a_e;
- 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;
- z_e <= b_e;
- end
- // If the inputs have equal exponent
- else
- begin
- greater <= 2'b00;
- abs <= 0;
- z_e <= a_e;
- // 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
- // Condition for overflow is that it sets the output to the larger input
- if (abs > N-1-M) // Shifting by N-1-M would give 0
- begin
- if (greater == 2'b01)
- begin
- z_m <= a_m; // Input a is larger and is translated to the output
- end
- else if (greater == 2'b10)
- begin
- z_m <= b_m; // Input b is larger and is translated to the output
- end
- else // Shouldn't happen as abs should be 0 for this to occur
- begin
- if (a_m >= b_m)
- begin
- z_m <= a_m; // Equal exponents but a has the larger mantissa
- end
- else if (b_m > a_m)
- begin
- z_m <= b_m; // 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
- output_z[N-1] <= z_s;
- output_z[N-2:N-1-M] <= z_e;
- output_z[N-2-M:0] <= z_m;
- end
-
- else
- begin
- a_s <= 0;
- a_e <= 0;
- a_m <= 0;
-
- b_s <= 0;
- b_e <= 0;
- b_m <= 0;
-
- z_s <= 0;
- z_e <= 0;
- z_m <= 0;
-
- greater <= 0;
- abs <= 0;
- res <= 0;
-
- output_z <= 0;
- end
- end
- endmodule : fp_adder
|