fp_adder.sv 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. module fp_adder #(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
  2. input logic [N-1:0] input_a, input_b;
  3. input logic clk, reset;
  4. output logic [N-1:0] output_z;
  5. reg [N-2-M:0] a_m, b_m, z_m; // mantissa
  6. reg [M-1:0] a_e, b_e, z_e; // exponent
  7. reg a_s, b_s, z_s; // sign
  8. reg [1:0] greater; // 01 for a, 10 for b, 11 for both and 00 for neither
  9. reg [M:0] abs; // For the absolute difference between exponents
  10. logic [N-2-M:0] res; // For the addition result
  11. always_ff @(posedge clk)
  12. begin
  13. if(~reset)
  14. begin
  15. // Unpacking the inputs
  16. a_m <= input_a[N-M-2:0];
  17. a_e <= input_a[N-2:N-M-1];
  18. a_s <= input_a[N-1];
  19. b_m <= input_b[N-M-2:0];
  20. b_e <= input_b[N-2:N-M-1];
  21. b_s <= input_b[N-1];
  22. // If input_a has the bigger exponent then flag it with greater and find the absolute difference
  23. if (a_e > b_e)
  24. begin
  25. greater <= 2'b01;
  26. abs <= a_e - b_e;
  27. z_s <= a_s;
  28. z_e <= a_e;
  29. end
  30. // If input_a has the bigger exponent then flag it with greater and find the absolute difference
  31. else if (b_e > a_e)
  32. begin
  33. greater <= 2'b10;
  34. abs <= b_e - a_e;
  35. z_s <= b_s;
  36. z_e <= b_e;
  37. end
  38. // If the inputs have equal exponent
  39. else
  40. begin
  41. greater <= 2'b00;
  42. abs <= 0;
  43. z_e <= a_e;
  44. // Assigning the overall sign based on the difference between the mantissa
  45. if(a_m > b_m)
  46. begin
  47. z_s <= a_s;
  48. end
  49. else if(b_m > a_m)
  50. begin
  51. z_s <= b_s;
  52. end
  53. else
  54. begin
  55. z_s <= 0;
  56. end
  57. end
  58. // Condition for overflow is that it sets the output to the larger input
  59. if (abs > N-1-M) // Shifting by N-1-M would give 0
  60. begin
  61. if (greater == 2'b01)
  62. begin
  63. z_m <= a_m; // Input a is larger and is translated to the output
  64. end
  65. else if (greater == 2'b10)
  66. begin
  67. z_m <= b_m; // Input b is larger and is translated to the output
  68. end
  69. else // Shouldn't happen as abs should be 0 for this to occur
  70. begin
  71. if (a_m >= b_m)
  72. begin
  73. z_m <= a_m; // Equal exponents but a has the larger mantissa
  74. end
  75. else if (b_m > a_m)
  76. begin
  77. z_m <= b_m; // Equal exponents but b has the larger mantissa
  78. end
  79. end
  80. end
  81. else
  82. begin
  83. // If a has the bigger exponent
  84. if (greater == 2'b01)
  85. begin
  86. // If the signs are the same then add
  87. if (a_s == b_s)
  88. begin
  89. res <= a_m + (b_m >> (abs-1));
  90. end
  91. // If they are different then subtract
  92. else
  93. begin
  94. res <= a_m - (b_m >> (abs-1));
  95. end
  96. end
  97. // If b has the bigger exponent
  98. else if (greater == 2'b10)
  99. begin
  100. // If the signs are the same then add
  101. if (a_s == b_s)
  102. begin
  103. res <= b_m + (a_m >> (abs-1));
  104. end
  105. // If they are different then subtract
  106. else
  107. begin
  108. res <= b_m - (a_m >> (abs-1));
  109. end
  110. end
  111. // If the exponents are equal
  112. else
  113. begin
  114. // If the signs are the same then add
  115. if (a_s == b_s)
  116. begin
  117. res <= a_m + b_m;
  118. end
  119. // If the signs are different then subtract
  120. else
  121. begin
  122. // First checking which has the bigger mantissa
  123. if (a_m > b_m)
  124. begin
  125. res <= a_m - b_m;
  126. end
  127. else if (b_m > a_m)
  128. begin
  129. res <= b_m - a_m;
  130. end
  131. // If the mantissa are the same as well then the result should be 0
  132. else
  133. begin
  134. res <= 0;
  135. end
  136. end
  137. end
  138. // Assigning the mantissa of output the the sum of input mantissa
  139. z_m <= res;
  140. end
  141. output_z[N-1] <= z_s;
  142. output_z[N-2:N-1-M] <= z_e;
  143. output_z[N-2-M:0] <= z_m;
  144. end
  145. else
  146. begin
  147. a_s <= 0;
  148. a_e <= 0;
  149. a_m <= 0;
  150. b_s <= 0;
  151. b_e <= 0;
  152. b_m <= 0;
  153. z_s <= 0;
  154. z_e <= 0;
  155. z_m <= 0;
  156. greater <= 0;
  157. abs <= 0;
  158. res <= 0;
  159. output_z <= 0;
  160. end
  161. end
  162. endmodule : fp_adder