mirror of
https://github.com/YosysHQ/sby.git
synced 2025-04-06 14:24:08 +00:00
86 lines
2.1 KiB
Systemverilog
86 lines
2.1 KiB
Systemverilog
`ifndef WIDTH
|
|
`define WIDTH 4
|
|
`endif
|
|
|
|
module divider #(
|
|
parameter WIDTH=`WIDTH
|
|
) (
|
|
input wire clk,
|
|
input wire start,
|
|
input wire [WIDTH-1:0] dividend,
|
|
input wire [WIDTH-1:0] divisor,
|
|
|
|
output reg done,
|
|
output reg [WIDTH-1:0] quotient,
|
|
output wire [WIDTH-1:0] remainder
|
|
);
|
|
|
|
reg [WIDTH-1:0] acc;
|
|
|
|
reg [WIDTH*2-1:0] sub;
|
|
reg [WIDTH-1:0] pos;
|
|
|
|
assign remainder = acc;
|
|
|
|
always @(posedge clk) begin
|
|
if (start) begin
|
|
acc <= dividend;
|
|
quotient <= 0;
|
|
sub <= divisor << (WIDTH - 1);
|
|
pos <= 1 << (WIDTH - 1);
|
|
done <= 0;
|
|
end else if (!done) begin
|
|
if (acc >= sub) begin
|
|
acc <= acc - sub[WIDTH-1:0];
|
|
quotient <= quotient + pos;
|
|
end
|
|
|
|
sub <= sub >> 1;
|
|
{pos, done} <= pos;
|
|
end
|
|
end
|
|
|
|
|
|
`ifdef FORMAL
|
|
reg [WIDTH-1:0] start_dividend = 0;
|
|
reg [WIDTH-1:0] start_divisor = 0;
|
|
|
|
reg started = 0;
|
|
reg finished = 0;
|
|
reg [$clog2(WIDTH + 1):0] counter = 0;
|
|
|
|
always @(posedge clk) begin
|
|
// Bound the number of cycles until the result is ready
|
|
assert (counter <= WIDTH);
|
|
|
|
if (started) begin
|
|
if (finished || done) begin
|
|
finished <= 1;
|
|
// Make sure result stays until we start a new division
|
|
assert (done);
|
|
|
|
// Check the result
|
|
if (start_divisor == 0) begin
|
|
assert ("ient);
|
|
assert (remainder == start_dividend);
|
|
end else begin
|
|
assert (quotient == start_dividend / start_divisor);
|
|
assert (remainder == start_dividend % start_divisor);
|
|
end
|
|
end else begin
|
|
counter <= counter + 1'b1;
|
|
end
|
|
end
|
|
|
|
// Track the requested inputs
|
|
if (start) begin
|
|
start_divisor <= divisor;
|
|
start_dividend <= dividend;
|
|
started <= 1;
|
|
counter <= 0;
|
|
finished <= 0;
|
|
end
|
|
end
|
|
`endif
|
|
endmodule
|