Clocks, Resets, and PLLs
Clocking discipline is one of the strongest predictors of FPGA design quality. A design can be logically correct and still fail if clocks are routed through ordinary LUT fabric, resets are released unsafely, or PLL outputs are used before they are locked.
Learning Objectives
You will learn to:
- explain why FPGA clocks use dedicated routing resources;
- use clock-enable pulses instead of fabric-generated clocks;
- choose synchronous and asynchronous reset strategies intentionally;
- use PLL/MMCM lock signals safely;
- constrain generated clocks and review each clock domain.
Clocks Are Not Ordinary Signals
FPGAs provide dedicated global and regional clock networks. These networks minimize skew so many flip-flops see the same edge at nearly the same time. A clock routed through LUTs and ordinary interconnect has uncontrolled skew and can create setup, hold, and CDC-like failures.
Bad beginner pattern:
reg [23:0] counter;
wire slow_clk = counter[23];
always @(posedge slow_clk) begin
led <= ~led;
end
This creates a new clock from fabric logic. The timing tools may not understand it correctly, and the signal does not use a proper clock network unless explicitly promoted through vendor resources.
Better pattern:
reg [26:0] div;
wire tick_1hz = (div == 27'd99_999_999);
always @(posedge clk) begin
if (tick_1hz)
div <= 27'd0;
else
div <= div + 1'b1;
end
always @(posedge clk) begin
if (tick_1hz)
led <= ~led;
end
All registers still use the real clk. The clock enable controls when selected registers update.
Clock Enables
A clock enable is a one-cycle condition sampled by registers on the normal clock edge. It is ideal for slow counters, LED blinkers, UART baud ticks, periodic sampling, and state-machine pacing.
Use this rule:
Use one real clock domain plus enables unless the design truly needs another clock frequency or phase.
Clock enables are not free: high-fanout enables can affect timing. Register or duplicate enables when the timing report shows fanout problems.
PLLs and MMCMs
PLL and MMCM blocks generate related clocks from an input clock. Depending on the FPGA family, they can:
- multiply frequency;
- divide frequency;
- shift phase;
- reduce jitter in supported modes;
- deskew clocks for external interfaces;
- report a
lockedstatus.
Example relationships:
| Input clock | Generated clock | Ratio | Period |
|---|---|---|---|
| 100 MHz | 50 MHz | divide by 2 | 20 ns |
| 100 MHz | 200 MHz | multiply by 2 | 5 ns |
| 125 MHz | 25 MHz | divide by 5 | 40 ns |
Each generated clock must be visible to timing analysis through vendor constraints or generated-clock inference.
Reset Strategy
Reset exists to put control logic into a known state. It is not a substitute for correct initialization, valid handshakes, or safe startup sequencing.
Common choices:
| Reset style | Strength | Risk |
|---|---|---|
| Synchronous reset | Releases on a clock edge and is easy for STA | Needs a running clock |
| Asynchronous assert, synchronous release | Can react immediately but exits cleanly | Needs one synchronizer per clock domain |
| Fully asynchronous reset | Simple to describe | Release can violate timing across many flops |
| No reset on datapath registers | Saves routing and can improve timing | Logic must tolerate unknown startup data until valid |
Reset only what must be reset. Control state, valid flags, counters, and interfaces usually need reset. Deep datapaths often only need valid bits reset.
Reset Release with PLL Lock
Dependent logic should stay in reset until the PLL is locked and reset release has been synchronized into that clock domain.
Verilog pattern:
reg [1:0] rst_pipe = 2'b11;
wire rst_async = external_reset | ~pll_locked;
always @(posedge clk) begin
if (rst_async)
rst_pipe <= 2'b11;
else
rst_pipe <= {rst_pipe[0], 1'b0};
end
assign rst = rst_pipe[1];
This asserts reset immediately when requested or when the PLL is unlocked, then releases reset synchronously to clk.
Worked Example: LED Blink with One Clock
For a 100 MHz board clock and a 1 Hz LED toggle:
cycles per second = 100,000,000
counter terminal count = 100,000,000 - 1
counter bits needed = ceil(log2(100,000,000)) = 27
The design needs one real clock, one 27-bit counter, and a one-cycle enable. It does not need a divided fabric clock.
Practical Clock Review
Before signoff:
- list every clock domain in the design;
- confirm each real clock reaches a clock-capable pin or PLL output;
- confirm every primary and generated clock is constrained;
- check that reset release is synchronized per domain;
- check that signals crossing between domains use CDC structures;
- inspect high-fanout enables and resets in the timing report;
- verify PLL
lockedparticipates in startup sequencing.
Common Mistakes
- Creating clocks with counter bits, LUT gates, or ordinary combinational logic.
- Using one asynchronous reset release across multiple unrelated domains.
- Ignoring PLL
lockedduring startup. - Forgetting generated-clock constraints.
- Resetting every datapath register and making routing harder.
- Using a clock enable as if it solved CDC between two real clocks.
Summary
Use dedicated FPGA clock resources for clocks, clock enables for slower behavior inside one domain, PLLs/MMCMs for real generated clocks, and synchronized reset release for each clock domain. Clocking is part of the architecture, not a cleanup step after the RTL is written.
Next: Clock-Domain Crossing.
Further Reading
- FPGA vendor clocking resource user guides
- AMD UltraFast reset and clocking methodology guidance
- Intel FPGA clock control block and PLL documentation
- Vendor timing-constraints guides for generated clocks