|
| 1 | +//-------------------------------------------------------------------------------- |
| 2 | +// NDivide.v |
| 3 | +// Konstantin Pavlov, pavlovconst@gmail.com |
| 4 | +//-------------------------------------------------------------------------------- |
| 5 | + |
| 6 | +// INFO -------------------------------------------------------------------------------- |
| 7 | +// Primitive integer divider |
| 8 | +// Unsigned inputs, y should be < or == x |
| 9 | + |
| 10 | + |
| 11 | +/* --- INSTANTIATION TEMPLATE BEGIN --- |
| 12 | +
|
| 13 | +NDivide ND1 ( |
| 14 | + .clk( ), |
| 15 | + .nrst( 1'b1 ), |
| 16 | + .d_start( ), |
| 17 | + .d_busy( ), |
| 18 | + .d_done( ), |
| 19 | + .x( ), |
| 20 | + .y( ), |
| 21 | + .q( ), |
| 22 | + .r( ) |
| 23 | + ); |
| 24 | +defparam ND1.XBITS = 32; |
| 25 | +defparam ND1.YBITS = 32; |
| 26 | +
|
| 27 | +--- INSTANTIATION TEMPLATE END ---*/ |
| 28 | + |
| 29 | + |
| 30 | +module NDivide(clk,nrst,d_start,d_busy,d_done,x,y,q,r); |
| 31 | + |
| 32 | +parameter XBITS = 32; |
| 33 | +parameter YBITS = 32; |
| 34 | + |
| 35 | +input wire clk; |
| 36 | +input wire nrst; |
| 37 | + |
| 38 | +input wire d_start; |
| 39 | +output reg d_busy = 0; |
| 40 | +output wire d_done; |
| 41 | + |
| 42 | +input wire [(XBITS-1):0] x; |
| 43 | +input wire [(YBITS-1):0] y; |
| 44 | +output reg [(XBITS-1):0] q = 0; |
| 45 | +output wire [(YBITS-1):0] r; |
| 46 | + |
| 47 | +reg [(XBITS+YBITS-1):0] x_buf = 0; |
| 48 | +reg [(YBITS-1):0] y_buf = 0; |
| 49 | +reg [31:0] i = 0; |
| 50 | + |
| 51 | +wire [(YBITS+XBITS-1):0] shift_y; |
| 52 | +wire [(YBITS+XBITS-1):0] x_buf_sub_shift_y; |
| 53 | +assign |
| 54 | + shift_y[(YBITS+XBITS-1):0] = y_buf[(YBITS-1):0] << i[31:0], |
| 55 | + x_buf_sub_shift_y[(YBITS+XBITS-1):0] = x_buf[(YBITS+XBITS-1):0] - shift_y[(YBITS+XBITS-1):0]; |
| 56 | + |
| 57 | +always @ (posedge clk) begin |
| 58 | + if (~nrst) begin |
| 59 | + q[(XBITS-1):0] <= 0; |
| 60 | + |
| 61 | + i[31:0] <= 0; |
| 62 | + x_buf[(XBITS+YBITS-1):0] <= 0; |
| 63 | + y_buf[(YBITS-1):0] <= 0; |
| 64 | + d_busy <= 0; |
| 65 | + end else begin |
| 66 | + if (~d_busy) begin |
| 67 | + if (d_start) begin |
| 68 | + i[31:0] <= (XBITS-1); |
| 69 | + x_buf[(XBITS+YBITS-1):0] <= x[(XBITS-1):0]; |
| 70 | + y_buf[(YBITS-1):0] <= y[(YBITS-1):0]; |
| 71 | + d_busy <= 1; |
| 72 | + end // d_start |
| 73 | + end else begin |
| 74 | + |
| 75 | + // this condition means crossing of zero boundary |
| 76 | + if (x_buf_sub_shift_y[(YBITS+XBITS-1):0] > x_buf[(XBITS+YBITS-1):0]) begin |
| 77 | + q[i[31:0]] <= 0; |
| 78 | + end else begin |
| 79 | + q[i[31:0]] <= 1; |
| 80 | + x_buf[(XBITS+YBITS-1):0] <= x_buf_sub_shift_y[(YBITS+XBITS-1):0]; |
| 81 | + end |
| 82 | + |
| 83 | + if (i[31:0] != 0) begin |
| 84 | + i[31:0] <= i[31:0] - 1; |
| 85 | + end else begin |
| 86 | + d_busy <= 0; |
| 87 | + end |
| 88 | + |
| 89 | + end // ~d_busy |
| 90 | + end // ~nrst |
| 91 | +end |
| 92 | + |
| 93 | +assign |
| 94 | + d_done = d_busy && ( i[31:0] == 0 ), |
| 95 | + r[(XBITS-1):0] = x_buf[(XBITS+YBITS-1):0]; |
| 96 | + |
| 97 | +endmodule |
0 commit comments