`default_nettype none module div #( parameter WIDTH = 16 ) ( input wire clock, input wire start, input wire [WIDTH-1 : 0] dividend, input wire [WIDTH-1 : 0] divisor, output wire [WIDTH-1 : 0] quotient, output wire [WIDTH-1 : 0] remainder, output wire done ); reg [$clog2(WIDTH)-1 : 0] steps; reg [2*WIDTH : 0] work_reg; reg [WIDTH-1 : 0] divisor_latched; wire [WIDTH+1 : 0] work_remainder; wire work_remainder_sign; assign work_remainder = work_reg[2*WIDTH : WIDTH-1]; assign work_remainder_sign = work_remainder[WIDTH + 1]; /* * The following variable represents quotient using digits 1 and -1, * where -1 is internally represented as 0 */ `define MINUS_ONE 1'b0 `define PLUS_ONE 1'b1 wire [WIDTH-1 : 0] work_quotient; assign work_quotient = work_reg[WIDTH-1 : 0]; reg work_quotient_ready; always @ (posedge clock) begin if (start) begin steps <= WIDTH - 1; work_reg <= dividend; divisor_latched <= divisor; work_quotient_ready <= 0; end else begin if (steps) steps <= steps - 1; else work_quotient_ready <= 1; if (!work_quotient_ready) begin work_reg[WIDTH-1 : 1] <= work_reg[WIDTH-2 : 0]; if (work_remainder_sign) begin /* work remainder negative */ work_reg[0] <= `MINUS_ONE; /* Filling up quotient */ work_reg[2*WIDTH : WIDTH] <= work_remainder + divisor_latched; end else begin /* work remainder equal 0 or positive */ work_reg[0] <= `PLUS_ONE; /* Filling up quotient */ work_reg[2*WIDTH : WIDTH] <= work_remainder - divisor_latched; end end end end // always @ (posedge clock) assign quotient = work_quotient - ~work_quotient - work_remainder_sign; assign remainder = (work_remainder >> 1) + (work_remainder_sign ? divisor_latched : 0); assign done = work_quotient_ready && !start; endmodule // div