Digital Design / Module 5: Counters and frequency dividers
29. Divide by 2, 4 and any even number
Create slower clocks correctly.
Lab: Frequency divider lab
The idea
Dividing a clock means producing a slower clock from a faster one. The simplest divider is a flop that feeds back its inverted output: it toggles at every rising edge, so it runs at half the frequency with a 50% duty cycle.
always_ff @(posedge clk)
if (rst) q <= 1'b0;
else q <= ~q;Any even number
To divide by N, toggle every N/2 input cycles. Divide-by-6 toggles every 3 cycles.
module div_even #(parameter N = 6) (
input clk, rst, output reg out
);
reg [$clog2(N)-1:0] cnt;
always_ff @(posedge clk)
if (rst) begin
cnt <= '0;
out <= 1'b0;
end else if (cnt == N/2 - 1) begin
cnt <= '0;
out <= ~out;
end else
cnt <= cnt + 1'b1;
endmoduleThe output is high for three input cycles and low for three, so the duty cycle is exactly 50%.
Clock or enable?
In most cases, you don't need a second clock at all. Generate a one-cycle enable pulse every N cycles, and keep the slower logic on the original clock. That leaves one , with no extra clock tree and no crossing problems. Make a true divided clock only when something requires one, such as an output pin or a block running at low power.
In real chips
A divided clock is a new clock for timing. It requires a create_generated_clock constraint, so that the timing tool understands its relationship to the source. between the two also needs care. Real chips commonly use dedicated clock-divider cells, not plain RTL flops.
Common mistake
Driving flops from a divider's output without telling the timing tools. The tool will then either skip those paths or time them wrongly, and the bug can surface in silicon. Try the lab to see how the output tracks the count.
Key ideas
- Toggle a flop to halve the frequency.
- Even N: toggle every N/2 input cycles.
- In real chips, generated clocks need constraints and clock-tree care.
Your exercise
Find the bug
This code has one deliberate bug. Read the symptom, then click the line you think is wrong.
The fix
else if (cnt == N/2 - 1) begin cnt <= 0; out <= ~out; end
Why it failed
To toggle every 3 clocks, cnt has to count 0, 1, 2, so the compare must be N/2 - 1. Comparing with N/2 adds one extra clock per half period. Counters that start at 0 almost always compare against one less than the count you want.
Interview questions
coreDivide-by-2 circuit?
A flop with D fed by its inverted Q.
basicWith a 100 MHz input clock, what does a flop with its inverted output fed back to D produce? What do you get if a counter toggles its output every two input cycles instead?
The toggle flop changes at every rising edge, so its output is 50 MHz with a 50% duty cycle. Toggling every two cycles gives a period of four input cycles, so 25 MHz, again at 50% duty. In general, toggling every N/2 cycles divides by N.
basicFor a divide-by-10 with 50% duty cycle using a counter that starts at 0, how many input cycles between output toggles, and what count value do you compare against?
The output must be high for 5 cycles and low for 5, so it toggles every 5 input cycles. Counting 0, 1, 2, 3, 4 is five cycles, so the compare value is N/2 - 1 = 4, at which the counter resets and the output toggles.
coreThis divider is instantiated with N = 6 but produces an output with a period of 8 input cycles. Why?
always @(posedge clk)
if (rst) begin cnt <= 0; out <= 1'b0; end
else if (cnt == N/2) begin
cnt <= 0;
out <= ~out;
end else
cnt <= cnt + 1'b1;The compare uses N/2 instead of N/2 - 1. Counting from 0 to 3 takes four cycles, so the output toggles every four cycles and the period is eight. Changing the compare to cnt == N/2 - 1 makes it toggle every three cycles and divide by 6.
coreA 120 MHz clock is divided by 6 with 50% duty cycle. What are the output frequency, period and high time?
120 / 6 = 20 MHz, so the period is 50 ns. With 50% duty, the output is high for 3 input cycles, which is 3 x 8.33 ns = 25 ns.
coreSlower logic needs to update at one sixth of the system clock. Why is an enable pulse usually better than a divided clock?
An enable keeps everything on one clock, so there is only one clock tree, no extra skew to manage, and no clock-domain crossing between fast and slow logic. Timing tools handle it as normal single-clock logic, possibly with multicycle constraints. A true divided clock is only worth its cost when something needs an actual clock, such as an output pin or a block running at low power.
coreWrite logic that produces a one-cycle enable pulse every 6 clock cycles.
always @(posedge clk)
if (rst) begin
cnt <= 3'd0;
tick <= 1'b0;
end else begin
tick <= (cnt == 3'd5);
cnt <= (cnt == 3'd5) ? 3'd0 : cnt + 3'd1;
endCount 0 to 5 and wrap, and register a pulse when the count is 5, as in the code. The tick is high for exactly one cycle in every six and is glitch-free because it comes from a flop. Slower logic then uses if (tick) inside its own always @(posedge clk) block.
advancedYou do use a divided clock from a flop to drive other flops. What must you tell the timing tools, and what goes wrong if you don't?
Declare it as a generated clock, with create_generated_clock, describing its source and divide ratio. Then the tool knows its edges are tied to the source clock and can time paths between the two domains and within the new one. Without it, the tool may skip those paths or time them against the wrong waveform, and a real violation can reach silicon. The divided clock's edges also come a clock-to-Q later than the source's, which adds skew that clock-tree work must handle.
advancedSomeone makes a divided clock by decoding a binary counter combinationally, for example clkout = (cnt == 2'd0) | (cnt == 2'd1). Why is this risky as a clock?
When the counter steps between values where more than one bit changes, such as 1 to 2, the bits do not change at exactly the same time, so the decode can glitch through an unintended value for a moment. On a data signal that would settle before the next edge, but on a clock it can create an extra edge. A clock output should come directly from a flop, which is why the toggle structure is preferred.