Cheat sheet

Timing formulae and rules of thumb

Setup and hold inequalities, fmax from slack, synchroniser MTBF, I/O timing budgets, DDR window arithmetic, pipelining gain and fixed-point bit growth, all in plain text.

Last verified 13 Nov 2026

This page collects the arithmetic behind timing reports and interface budgets. It is for engineers who want to check a tool’s number by hand or size a design before the tool exists. Symbols are defined once at the top and reused. Every formula is written in plain text so it can be pasted into a calculator or a script.

Symbols

Symbol Meaning Typical value, mid-range FPGA, 28 nm to 16 nm
T clock period 5 to 10 ns
t_cko clock-to-output of the launching flop 0.2 to 0.5 ns
t_logic combinational delay including routing depends on design
t_su, t_h setup and hold requirement at the capturing flop 0.05 to 0.2 ns each
t_skew capture clock arrival minus launch clock arrival plus or minus 0.1 to 0.3 ns on a global net
t_j peak-to-peak clock jitter, or the tool’s uncertainty 0.05 to 0.2 ns
WNS, TNS worst negative slack, total negative slack from the report

Setup and hold inequalities

Setup:  t_cko + t_logic(max) + t_su + t_j  <=  T + t_skew
Hold:   t_cko + t_logic(min)               >=  t_h + t_skew + t_j

Positive skew (capture clock arrives late) helps setup and hurts hold. Hold does not depend on the period, which is why a hold violation cannot be fixed by lowering the clock frequency. The tool fixes hold by adding routing delay, and reports it as a separate slack.

Setup slack = T + t_skew - (t_cko + t_logic(max) + t_su + t_j)
Hold slack  = t_cko + t_logic(min) - (t_h + t_skew + t_j)

fmax from the report

fmax = 1 / (T - WNS)          # WNS is negative when failing

Example: a 10 ns constraint with WNS of minus 0.8 ns gives fmax of 1 / 10.8 ns, which is 92.6 MHz. With WNS of plus 1.2 ns the design could run at 1 / 8.8 ns, which is 113.6 MHz, but only if every other path has at least that much slack, which the report does not promise. TNS tells you how far away you are overall: a large TNS with small WNS means many paths need work, not one.

Rule of thumb Value
Logic levels per 100 MHz on a 28 nm fabric about 8 to 10 LUTs between flops
Logic levels at 300 MHz on the same fabric 2 to 3
Fraction of the period spent on routing in a congested design 50 to 70 %
Fan-out above which a net starts to cost a logic level about 32 (varies widely)

Synchroniser MTBF

For a two-flop synchroniser, the mean time between metastability failures is usually modelled as

MTBF = exp(t_r / tau) / (T_0 * f_clk * f_data)

where t_r is the time available for the first flop to resolve (one capture period minus the second flop’s setup and the routing between them), tau is the flop’s resolution time constant, T_0 is a window constant that depends on the flop, f_clk is the capture clock frequency and f_data is the rate at which the input changes.

Worked example (illustrative constants, not any vendor’s numbers):

tau   = 20 ps
T_0   = 50 ps
f_clk = 200 MHz, so T = 5 ns
f_data = 50 MHz
t_r   = 5 ns - 0.3 ns (setup plus routing) = 4.7 ns

exp(4.7 ns / 20 ps) = exp(235) = about 1.15e102
denominator = 50e-12 * 200e6 * 50e6 = 5e5
MTBF = about 2.3e96 seconds

The same arithmetic with one flop only (t_r near zero) gives an MTBF measured in seconds, which is why one flop is never enough. Vendors publish tau and T_0 per family. AMD exposes them through report_synchronizer_mtbf in Vivado when ASYNC_REG is set. Adding a third flop multiplies the exponent’s numerator by nearly another period, which is why three flops are common above 400 MHz.

I/O timing budgets

System-synchronous (shared clock from the board)

