1
0

FPDivider.v 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * 32-bit multicycle fixed-point divider
  3. */
  4. module FPDivider #(
  5. parameter WIDTH=32, // width of numbers in bits (integer and fractional)
  6. parameter FBITS=16 // fractional bits within WIDTH
  7. ) (
  8. input clk, // clock
  9. input rst, // reset
  10. input start, // start calculation
  11. input write_a,
  12. output reg busy = 1'b0, // calculation in progress
  13. output reg done = 1'b0, // calculation is complete (high for one tick)
  14. output reg valid = 1'b0, // result is valid
  15. output reg dbz = 1'b0, // divide by zero
  16. output reg ovf = 1'b0, // overflow
  17. input signed [WIDTH-1:0] a_in, // dividend (numerator)
  18. input signed [WIDTH-1:0] b, // divisor (denominator)
  19. output reg signed [WIDTH-1:0] val = 32'd0 // result value: quotient
  20. );
  21. reg signed [WIDTH-1:0] a = 0;
  22. always @(posedge clk)
  23. begin
  24. if (write_a)
  25. begin
  26. a <= a_in;
  27. end
  28. end
  29. localparam WIDTHU = WIDTH - 1; // unsigned widths are 1 bit narrower
  30. localparam FBITSW = (FBITS == 0) ? 1 : FBITS; // avoid negative vector width when FBITS=0
  31. localparam SMALLEST = {1'b1, {WIDTHU{1'b0}}}; // smallest negative number
  32. localparam ITER = WIDTHU + FBITS; // iteration count: unsigned input width + fractional bits
  33. reg [$clog2(ITER):0] i; // iteration counter (allow ITER+1 iterations for rounding)
  34. reg a_sig = 1'b0;
  35. reg b_sig = 1'b0;
  36. reg sig_diff = 1'b0; // signs of inputs and whether different
  37. reg [WIDTHU-1:0] au = 0;
  38. reg [WIDTHU-1:0] bu = 0; // absolute version of inputs (unsigned)
  39. reg [WIDTHU-1:0] quo = 0;
  40. reg [WIDTHU-1:0] quo_next = 0; // intermediate quotients (unsigned)
  41. reg [WIDTHU:0] acc = 0;
  42. reg [WIDTHU:0] acc_next = 0; // accumulator (unsigned but 1 bit wider)
  43. // input signs
  44. always @(*)
  45. begin
  46. a_sig = a[WIDTH-1+:1];
  47. b_sig = b[WIDTH-1+:1];
  48. end
  49. // division algorithm iteration
  50. always @(*)
  51. begin
  52. if (acc >= {1'b0, bu}) begin
  53. acc_next = acc - bu;
  54. {acc_next, quo_next} = {acc_next[WIDTHU-1:0], quo, 1'b1};
  55. end else begin
  56. {acc_next, quo_next} = {acc, quo} << 1;
  57. end
  58. end
  59. // calculation state machine
  60. parameter IDLE = 5'd0;
  61. parameter INIT = 5'd1;
  62. parameter CALC = 5'd2;
  63. parameter ROUND = 5'd3;
  64. parameter SIGN = 5'd4;
  65. parameter DONE = 5'd5;
  66. reg [2:0] state = IDLE;
  67. always @(posedge clk) begin
  68. done <= 0;
  69. case (state)
  70. INIT: begin
  71. state <= CALC;
  72. ovf <= 0;
  73. i <= 0;
  74. {acc, quo} <= {{WIDTHU{1'b0}}, au, 1'b0}; // initialize calculation
  75. end
  76. CALC: begin
  77. if (i == WIDTHU-1 && quo_next[WIDTHU-1:WIDTHU-FBITSW] != 0) begin // overflow
  78. state <= DONE;
  79. busy <= 0;
  80. done <= 1;
  81. ovf <= 1;
  82. end else begin
  83. if (i == ITER-1) state <= ROUND; // calculation complete after next iteration
  84. i <= i + 1;
  85. acc <= acc_next;
  86. quo <= quo_next;
  87. end
  88. end
  89. ROUND: begin // Gaussian rounding
  90. state <= SIGN;
  91. if (quo_next[0] == 1'b1) begin // next digit is 1, so consider rounding
  92. // round up if quotient is odd or remainder is non-zero
  93. if (quo[0] == 1'b1 || acc_next[WIDTHU:1] != 0) quo <= quo + 1;
  94. end
  95. end
  96. SIGN: begin // adjust quotient sign if non-zero and input signs differ
  97. state <= DONE;
  98. if (quo != 0) val <= (sig_diff) ? {1'b1, -quo} : {1'b0, quo};
  99. busy <= 0;
  100. done <= 1;
  101. valid <= 1;
  102. end
  103. DONE: begin
  104. done <= 1;
  105. state <= IDLE;
  106. end
  107. default: begin // IDLE
  108. if (start) begin
  109. valid <= 0;
  110. if (b == 0) begin // divide by zero
  111. state <= DONE;
  112. busy <= 0;
  113. done <= 1;
  114. dbz <= 1;
  115. ovf <= 0;
  116. end else if (a == SMALLEST || b == SMALLEST) begin // overflow
  117. state <= DONE;
  118. busy <= 0;
  119. done <= 1;
  120. dbz <= 0;
  121. ovf <= 1;
  122. end else begin
  123. state <= INIT;
  124. au <= (a_sig) ? -a[WIDTHU-1:0] : a[WIDTHU-1:0]; // register abs(a)
  125. bu <= (b_sig) ? -b[WIDTHU-1:0] : b[WIDTHU-1:0]; // register abs(b)
  126. sig_diff <= (a_sig ^ b_sig); // register input sign difference
  127. busy <= 1;
  128. dbz <= 0;
  129. ovf <= 0;
  130. end
  131. end
  132. end
  133. endcase
  134. if (rst) begin
  135. state <= IDLE;
  136. busy <= 0;
  137. done <= 0;
  138. valid <= 0;
  139. dbz <= 0;
  140. ovf <= 0;
  141. val <= 0;
  142. end
  143. end
  144. endmodule