Hardware Engineering · FPGAs
Clock Networks, Global Buffers, and Skew Budgets
Why a clock reaches every register through a dedicated balanced tree, what skew and jitter cost a timing budget, and when a clock must be routed on general interconnect instead.
A clock is the one signal in a synchronous design that must reach essentially every register, and it must reach them at nearly the same instant. In an ASIC the clock tree is inserted by the physical design tool, balanced by construction. In an FPGA the tree already exists in silicon, built from dedicated low-skew buffers and a symmetric distribution network, and the designer’s job is to choose how to use it and to keep the clock’s own uncertainty out of the data path budget.
The dedicated distribution tree
Clock-capable inputs on an FPGA do not connect to the general routing fabric. They enter dedicated buffers that drive vertical spines, and from those spines horizontal distribution lines reach every logic column. The tree is built so that the path length from the buffer to any register is as close to equal as the layout allows, which is what makes skew small: the device’s timing model reports it as a fraction of a nanosecond, and that figure is carried explicitly into every path calculation.
Two properties follow. First, a clock that arrives on a general-purpose input pin and is routed through the fabric to reach registers will have large and unpredictable skew, because the route to each register is different and the delays accumulate. Second, the number of global buffers is finite, usually a small multiple of the number of clock regions, and they are a resource that must be budgeted like any other.
The buffers come in types. A global clock buffer drives the full tree with minimal skew and is the right choice for a clock that reaches registers across the die. A regional buffer drives only part of the tree, with somewhat less insertion delay and a smaller reach, which matters when a clock is confined to one area. A local buffer drives a small network within a single region, intended for high-fanout non-clock signals rather than clocks. Using a global buffer for a signal that reaches only one region wastes a scarce resource; using a local buffer for a signal that must reach everywhere produces a design that either fails to route or routes with skew large enough to break setup.
Clock skew, insertion delay, and what the tools assume
Skew is the difference in arrival time of the same clock edge at two different registers. Insertion delay is the time from the clock source to the register. Skew matters because a timing path between two registers is affected by it: if the launching register’s clock arrives later than the capturing register’s, the path has less time; if earlier, more. Setup analysis subtracts the skew that hurts and adds the skew that helps, and hold analysis does the reverse.
The conventional formulation makes the roles clear. For a path from register A to register B with combinational delay $d$, setup requires
$$d \le T - t_{su} - t_{cq} - \text{skew}_{setup} - \text{jitter} - \text{uncertainty}$$
and hold requires
$$d \ge t_{hold} - t_{cq} + \text{skew}_{hold}.$$
The uncertainty term is where the tool’s pessimism lives. It is a user-supplied allowance, set on the clock constraint, that covers jitter, power-supply variation, and any modelling gap the tool cannot resolve. It is subtracted from the available time on every path, so a value chosen too generously silently gives away performance across the whole design, and a value chosen too tightly produces a report that claims timing is met when hardware will not meet it. The mechanism and the constraint syntax are covered in timing constraints and clock definitions.
Jitter itself has two relevant forms. Period jitter is the variation of one clock period from its nominal value; cycle-to-cycle jitter is the variation between adjacent periods. For a single-cycle path, period jitter matters; for a path that takes several cycles, the accumulated jitter over that interval matters. A clock generated by a phase-locked loop inside the device inherits the reference clock’s jitter plus the loop’s own contribution, and the loop’s output jitter is specified in the device data sheet for particular configurations.
Generated clocks and the phase-locked loop
The device contains clock management tiles, each with a phase-locked loop and often a mixed-mode clock manager, which can multiply, divide, and phase-shift a reference clock. The output is a new clock with a specified relationship to the input, and the timing tool needs to know that relationship or every path between the two clock domains will be analysed as asynchronous.
Declaring the relationship is the point of a generated clock constraint. When a clock is produced by a PLL or a clock divider in the fabric, the constraint must describe its source and its division or multiplication factor. Without that, the tool treats the derived clock as unrelated to its parent, and either reports unbounded paths or, worse, silently ignores them.
A divider built from a counter in the logic fabric is a common source of trouble. The divided clock is a real clock, but it is generated by general logic and distributed through general routing unless it is explicitly placed on a global buffer. Registers clocked by it, and registers clocked by the original, form a multicycle relationship that must be declared, and the divided clock’s own skew is whatever the fabric routing produces. The alternative, and the one that avoids the whole category of problem, is to keep one clock and use a clock enable: a register that updates only when its enable is high behaves like a slower clock without creating a second clock domain at all.
-- A divided-rate register without a second clock: the enable gates updates.
process (clk)
begin
if rising_edge(clk) then
if ce = '1' then
counter <= counter + 1;
end if;
end if;
end process;
The enable approach has a cost: the enable signal itself must reach all the gated registers within one cycle, so a wide enable with high fanout becomes a timing path. It also consumes the clock-enable input of each register, which is free in the cell but only one per register. Its benefit is that all registers share one clock, one skew model, and one constraint, which removes an entire class of analysis ambiguity.
When a clock cannot use the tree
Some signals must be used as clocks but cannot reach a global buffer: a clock recovered from a data stream, a clock forwarded from an external device on an ordinary pin, or a clock that must be gated by logic. These cases force the clock onto general routing, and the consequences are specific.
Clock gating built from an AND gate is the classic hazard. If the enable changes while the clock is high, the gated clock produces a runt pulse, and a register clocked by a runt pulse may latch metastable data or may double-count. The safe construction gates the enable with a register clocked by the falling edge of the same clock, so the enable can only change when the clock is low. Even then, the gated clock’s skew differs from the tree’s, and any path between a register on the gated clock and a register on the tree is a cross-domain path. Vendors provide dedicated clock-gating cells for exactly this reason, and using them keeps the gated clock on the tree.
A clock that must be selected between two sources, as in a design with a redundant reference, needs a glitch-free multiplexer. A combinational multiplexer on a clock line produces a runt whenever the select changes while the clock is high. The dedicated primitive sequences the switch so that the outgoing clock is stopped cleanly before the incoming one starts, at the cost of a few cycles of no clock. A design that builds the selection from ordinary logic works in simulation and produces an intermittent failure in hardware.
Skew across the boundary
Two devices, or two clock domains inside one device, do not share a skew model. When data crosses from one clock to another, the receiving register’s setup and hold relative to the transmitting clock are not analysed by the single-clock formulas above; the paths are asynchronous and the tool must be told so, with the crossing handled by a synchronizer. The construction of those synchronizers and the analysis that verifies them belong to clock domain crossing.
What remains specific to the clock network is the accounting. Skew between two regions of the same tree is small but not zero, and it is included in the reported slack. Insertion delay from an input pin to the registers is often a nanosecond or more, and it appears in the input timing path as clock latency. A design that forgets to declare the input clock’s latency, or declares it without the board delay, analyses the interface against the wrong reference and produces a report that does not correspond to the hardware. Board-level clock distribution and the delays outside the device are a separate accounting problem, and the device cannot discover them.
References
- 7 Series FPGAs Clocking Resources User Guide (UG472) — Xilinx / AMD
- Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog — Clifford E. Cummings, SNUG 2008
- IEEE 1800-2017: SystemVerilog Language Reference Manual — IEEE