diff options
author | Wojciech Kosior <kwojtus@protonmail.com> | 2020-09-01 10:54:59 +0200 |
---|---|---|
committer | Wojciech Kosior <kwojtus@protonmail.com> | 2020-09-01 11:04:22 +0200 |
commit | ee1f6c47e1eff920068f4bceaf604f9535a2e8a9 (patch) | |
tree | 580eb001a72601d254bb29cc348a529490f84808 /design/div.v | |
parent | cd02ddff8886aa1db29f80d3cc5cf99a349d8258 (diff) | |
download | AGH-engineering-thesis-ee1f6c47e1eff920068f4bceaf604f9535a2e8a9.tar.gz AGH-engineering-thesis-ee1f6c47e1eff920068f4bceaf604f9535a2e8a9.zip |
start anew
Diffstat (limited to 'design/div.v')
-rw-r--r-- | design/div.v | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/design/div.v b/design/div.v new file mode 100644 index 0000000..10db627 --- /dev/null +++ b/design/div.v @@ -0,0 +1,70 @@ +`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 |