With on-chip variation, STA analyses setup with the launch clock path slow (late) and the capture clock path fast (early). Both paths usually share the first part of the clock tree. A single buffer on that shared part cannot be slow for the launch and fast for the capture at the same instant, yet a naive analysis applies both. Common path pessimism removal (CRPR, also called CPPR) gives that difference back.
Quantity | Value (illustrative, ns) |
|---|---|
Shared clock segment (common path) | 0.80 |
Launch-only branch | 0.20 |
Capture-only branch | 0.25 |
Late derate (launch) | 1.10 |
Early derate (capture) | 0.90 |
common, lb, cb = 0.80, 0.20, 0.25
late, early = 1.10, 0.90
launch_arrival = (common + lb) * late # 1.10
capture_arrival = (common + cb) * early # 0.945
naive = capture_arrival - launch_arrival # -0.155 : skew seen without CRPR
credit = common * (late - early) # 0.16 : the shared segment counted twice
with_crpr = naive + credit # +0.005
# physically: only the branches differ in derate, the common path cancels
true = cb * early - lb * late # 0.225 - 0.22 = 0.005
assert abs(credit - 0.16) < 1e-9
assert abs(with_crpr - true) < 1e-9 and abs(true - 0.005) < 1e-9
print("PASS: CRPR credit =", round(credit, 3), "ns; skew goes from", round(naive, 3), "to", round(with_crpr, 3))Without CRPR the clock skew looks like -0.155 ns, costing setup slack. The credit is the common segment times the derate spread: 0.80 x (1.10 - 0.90) = 0.16 ns. After the credit the skew is +0.005 ns, which matches the physical situation where only the two private branches differ. The credit grows with the length of the shared path, so it matters most when launch and capture flops are close together in the clock tree.
CRPR is enabled in signoff and applied consistently in both setup and hold analyses.
A report that shows a credit line in the clock path is read with the credit included; slack numbers quoted without it are different numbers.
CRPR is a physical correction, not a margin: it never turns a real violation into a pass, only removes an impossible assumption.
0.50 x (1.08 - 0.92) = 0.50 x 0.16 = 0.08 ns.