ADR 0003 — OpenTimer as in-process reference STA
Status: Superseded (2026-05-01). Spike (../spikes/opentimer-sky130.md) failed Q2 — OpenTimer's input pipeline cannot handle real OpenROAD-flow .v/.spef for SKY130 designs with bus ports. Fallback is OpenSTA subprocess validation only (ADR 0001); a future ADR may revisit libreda-sta or an in-house walker if an in-process reference is wanted later.
Context
Jacquard needs an in-process reference STA path to:
- Validate SDF-derived timing against an independent computation at load time and on demand (requirement R2 in
timing-correctness.md). - Provide exact per-edge arrival for top-K critical paths (requirement R4, pessimism-delta reporting).
OpenSTA (ADR 0001) is the ground-truth oracle but runs only as a subprocess — unsuitable for per-run, in-process checking. A linked alternative is needed.
Options surveyed:
- OpenTimer (MIT, C++17). Parses
.lib/.v/.spef/.sdcdirectly. Won TAU Timing Analysis Contests (2014 1st, 2015 2nd, 2016 1st); industry "Golden Timer" for benchmark comparisons. Actively maintained (latest push 2025-12-26 as of this writing). Does not parse SDF — timing is computed from Liberty + parasitics. - libreda-sta (Rust, permissive). Young framework, self-described as "basic components." Unknown whether it handles SKY130 Liberty robustly. Lower maturity risk than OpenTimer.
- Tatum (MIT, C++). Analysis engine only; does not parse Liberty/SDF/Verilog. Using Tatum would require supplying our own parsers, so it does not solve the problem directly.
- In-house Rust walker. Author-shared blind spots with Jacquard's main pipeline reduce the independence benefit.
Decision
Subject to the spike's success, OpenTimer becomes Jacquard's in-process reference STA, integrated via C++ FFI (bindgen or equivalent).
- Linked directly; MIT licence satisfies
project-scope.md. - Computes timing from
.lib+.spefindependently of any SDF-derived path. This is an accepted (and arguably preferable) property: the reference path shares no parsing with Jacquard's SDF consumer, so a parse bug on either side is detectable rather than mutually masked. - Emits timing IR (per ADR 0002) so its output is directly diffable against Jacquard's SDF-derived IR.
Spike criteria in ../spikes/opentimer-sky130.md. On spike failure, fallback is to drop the in-process reference entirely and rely on OpenSTA subprocess validation (ADR 0001). This weakens per-PR feedback on timing correctness but is not fatal.
Consequences
- C++ FFI dependency;
bindgen-generated bindings; build complexity rises modestly. - Direct linking preserves permissive licensing (MIT).
- Three-way cross-check becomes the default in CI: Jacquard (SDF path) vs OpenTimer (Liberty+SPEF path) vs OpenSTA (subprocess, full ground truth). Three-way disagreement localises bugs to SDF parse / delay model / tool issue cleanly.
- OpenTimer does not parse SDF. To use it in Jacquard's current flow, OpenLane2 (or equivalent) must produce SPEF alongside SDF. This plumbing change is tracked in the phase-0 plan.
- OpenTimer's maturity is measured in contest benchmarks, not SKY130/GF130 real-flow output. Spike must verify it handles our actual Liberty and SPEF. The spike is structured to fail fast if it does not.
- If OpenTimer is dropped post-spike, alternative in-process references (libreda-sta, in-house) can be revisited; this ADR would be superseded rather than amended.
Links
../project-scope.md— licensing constraint, validation constraint.../timing-correctness.md— requirement R2, requirement R4.../spikes/opentimer-sky130.md— spike and success criteria.- ADR 0001 — OpenSTA oracle.
- ADR 0002 — timing IR (OpenTimer emits it).