A derate such as 1.07 is not a constant of nature. It encodes a measurement of how much matching structures differ across a die and a decision on how many sigmas to cover. Knowing the derivation lets you challenge a value, and update it when the process matures.
import statistics
# Measured delay ratios of neighbouring identical structures (a small, illustrative sample).
ratios = [1.00, 1.02, 0.99, 1.03, 0.98, 1.01, 1.00, 0.97, 1.04, 1.02]
mean = statistics.fmean(ratios)
sigma = statistics.stdev(ratios)
k = 3.0
late = 1 + k * sigma / mean
early = 1 - k * sigma / mean
assert abs(mean - 1.006) < 1e-9
assert abs(sigma - 0.02221) < 1e-4
assert round(late, 2) == 1.07 and round(early, 2) == 0.93
print("PASS: mean", round(mean, 3), "sigma", round(sigma, 4), "late", round(late, 3), "early", round(early, 3))Ten samples give a mean of 1.006 and a standard deviation of about 0.0222. Covering three sigmas gives late 1.066 and early 0.934, which round to 1.07 and 0.93. Ten samples are only for illustration: a real derate is based on many structures across many dies, and the confidence in the standard deviation matters as much as its value.
Choice | Options |
|---|---|
Coverage | Number of sigmas; a higher number is safer and more pessimistic |
Applies to | Cell delay, net delay, clock paths, data paths, setup and hold constraints |
Direction | Late and early values, separately per check |
Granularity | One value per scenario, or varying by depth, distance or cell type |
Each derate has a source (measurement, foundry guidance, characterisation) and a coverage statement.
Early and late values are consistent with each other and with the variation data.
Derates are revisited at process milestones, not carried over unchanged across technologies.
1 + 3 × 0.030 / 1.006 = 1.0895, about 1.09.