blob: 1e09a078ee5d6994c80300eea1366bdef85af2e3 [file] [log] [blame]
// See LICENSE for license details.
/**
* An unsynthesizable divide-by-N clock divider.
* Duty cycle is 100 * (ceil(DIV / 2)) / DIV.
*/
module ClockDividerN #(parameter DIV = 1)(output logic clk_out = 1'b0, input clk_in);
localparam CWIDTH = $clog2(DIV);
localparam LOW_CYCLES = DIV / 2;
localparam HIGH_TRANSITION = LOW_CYCLES - 1;
localparam LOW_TRANSITION = DIV - 1;
generate
if (DIV == 1) begin
// This needs to be procedural because of the assignment on declaration
always @(clk_in) begin
clk_out = clk_in;
end
end else begin
reg [CWIDTH - 1: 0] count = HIGH_TRANSITION[CWIDTH-1:0];
// The blocking assignment to clock out is used to conform what was done
// in RC's clock dividers.
// It should have the effect of preventing registers in the divided clock
// domain latching register updates launched by the fast clock-domain edge
// that occurs at the same simulated time (as the divided clock edge).
always @(posedge clk_in) begin
if (count == LOW_TRANSITION[CWIDTH-1:0]) begin
clk_out = 1'b0;
count <= '0;
end
else begin
if (count == HIGH_TRANSITION[CWIDTH-1:0]) begin
clk_out = 1'b1;
end
count <= count + 1'b1;
end
end
end
endgenerate
endmodule // ClockDividerN