fp_adder.sv 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. typedef enum logic [1:0]{
  2. greater_a,
  3. greater_b,
  4. equal_ab
  5. } grater_state;
  6. module fp_adder#(parameter N=16, M=5)(input_a, input_b, output_z, clk, reset);
  7. localparam K=N-M-1; // Size of mantissa
  8. input reg [N-1:0] input_a, input_b;
  9. input logic clk, reset;
  10. output reg [N-1:0] output_z;
  11. reg [K-1:0] a_m0, b_m0; // mantissa
  12. reg [K-1:0] a_m1, b_m1, z_m2;
  13. reg [K*2-1:0] z_m1a, z_m1b, z_m1z; // Double mantissa
  14. reg z_m1s;
  15. reg [M-1:0] a_e0, b_e0; // exponent
  16. reg [M-1:0] z_e1, z_e2;
  17. reg a_s0, b_s0; // sign
  18. reg a_s1, b_s1, z_s1, z_s2;
  19. grater_state greater; // 01 for a, 10 for b, 11 for both and 00 for neither
  20. reg [M:0] abs; // For the absolute difference between exponents
  21. always_comb begin
  22. output_z = {z_s2, z_e2, z_m2};
  23. z_m1a = {a_m1, {K{1'b0}}};
  24. z_m1b = {b_m1, {K{1'b0}}};
  25. // If a has the bigger exponent
  26. if (greater == greater_a)
  27. begin
  28. // If the signs are the same then add
  29. if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1a+(z_m1b >> abs - 2);
  30. // If they are different then subtract
  31. else {z_m1s, z_m1z} = z_m1a-(z_m1b >> abs - 2);
  32. end
  33. // If b has the bigger exponent
  34. else if (greater == greater_b)
  35. begin
  36. // If the signs are the same then add
  37. if (a_s1 == b_s1) {z_m1s, z_m1z} = z_m1b+(z_m1a >> abs - 2);
  38. // If they are different then subtract
  39. else {z_m1s, z_m1z} = z_m1b-(z_m1a >> abs - 2);
  40. end
  41. // If the exponents are equal
  42. else
  43. begin
  44. // If the signs are the same then add
  45. if (a_s1 == b_s1) {z_m1s, z_m1z} = (z_m1a + z_m1b) >> 1;
  46. // If the signs are different then subtract
  47. else
  48. begin
  49. // First checking which has the bigger mantissa
  50. if (a_m1 > b_m1) {z_m1s, z_m1z} = z_m1a-z_m1b;
  51. else if (b_m1 > a_m1) {z_m1s, z_m1z} = z_m1b-z_m1a;
  52. // If the mantissa are the same as well then the result should be 0
  53. else {z_m1s, z_m1z} = 0;
  54. end
  55. end
  56. end
  57. always_ff @(posedge clk)
  58. begin
  59. if (~reset)
  60. begin
  61. // Unpacking the inputs
  62. a_m0 <= input_a[K-1:0];
  63. a_e0 <= input_a[N-2:K];
  64. a_s0 <= input_a[N-1];
  65. b_m0 <= input_b[K-1:0];
  66. b_e0 <= input_b[N-2:K];
  67. b_s0 <= input_b[N-1];
  68. // Second stage
  69. a_m1 <= a_m0;
  70. a_s1 <= a_s0;
  71. b_m1 <= b_m0;
  72. b_s1 <= b_s0;
  73. z_e2 <= z_e1;
  74. z_s2 <= z_s1;
  75. // If input_a has the bigger exponent then flag it with greater and find the absolute difference
  76. if (a_e0 > b_e0)
  77. begin
  78. greater <= greater_a;
  79. abs <= a_e0-b_e0;
  80. z_s1 <= a_s0;
  81. z_e1 <= a_e0;
  82. end
  83. // If input_a has the bigger exponent then flag it with greater and find the absolute difference
  84. else if (b_e0 > a_e0)
  85. begin
  86. greater <= greater_b;
  87. abs <= b_e0-a_e0;
  88. z_s1 <= b_s0;
  89. z_e1 <= b_e0;
  90. end
  91. // If the inputs have equal exponent
  92. else
  93. begin
  94. greater <= equal_ab;
  95. abs <= -1;
  96. z_e1 <= a_e0;
  97. // Assigning the overall sign based on the difference between the mantissa
  98. if (a_m0 > b_m0) z_s1 <= a_s0;
  99. else if (b_m0 > a_m0) z_s1 <= b_s0;
  100. else z_s1 <= 0;
  101. end
  102. // Condition for overflow is that it sets the output to the larger input
  103. if (abs > K) // Shifting by N-1-M would give 0
  104. begin
  105. z_m2 <= (greater == greater_a) ? a_m1 : b_m1;
  106. // Input a is larger and is translated to the output
  107. // if (greater == greater_a) z_m0 <= a_m1;
  108. // Input b is larger and is translated to the output
  109. // else if (greater == greater_b) z_m0 <= b_m1;
  110. // Shouldn't happen as abs should be 0 for this to occur
  111. // else begin
  112. // if (a_m1 >= b_m1) z_m0 <= a_m1; // Equal exponents but a has the larger mantissa
  113. // else if (b_m1 > a_m1) z_m0 <= b_m1; // Equal exponents but b has the larger mantissa
  114. // end
  115. end
  116. else
  117. begin
  118. z_m2 <= z_m1z[K*2-1:K];
  119. end
  120. end
  121. else
  122. begin
  123. a_m0 <= 0;
  124. a_e0 <= 0;
  125. a_s0 <= 0;
  126. b_m0 <= 0;
  127. b_e0 <= 0;
  128. b_s0 <= 0;
  129. a_m1 <= 0;
  130. b_m1 <= 0;
  131. z_e2 <= 0;
  132. z_s2 <= 0;
  133. z_s1 <= 0;
  134. z_e1 <= 0;
  135. z_s2 <= 0;
  136. z_e2 <= 0;
  137. z_m2 <= 0;
  138. greater <= equal_ab;
  139. abs <= 0;
  140. end
  141. end
  142. endmodule : fp_adder