Clock uncertainty is an EXAMPLE margin, in nanoseconds, covering skew and jitter the tool should not try to use. Latency is the delay from the clock source to the flop clock pin, split into source and network parts at concept level.
Uncertainty shrinks the usable period on every path. Latency shifts when the clock arrives; how each tool models the split varies, so state both numbers explicitly.
An input delay states how much of the period the outside world consumes before the signal reaches the input port. An output delay states how much of the period the outside world needs after the signal leaves the output port.
Both are EXAMPLE parameters in nanoseconds. The listing below sketches them in tool-neutral form.
The listing below is illustrative tool-neutral SDC and is not run by any tool.
illustrative SDC sketch (not run by any tool):
set_input_delay -clock CLK 3.0 [get_ports req]
set_output_delay -clock CLK 2.5 [get_ports ack]Available time is the period minus what the outside world, uncertainty, and the capturing flop's setup time already take. For an input-to-register path the remainder before setup is the period minus the input delay minus uncertainty.
For a register-to-output path it is the period minus the output delay minus uncertainty. The launching side contributes clock-to-Q plus combinational delay, which must fit inside the remainder minus the setup time.
EXAMPLE parameters (not real targets): period 10.0 ns, input delay 3.0 ns, output delay 2.5 ns, uncertainty 0.5 ns, setup 0.5 ns
full equation: combinational budget = period - IO delay - uncertainty - setup
input-to-register: remainder before setup = 10.0 - 3.0 - 0.5 = 6.5 ns; budget = 6.5 - 0.5 = 6.0 ns
register-to-output: remainder before setup = 10.0 - 2.5 - 0.5 = 7.0 ns; budget = 7.0 - 0.5 = 6.5 nsThe program below repeats the subtraction in integer picoseconds, so the arithmetic is exact. Its six self-checks pin both remainders, both budgets, and their sums back to the period.
import sys
PERIOD_PS = 10000
IN_DELAY_PS = 3000
OUT_DELAY_PS = 2500
UNC_PS = 500
SETUP_PS = 500
def remainder(delay_ps):
return PERIOD_PS - delay_ps - UNC_PS
def budget(delay_ps):
return remainder(delay_ps) - SETUP_PS
in2reg_rem = remainder(IN_DELAY_PS)
reg2out_rem = remainder(OUT_DELAY_PS)
in2reg = budget(IN_DELAY_PS)
reg2out = budget(OUT_DELAY_PS)
if in2reg_rem != 6500:
print("FAIL: in2reg remainder got " + str(in2reg_rem) + " want 6500")
sys.exit(1)
if reg2out_rem != 7000:
print("FAIL: reg2out remainder got " + str(reg2out_rem) + " want 7000")
sys.exit(1)
if in2reg != 6000:
print("FAIL: in2reg budget got " + str(in2reg) + " want 6000")
sys.exit(1)
if reg2out != 6500:
print("FAIL: reg2out budget got " + str(reg2out) + " want 6500")
sys.exit(1)
if in2reg + IN_DELAY_PS + UNC_PS + SETUP_PS != PERIOD_PS:
print("FAIL: in2reg parts do not sum to period")
sys.exit(1)
if reg2out + OUT_DELAY_PS + UNC_PS + SETUP_PS != PERIOD_PS:
print("FAIL: reg2out parts do not sum to period")
sys.exit(1)
print("PASS: combinational budgets 6.0 ns in and 6.5 ns out of a 10.0 ns period")Path | Combinational budget | Meaning |
|---|---|---|
Input to register | 6.0 ns | Remainder 6.5 ns before setup; budget 6.5 minus setup 0.5. |
Register to output | 6.5 ns | Remainder 7.0 ns before setup; budget 7.0 minus setup 0.5. |
The remainder is 10.0 minus 3.0 minus 0.5, which is 6.5 ns. The budget is 6.5 minus 0.5, which is 6.0 ns.
The remainder is 10.0 minus 2.5 minus 0.5, which is 7.0 ns. The budget is 7.0 minus 0.5, which is 6.5 ns.