Real clocks are not perfect: their edges move cycle to cycle (jitter), and before the clock tree is final the skew between flops is only estimated. Clock uncertainty is the margin that covers these. Too little hides real failures; too much wastes performance. Its value should be a decision with a documented reason.
# not-run: SDC is not executable here
set_clock_uncertainty -setup 0.12 [get_clocks sys_clk]
set_clock_uncertainty -hold 0.05 [get_clocks sys_clk]
set_clock_uncertainty -setup 0.20 -from [get_clocks clk_a] -to [get_clocks clk_b] ;# inter-clockSource of uncertainty | Affects | Typical treatment |
|---|---|---|
PLL and clock source jitter | Setup (period variation), and a smaller amount of hold | A budgeted value per clock from the clock design |
Skew not yet known (pre-CTS) | Setup and hold | A larger value, reduced after clock tree synthesis |
Duty-cycle distortion | Half-cycle paths | Included for half-cycle checks |
Project margin | Both | A visible, owned number, never hidden in a derate |
# Uncertainty effect on one setup path (ns, illustrative)
T, S, arrival, C = 2.0, 0.10, 1.70, 0.35
def slack(U): return (T + C - S - U) - arrival
s_small, s_large = slack(0.05), slack(0.15)
assert abs(s_small - 0.50) < 1e-9 and abs(s_large - 0.40) < 1e-9
# every 0.1 ns of setup uncertainty removes 0.1 ns of slack, on every path of that clock
assert abs((s_small - s_large) - 0.10) < 1e-9
print("PASS: +0.10 ns uncertainty costs 0.10 ns slack on every path")Uncertainty acts uniformly on every path of the clock, so a small change moves WNS, TNS and the failing count together. That makes it a blunt tool and a common source of arguments in closure reviews.
A documented rationale: clock-source jitter figure, skew estimate, and project margin listed separately.
Pre-CTS uncertainty is reduced after the clock tree is built; leaving it large wastes closure effort.
Setup and hold uncertainties differ when they should: jitter mostly matters for setup.
Jitter changes the period seen by a path, which directly eats setup time, while hold is a same-edge check where jitter largely cancels. Hold uncertainty mostly covers skew estimation error.