How to implement the design of odd frequency dividers in Verilog?
There are two common, FPGA-friendly ways to “divide by an odd number” in Verilog:
-
Stay in one clock domain and generate a clock-enable (CE) pulse every N cycles. (Best practice.)
-
If you truly need a new clock with ~50% duty, use both clock edges (posedge + negedge) to alternate half-period lengths. (Use sparingly; route through a clock buffer.)
1) Preferred: odd divider as a clock-enable pulse
This avoids creating a new clock domain and all the CDC/timing pain. Your logic runs on the original clock, gated by a CE that goes high every N cycles.
Use ce
to step your state machines or to toggle a flop:
Pros: one clean clock domain, simple timing, portable to all FPGAs/ASICs.
2) If you must output a 50% clock for odd N
A 50% duty cycle with odd division isn’t possible with a single edge. The trick is to toggle the output on alternating counts so that one half-cycle lasts floor(N/2)
input cycles and the other half lasts ceil(N/2)
input cycles. Implement that by using both edges (posedge/negedge) of the input clock (or by counting edges).
Generic odd divider with ~50% duty (uses both edges)
Notes:
-
This makes
clk_out
toggle after A edges, then B edges, alternating → average 50% duty for oddN
. -
In most FPGAs it’s better to avoid dual-edge always blocks. An alternative is to count both edges using an input DDR primitive (IDDR) or by doubling the reference with a PLL/MMCM and then dividing by an even number.
-
If you must distribute
clk_out
, feed it into a global clock buffer (e.g.,BUFG
/BUFGCTRL
on Xilinx,Global Clock
on Intel) to avoid skew. -
Prefer PLL/MMCM/DCM/Clocking resources for clocks. Use fabric logic only when absolutely necessary.
Concrete, simple examples
A) Divide-by-3 (50% duty) using posedge+negedge counters (classic)
B) Divide-by-5 (50% duty) with alternating half-period counts
Use the clk_div_odd
generic above with N=5
; it alternates 2 and 3 input edges per half-cycle.
What should you use when?
-
Most FPGA designs: Use the CE pulse method (Section 1). Keep a single clock domain; gate logic with
ce
. -
When an external block needs a real slower clock (and you can’t use a PLL/MMCM):
-
Try to use a vendor clocking primitive (PLL/MMCM/DCM/BUFGCE_DIV).
-
If not possible, the both-edges fabric divider works, but route through a clock buffer and constrain it.
-
评论
发表评论