ADR 0004: Phase 2a static timing conventions¶
- Status: accepted
- Date: 2026-10-16
Context¶
Phase 1 of RustSTA implemented a single-corner ideal-wire static timing engine with per-tag slews
(STA-REQ-0101, 0115), zero clock latency on set_input_delay startpoints (STA-REQ-0201),
D_h = D_s - T_C for the hold relation (STA-REQ-0210), latch borrowing that carried the upstream
launch tag through D -> Q without setup uncertainty at the opening edge (STA-REQ-0213), and no
constant propagation, three-state enable/disable propagation, driver output-pin capacitance, or
wire-load estimation (STA-REQ-0011, 0110). Extending the engine to multi-corner industrial cell
libraries and SDC constraints requires explicit, unambiguous conventions for each of these points.
Decision¶
The Phase 2a timing specifications (docs/specs/sta/) adopt the
following conventions, while moving the superseded Phase 1 texts to
docs/specs/sta/legacy.md until package Z1 removes the legacy engine:
- Per-pin slews (
STA-REQ-0108,0109). Transition times are stored per pin, transition and analysis bound (slew[node][tr][an]), reduced as the worst (maxforlate,minforearly) output transition across all enabled incoming arcs, including arcs whose source pin carries a transition but no launch tag. Cell arc delays and output transitions are evaluated once per(tr_in, tr_out, an)from the source pin slew, and shared across all launch tags reaching the source pin (COMPUTE-REQ-0015 to 0018). - Extrapolation clamping (
STA-REQ-0120). Linear extrapolation outside a transition table's index range clamps negative output slews at0.0, preventing runaway negative slews on high-fanout nets. Extrapolated arc delays and constraint values are not clamped at zero. Out-of-range table lookups andmax_transition/max_capacitanceviolations emit one aggregated warning per construct. - Driver output-pin capacitance (
STA-REQ-0121). The capacitive loadC_netof a net sums, in canonicalNET_PINSorder, the load pin capacitances, the output-pin capacitance of every driver pin on the net (including allthree_statedrivers on a bus), explicitset_loadvalues, and wire capacitance. - Lumped wire-load model and port-net exclusion (
STA-REQ-0122to0125). InWireloadLumpedmode (WireModel), an internal net withFconnected instance load pins addsC_wire = capacitance * L(F)with linear interpolation andslopeextrapolation onfanout_length. Nets connected to any top-level port receiveC_wire = 0.0. - Per-corner resolution and threshold/derate rules (
STA-REQ-0015,0016). Cells are resolved independently per corner, and duplicate cell definitions within a corner are an error. Library slew trip points andslew_derate_from_libraryare verified consistent within each corner and recorded in corner metadata; in lumped NLDM delay calculation, table values are evaluated directly without multiplying byslew_derate_from_library. - Three-state bus propagation (
STA-REQ-0013,0223).three_state_enable(Z -> 1rise,Z -> 0fall) andthree_state_disable(0 -> Zrise,1 -> Zfall) arcs propagate fromENtoZ, and multi-driver three-state bus nets merge arrivals and slews across all enabled drivers. - Input/output delay clock latency and driving cells (
STA-REQ-0217,0218).set_input_delaystart arrivals include the reference clock's source and network latency unless-source_latency_includedor-network_latency_includedis given;set_output_delaycapture latencies obey the same flags.set_driving_celladdsdelay(s_in, C_port) - delay(s_in, 0)to the port arrival and sets the port transition toslew(s_in, C_port). - One-sided
-max/-minI/O delays (STA-REQ-0219). Specifying only-max(or only-min) onset_input_delayorset_output_delayseeds only the corresponding analysis bound and leaves the opposite bound unset. - Hold relation over the common period (
STA-REQ-0220). Over all launch edgeslin the common periodP = lcm(T_L, T_C)(in integer femtoseconds),D_s = min_l (min { c > l } - l)andD_h = max_l (max { c <= l } - l). This replacesD_h = D_s - T_C, which is optimistic by multiples of the clock period wheneverT_L != T_C. - Latch window, opening-edge uncertainty, and
D -> Qtag re-launch (STA-REQ-0221,0222). A latch check pairs each closing edgeD_closewith the opening edge of the same enable pulseD_open = D_close - W, subtracts setup uncertaintyu_sat bothR_openandR_close, appliesset_max_time_borrow, and re-launches borrowed arrivals (a > R_open) throughD -> Qinto the latch enable's opening-edge tagtag_openat(min(a, R_close) - D_open) + delay_DQ, withslew[Q]taken from theG -> Qenable arc. - Recovery/removal, clock gating, and endpoint completeness (
STA-REQ-0224to0228). Asynchronousrecovery_*andremoval_*checks form theasync_defaultgroup; combinational AND (v = 0, active-high) and OR (v = 1, active-low) clock-gating checks pair leading and trailing edges of the gated pulse; every potential endpoint receives an explicit status incompleteness.unconstrained_by_reason. - Constants, case analysis, and unate sense refinement (
STA-REQ-0150to0157). Kleene three-valued evaluation (0,1,X) from netlist ties, tie cells,set_case_analysisandset_logic_*disables controlled combinational arcs, refinesnon_unatearcs (such asXOR2with a constant input) topositive_unateornegative_unate, suppresses checks on constant sequential pins while preserving clockedCK -> Qlaunches, and records disabled-arc counts by reason. - Transitions ignore logic values; checks take the capture clock path's transition (version
0.4,
STA-REQ-0117,0159,0163,0229,0230). Black-box comparisons with a reference timing tool on both default libraries (gates with constant side inputs next to their twins whose constant input is a port with transition 0, case analysis on and off, clock muxes with a tied select, latches with tied enables) showed that the reference's pin transitions do not depend on logic values, while its arrivals do. RustSTA now merges into a pin's transition every arc that only logic values disable (and the clock-to-output arcs of unclocked sequential cells), with the arc's library sense; these arcs carry no arrival and no required time. A unate arc whose sense the residual function contradicts is disabled; a latch whose enable a constant holds active is transparent for late arrivals. Since a pin's early and late transitions now differ wherever several arcs merge, the related pin transition of a check is that of the capture clock path (early for setup and recovery, late for hold and removal), which the same comparison confirmed; with a single arc into each clock pin the results are those of the earlier rule. - Sequential cells, clock gates and constant pins next to logic values (version 0.4,
STA-REQ-0162,0163,0164,0714,0822). Further black-box comparisons with the reference timing tool on both default libraries showed that a flop or latch whose asynchronous clear or preset is held active is not a constant there (its clock-to-output arc launches and the cone below it is timed and checked); that a clock gate output is the conjunction of its clock and enable pins as the Liberty clock-gate pin attributes name them (an enable held at 0 stops the clock whatever the test enable, the state function and the statetable say; copies of the libraries with the attributes removed confirmed it); that a pin at a constant passes no arrival (the loads of a port under case analysis are not in its clock's domain); that the transition of a propagated clock pin merges a launched enable that enters the clock network; and that with ideal clocks the pins reached through arcs that constants disable belong to the ideal clock network, whose stopped flops launch at the ideal clock transition. RustSTA follows each observation.
Consequences¶
- Each convention has a closed-form hand derivation on the linear synthetic library in
verification/analytic/sta/, checked to1e-9 nsby both the engine (E3โE7) and the independent checker (R1). - Separating per-pin slews from per-tag arrivals shrinks the per-tag node state and matches the
shared
rusteda-compute::timingABI (docs/specs/compute/timing.md).