[clocks] ClockDividerN: make first output edge occur on first input edge

This commit is contained in:
David Biancolin
2020-09-29 16:06:48 -07:00
parent b76972d34b
commit a6ce850391

View File

@@ -7,8 +7,10 @@
module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in); module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in);
localparam DIV_COUNTER_WIDTH = $clog2(DIV); localparam CWIDTH = $clog2(DIV);
localparam LOW_CYCLES = DIV / 2; localparam LOW_CYCLES = DIV / 2;
localparam HIGH_TRANSITION = LOW_CYCLES - 1;
localparam LOW_TRANSITION = DIV - 1;
generate generate
if (DIV == 1) begin if (DIV == 1) begin
@@ -17,19 +19,19 @@ module ClockDividerN #(parameter DIV)(output logic clk_out = 1'b0, input clk_in)
clk_out = clk_in; clk_out = clk_in;
end end
end else begin end else begin
reg [DIV_COUNTER_WIDTH - 1: 0] count = '0; reg [CWIDTH - 1: 0] count = HIGH_TRANSITION[CWIDTH-1:0];
// The blocking assignment to clock out is used to conform what was done // The blocking assignment to clock out is used to conform what was done
// in RC's clock dividers. // in RC's clock dividers.
// It should have the effect of preventing registers in the divided clock // It should have the effect of preventing registers in the divided clock
// domain latching register updates launched by the fast clock-domain edge // domain latching register updates launched by the fast clock-domain edge
// that occurs at the same simulated time (as the divided clock edge). // that occurs at the same simulated time (as the divided clock edge).
always @(posedge clk_in) begin always @(posedge clk_in) begin
if (count == (DIV - 1)) begin if (count == LOW_TRANSITION[CWIDTH-1:0]) begin
clk_out = 1'b0; clk_out = 1'b0;
count <= '0; count <= '0;
end end
else begin else begin
if (count == (LOW_CYCLES - 1)) begin if (count == HIGH_TRANSITION[CWIDTH-1:0]) begin
clk_out = 1'b1; clk_out = 1'b1;
end end
count <= count + 1'b1; count <= count + 1'b1;