FPDivider.v 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. `timescale 1ns / 1ps // NW 16.9.2016
  2. module FPDivider(
  3. input clk, run,
  4. input [31:0] x,
  5. input [31:0] y,
  6. output stall,
  7. output [31:0] z);
  8. reg [4:0] S; // state
  9. reg [23:0] R;
  10. reg [25:0] Q;
  11. wire sign;
  12. wire [7:0] xe, ye;
  13. wire [8:0] e0, e1;
  14. wire [24:0] r0, r1, d;
  15. wire [25:0] q0;
  16. wire [24:0] z0, z1;
  17. assign sign = x[31]^y[31];
  18. assign xe = x[30:23];
  19. assign ye = y[30:23];
  20. assign e0 = {1'b0, xe} - {1'b0, ye};
  21. assign e1 = e0 + 126 + Q[25];
  22. assign stall = run & ~(S == 26);
  23. assign r0 = (S == 0) ? {2'b01, x[22:0]} : {R, 1'b0};
  24. assign r1 = d[24] ? r0 : d;
  25. assign d = r0 - {2'b01, y[22:0]};
  26. assign q0 = (S == 0) ? 0 : Q;
  27. assign z0 = Q[25] ? Q[25:1] : Q[24:0];
  28. assign z1 = z0 + 1;
  29. assign z = (xe == 0) ? 0 :
  30. (ye == 0) ? {sign, 8'b11111111, 23'b0} : // div by 0
  31. (~e1[8]) ? {sign, e1[7:0], z1[23:1]} :
  32. (~e1[7]) ? {sign, 8'b11111111, z0[23:1]} : 0; // NaN
  33. always @ (posedge(clk)) begin
  34. R <= r1[23:0];
  35. Q <= {q0[24:0], ~d[24]};
  36. S <= run ? S+1 : 0;
  37. end
  38. endmodule