Input setup check:  t_clk_to_fpga + t_co(ext) + t_pcb(data) + t_su(fpga)  <=  T + t_pcb(clk)
Input hold check:   t_co(ext,min) + t_pcb(data,min)  >=  t_h(fpga) + t_pcb(clk) - t_pcb(clk,min)

What you write in the constraint file, where the external device’s datasheet gives t_co(max) and t_co(min) and the board gives trace delays:

set_input_delay -max = t_co(ext,max) + t_pcb(data,max) - t_pcb(clk,min)
set_input_delay -min = t_co(ext,min) + t_pcb(data,min) - t_pcb(clk,max)
set_output_delay -max = t_su(ext) + t_pcb(data,max) - t_pcb(clk,min)
set_output_delay -min = -t_h(ext) + t_pcb(data,min) - t_pcb(clk,max)

The output -min value is usually negative. Board traces run at roughly 6 to 7 ps per mm on FR-4 microstrip, so a 50 mm mismatch is about 0.3 ns.

Source-synchronous (clock forwarded with the data)

The external clock and data travel together, so the board delays cancel and only the skew between them matters.

Data valid window at the FPGA pin = T_bit - t_skew(ext) - t_pcb_mismatch - t_jitter
Required window                   = t_su(fpga) + t_h(fpga)    # from the datasheet, per I/O standard
Margin                            = valid window - required window

Centre the capture edge in the window using the input delay element (IDELAY on AMD, dynamic phase shift on Altera, DLL on Lattice) or by shifting the PLL phase. Edge-aligned interfaces need a 90 degree shift, centre-aligned ones need none.

DDR data-valid window

For double data rate, a bit lasts half a period.

T_bit = T / 2
Window = T_bit - t_dvw_loss
t_dvw_loss = t_skew(driver) + t_pcb_mismatch + t_duty_error + t_jitter

Example at 800 Mb/s per pin (400 MHz DDR, T = 2.5 ns):

T_bit        = 1.25 ns
driver skew  = 0.20 ns
PCB mismatch = 0.05 ns (within 8 mm)
duty error   = 0.10 ns (4 %)
jitter       = 0.10 ns
window       = 1.25 - 0.45 = 0.80 ns

An FPGA input with t_su + t_h of 0.40 ns leaves 0.20 ns each side once centred, which is workable but leaves no room for temperature drift without calibration. Memory controllers calibrate for exactly this reason.

Pipelining gain estimate

Splitting a combinational block of delay D into N balanced stages:

T_new  = D / N + t_cko + t_su + t_overhead
Speedup = (D + t_cko + t_su) / T_new
Latency = N cycles

The overhead term (register delay plus the routing that does not shrink) is typically 0.5 to 0.8 ns on a 28 nm fabric, which caps the useful N. Going from 1 to 2 stages roughly doubles fmax. Going from 4 to 8 rarely gives more than 20 % because the overhead dominates. Pipelining does not help if the block feeds back to itself within the loop: for an accumulator, retiming across the loop is impossible and you need a different algorithm.

Fixed-point bit growth

Widths in bits, with signed two’s complement unless stated.

Operation Result width Note
a + b, both N bits N + 1 one carry bit
Sum of M terms of N bits N + ceil(log2(M)) an accumulator of 1024 samples adds 10 bits
a × b, N and M bits unsigned N + M
a × b, N and M bits signed N + M - 1 except for the one case of minimum times minimum, which needs N + M; most tools keep N + M
Multiply by a constant of K bits N + K
FIR with M taps of C-bit coefficients and N-bit data N + C + ceil(log2(M)) before any rounding
Shift left by s N + s
Truncation of F fraction bits N - F introduces a bias of minus half an LSB; round-half-even or add 1 at the dropped bit to centre it

Keep the full width through the arithmetic and round once at the end. Rounding at every stage is cheaper in flops but stacks bias and can cause limit cycles in IIR filters.

Sources