To divide a 1 GHz clock down to an average of exactly 622.08 MHz with digital logic only, use a phase accumulator: add 1944 every input cycle, modulo 3125, and produce one output pulse each time the sum wraps. That works because 1000 / 622.08 reduces exactly to 3125 / 1944, so the output alternates between periods of one and two input cycles, the long-run average is exact, and every output edge stays within one input cycle of its ideal position. The result is a clock enable (or gated clock) with bounded jitter, not a clean 50% duty-cycle clock.
The question: design a fractional clock divider in RTL that takes a 1 GHz reference clock down to exactly 622.08 MHz, a real telecom frequency. You cannot use an analogue PLL or DLL, only digital logic.
Key takeaways
- Reduce the ratio to a fraction first: 1 GHz / 622.08 MHz = 3125 / 1944 exactly, about 1.6075.
- Alternate two integer divides (here ÷1 and ÷2) so the average is exact; the accumulator decides which one each time.
- The accumulator is the remainder: it carries the error forward, so the error can never grow beyond one input cycle.
- The same structure handles any ratio N/M by changing two constants.
- The output has deterministic jitter of one input period (1 ns here), so treat it as a clock enable inside the 1 GHz domain, or as a separate clock with its own timing constraints.
Constraints
- The divide ratio is fractional and its decimal form does not terminate: 1 GHz ÷ 622.08 MHz ≈ 1.6075 (exactly 3125/1944 = 1.60751028...).
- The output jitter must stay bounded: no more than ±1 input clock cycle away from the ideal edge position.
- The design must be synthesisable and efficient in area and power.
Hints
- What happens if you alternate between two nearby integer divides, say ÷1 and ÷2, so that the average comes out right?
- Suppose you keep track of a remainder every cycle. What could you do with it?
- The output edges do not need to be perfectly evenly spaced, but the error must never grow without limit. How would you guarantee that?
- If you were asked to support any ratio N/M, not just this one, what structure would handle every fraction?
- How would the design behave if the divided clock drove a separate domain? Would you treat it as fully synchronous?
Step 1: find the exact fraction
622.08 MHz is the SONET OC-12 and SDH STM-4 line rate (12 × 51.84 MHz). Write the ratio as integers: 1,000,000 kHz / 622,080 kHz = 100,000 / 62,208. The greatest common divisor is 32, so the ratio is 3125 / 1944. Since 1944 = 2³ × 3&sup5;, the factor of 3 is why the decimal never terminates, but the fraction is exact and that is all the hardware needs.
So in every 3125 input cycles, we need exactly 1944 output edges. That needs 1181 output periods of two input cycles and 763 periods of one input cycle (763 × 1 + 1181 × 2 = 3125, and 763 + 1181 = 1944).
Step 2: the phase accumulator
Keep a 12-bit accumulator. Each input cycle, add 1944. If the sum reaches 3125 or more, subtract 3125 and emit a pulse. This is the same idea as Bresenham's line algorithm or a direct digital synthesiser: the accumulator holds the fractional phase, and the wrap is the output edge.
| Input cycle | Accumulator before | +1944 | Wrap? | Accumulator after |
|---|---|---|---|---|
| 1 | 0 | 1944 | No | 1944 |
| 2 | 1944 | 3888 | Yes | 763 |
| 3 | 763 | 2707 | No | 2707 |
| 4 | 2707 | 4651 | Yes | 1526 |
| 5 | 1526 | 3470 | Yes | 345 |
| 6 | 345 | 2289 | No | 2289 |
The gaps between pulses are 2, 2, 1, ... input cycles, never more than two and never less than one. The accumulator holds the fractional phase left over after each pulse, and it is always below 3125, so the real output never drifts a full input cycle away from the ideal one. That is the bounded-jitter guarantee.
Step 3: RTL
`timescale 1ns/100ps
// Fractional divider: 1 GHz in, 622.08 MHz average out.
// 1000 / 622.08 = 3125 / 1944 exactly, so add 1944 every input cycle
// modulo 3125 and emit one output pulse each time the accumulator wraps.
module frac_div #(
parameter integer NUM = 1944, // output edges per period
parameter integer DEN = 3125 // input cycles per period
) (
input wire clk,
input wire rst_n,
output reg en // one-cycle enable, 1944 per 3125 cycles
);
reg [11:0] acc; // 0 .. DEN-1 fits in 12 bits
wire [12:0] sum = acc + NUM;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin acc <= 12'd0; en <= 1'b0; end
else if (sum >= DEN) begin acc <= sum - DEN; en <= 1'b1; end
else begin acc <= sum[11:0]; en <= 1'b0; end
endmodule
A self-checking testbench, run over four full periods of 3125 cycles:
`timescale 1ns/100ps
module tb_frac;
reg clk = 0, rst_n = 0;
wire en;
integer cyc = 0, pulses = 0, maxerr_x = 0, err_x, gap = 0, mingap = 99, maxgap = 0;
frac_div u (.clk(clk), .rst_n(rst_n), .en(en));
always #0.5 clk = ~clk; // 1 ns period
always @(posedge clk) if (rst_n) begin
cyc = cyc + 1;
gap = gap + 1;
if (en) begin
pulses = pulses + 1;
if (pulses > 1) begin
if (gap < mingap) mingap = gap;
if (gap > maxgap) maxgap = gap;
end
gap = 0;
end
// error between ideal pulse count and actual, scaled by DEN
err_x = (cyc - 1) * 1944 - pulses * 3125; // en is registered: one cycle late
if (err_x < 0) err_x = -err_x;
if (err_x > maxerr_x) maxerr_x = err_x;
end
initial begin
#2.2 rst_n = 1;
wait (cyc == 3125 * 4 + 1);
@(negedge clk);
$display("cycles %0d, pulses %0d (expected %0d)", cyc, pulses, 1944 * 4);
$display("gap between enables: min %0d, max %0d input cycles", mingap, maxgap);
$display("max phase error %0d/3125 of an input cycle", maxerr_x);
if (pulses == 1944 * 4 && maxerr_x < 3125 && mingap == 1 && maxgap == 2) $display("PASS");
else $display("FAIL");
$finish;
end
endmodule
The run reports 7776 pulses in 12,500 cycles, gaps of one or two cycles, and a worst phase error of 3124/3125 of an input cycle, inside the ±1 cycle limit.
Step 4: turning the enable into a clock
- Best option, a clock enable: keep all downstream logic on the 1 GHz clock and use
enas an enable. Everything stays synchronous and timing analysis is simple. This is how most designs consume a fractional rate. - Gated clock: feed
ento an integrated clock-gating cell (ICG) on the 1 GHz clock. The output is a pulse train with an average of 622.08 MHz, high for half an input cycle per pulse. Define it as a generated clock in SDC; downstream logic sees periods of 1 ns and 2 ns, so it must meet timing at the 1 ns spacing. - Using both edges: running the accumulator at double resolution (on both edges, or with a 2 GHz equivalent) halves the jitter to half an input cycle, at the cost of more complex timing.
Step 5: any ratio N/M
Change the two parameters: NUM is the number of output edges and DEN the number of input cycles in one repeat period, after reducing the fraction. The accumulator needs ceil(log2(DEN)) bits. For ratios above two, the same accumulator chooses between ÷K and ÷(K+1) by adding the wrap to a base integer counter, which is the structure of a dual-modulus divider. When the fraction is very large or irrational, a wide binary accumulator (as in a DDS) gives an approximation with known frequency error.
How interviewers probe this question
- Can you get from 1.6075 to an exact fraction, and do you notice it must be exact for "exactly 622.08 MHz"?
- Do you explain why the error stays bounded instead of just asserting it?
- Do you see that ÷1 means passing an input pulse through, so the output cannot be a 50% duty-cycle clock?
- Do you treat the output as a clock enable or a constrained generated clock, and do you mention the jitter for any downstream SerDes or PLL? A telecom line clock usually needs a cleanup PLL after such a divider, because 1 ns of deterministic jitter is far too much for a line interface.
- Do you consider glitches, reset behaviour and the cost of the comparator and subtractor at 1 GHz?
Common mistakes
- Rounding the ratio to 1.6 or 1.61 and calling the result exact.
- Building the output with combinational logic on the clock path, which can glitch.
- Treating the divided clock as a normal 622 MHz clock in STA, when its shortest period is 1 ns.
- Letting the accumulator overflow its width; 12 bits are needed for values up to 3124, 13 for the sum.
FAQ
Why not a simple counter?
A counter can only divide by integers. Any fixed integer gives the wrong average; the accumulator is what distributes the extra cycles evenly.
Is this a sigma-delta divider?
It is a first-order version of the same idea. Higher-order sigma-delta modulators push the timing error to higher frequencies so a following PLL can filter it more easily, but they allow larger instantaneous error than one cycle.
Does the 1 GHz comparator meet timing?
It is a 13-bit add and compare per cycle, which is achievable at 1 GHz in modern nodes but tight. Pipelining the compare, or precomputing the next two sums, are common fixes.


Your comments will be moderated before it appears here.