Skip to content

dbSta: timing-accuracy report commands (AOCV/SI/PBA/CPPR/MCMM/crosstalk/noise/incremental-STA)#10846

Draft
saurav-fermions wants to merge 20 commits into
The-OpenROAD-Project:masterfrom
Fermions-ASI:feat/ta-stack
Draft

dbSta: timing-accuracy report commands (AOCV/SI/PBA/CPPR/MCMM/crosstalk/noise/incremental-STA)#10846
saurav-fermions wants to merge 20 commits into
The-OpenROAD-Project:masterfrom
Fermions-ASI:feat/ta-stack

Conversation

@saurav-fermions

Copy link
Copy Markdown
Contributor

Summary

Adds the dbSta timing-accuracy command surface: a stacked series of report-only, flag-gated advanced-timing commands. Every command is additive — the default / flag-off paths are byte-identical to baseline report_checks / GBA timing.

Command surface:

  • AOCV — depth-based OCV derate report (report_checks_aocv, aocv_derate_*) and depth-based derate applied during STA propagation (set_aocv_derate -propagate, default OFF).
  • SI — Miller-factor coupling derate (report_coupling_si) and a timing-window-aware coupling derate (SiWindow).
  • PBAreport_pba_slack (setup) + hold-path recovery + endpoint-closure decision.
  • CPPR — clock reconvergence pessimism removal (report-only) + slice-2 endpoint closure with CRPR credit.
  • Unified closurereport_closure.
  • MCMM — multi-corner + cross-corner worst-slack, plus a per-mode dimension (report_mcmm_slack -by_mode).
  • Crosstalk-aware delay — coupling-cap effective-C stage delay, per-edge direction, and crosstalk on hold paths (flag-gated).
  • Noise — crosstalk-noise estimation (report_noise) and an optional noise-induced delay push.
  • Incremental STA — additive, full-STA-equivalent, for the ECO/repair path.

⚠️ Dependencies (please read)

Engine hooks — OpenSTA #383. Two commits consume OpenSTA-fork hooks:

  • AOCV propagation needs AocvDepthDerate / Search::deratedDelayData.
  • SI timing-window needs the per-coupling-cap value setter (Parasitics::setCapacitorValue).

Both hooks ship in The-OpenROAD-Project/OpenSTA#383. CI here will fail until #383 is merged and this repo's src/sta submodule is bumped to include those hooks. This PR intentionally does not carry a src/sta gitlink bump. Related engine PRs: The-OpenROAD-Project/OpenSTA#384, The-OpenROAD-Project/OpenSTA#385.

Shared noise foundation. The crosstalk and noise commands build on a small, additive, report-only noise-estimation module (report_noiseNoiseState/NoiseVictimResult/noise_estimate_victim). It is included here as a foundation commit ("feat(dbSta): add report_noise crosstalk glitch triage").

Testing

Built the full openroad binary against src/sta carrying the #383 hooks. All 103 dbSta + rcx ctests pass (100%), including the 18 new feature regressions and the byte-identical-baseline checks (default/flag-off == baseline report_checks/GBA).

Notes

  • Marked draft until the src/sta hooks land (see Dependencies).
  • All commits additive / flag-gated / report-only; no default behavior change.

Add an OpenROAD-side, report-only first slice of depth-dependent
on-chip-variation derating, reusing public OpenSTA path APIs without
modifying src/sta.

OpenSTA applies the OCV derate per timing arc inside the forward search
(Search::deratedDelay), with no notion of path depth, so per-path-depth
derate cannot be expressed via the existing Sdc derate lookups without
editing the upstream search. Instead, recompute a depth-adjusted setup
slack on reported critical paths.

New commands (dbSta):
- set_aocv_derate: load a depth->derate table (-file / inline -depth/-late;
  -reset). Empty table == inactive == baseline behavior.
- report_checks_aocv: for the worst N setup paths, report logic depth,
  flat-OCV slack, AOCV-adjusted slack, recovered pessimism, and derate.

With no table loaded, report_checks is byte-for-byte unchanged. Adds a
gcd/Nangate45 regression (dual CMake+Bazel registration) asserting
inactive==baseline and that a depth-based table improves deep-path slack.

See AOCV_INVESTIGATION.md and AGENT_REPORT.md for the derate trace,
chosen slice, and out-of-scope items (in-search per-depth derate, full
statistical LVF/POCV).



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Upgrade the report-only AOCV slice into a real per-arc, depth-dependent OCV
derate applied during OpenSTA forward propagation, opt-in via
set_aocv_derate -propagate (defaults OFF -> timing byte-identical to baseline).

src/sta (submodule, fork edits marked // OpenROAD-fork: AOCV):
  AocvDepthDerate interface + Search::deratedDelayData/aocvDataDepth hook.

src/dbSta:
  AocvDerateTable implements AocvDepthDerate; dbSta.i installs the table on the
  live Search and invalidates arrivals; set_aocv_derate gains -propagate /
  -no_propagate. report_checks_aocv unchanged.

Tests: src/dbSta/test/aocv_propagate (CMake + Bazel) proves flag-off ==
baseline, flat-table == flat OCV, depth-decreasing table recovers late-path
pessimism, and disable/reset returns to baseline. Full dbSta suite (73) and
OpenSTA search/sdc suite (115, incl. derate/crpr/multicorner) pass.

See AOCV_STA_INVESTIGATION.md and AGENT_REPORT.md.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add a bounding "poor-man's SI" Miller-factor coupling derate as a first
slice of crosstalk/signal-integrity aware timing.

New OpenROAD-native commands (implemented in src/dbSta, no src/sta edits):

  set_coupling_miller_factor [-setup mf_s] [-hold mf_h]
    Scales the coupling caps kept in the parasitic network by a Miller
    factor when computing a victim net's effective capacitance for timing.
    -setup applies to the max (setup) parasitics, -hold to the min (hold)
    parasitics. Both default to 1.0 (exact no-op). 2.0 ~ worst-case
    opposite-switching aggressor (slower setup); 0.0 ~ best-case (hold).

  report_coupling_si [-max_nets N] [-corner C]
    Ranks signal nets by total coupling cap and reports Cc, Cgnd and the
    Cc/Cgnd ratio (SI-risk hotspots) plus the active Miller factors.

Reuses OpenSTA's existing coupling_cap_factor reduction path rather than a
parallel mechanism: the command sets Parasitics::setCouplingCapFactor per
scene min/max, drops cached reduced (pi) parasitics so the next delay calc
re-reduces with the new factor, then invalidates delays. Requires coupling
caps to be kept (read_spef -keep_capacitive_coupling).

Default behavior is unchanged: factor 1.0 reproduces baseline timing
exactly. Adds regression test src/rcx/test/coupling_si_miller.tcl
(registered in CMake + Bazel) proving (a) mf=1.0 == baseline, (b) mf=2.0
increases worst-case setup path delay, (c) restore returns to exact
baseline. rcx (16/16) and dbSta (70/70) ctest suites stay green.

See SI_INVESTIGATION.md and AGENT_REPORT.md for the full CC->parasitic->STA
trace, hook rationale, and honest scope/gap assessment.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Refine the slice-1 blanket Miller coupling derate to be switching-window
aware: a victim net only keeps the worst-case coupling contribution from an
aggressor whose driver switching window overlaps the victim's. Non-overlapping
aggressors are scaled back to nominal, recovering slice-1 pessimism.

New commands (src/dbSta):
  * set_si_timing_window [-enable|-disable] [-guardband s] [-max_nets n]
  * report_si_windows [-max_nets n] [-corner c]

A net's window is its driver-vertex arrival interval [min,max] over both
edges. The filter scales non-overlapping coupling caps by 1/mf_setup in the
OpenSTA parasitic network (Parasitics::setCapacitorValue); the slice-1 blanket
factor re-multiplies during pi/Arnoldi reduction, so gated caps net to nominal
and overlapping caps stay at worst case. Original values are snapshotted and
restored on -disable -> byte-identical baseline.

Default (never enabled / -disable) reproduces slice-1 and baseline timing
exactly (proven byte-identical via report_checks). Bumps the src/sta submodule
for the flag-gated, default-no-op setCapacitorValue hook.

Test: src/rcx/test/coupling_si_window.tcl (gcd/sky130hs real extraction):
baseline-equality, blanket-worsening, gating discrimination (1564 gated at
guardband 0 vs 0 at large guardband), pessimism recovery
(blanket -3.193e-08 <= windowed -3.166e-08 <= baseline -2.767e-08), and exact
restore. ctest dbSta|rcx: 100% pass (90/90).

See SI_WINDOW_INVESTIGATION.md and AGENT_REPORT.md.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add an additive dbSta-side command that quantifies and recovers
Graph-Based-Analysis (GBA) gate-slew pessimism on the top-N setup
critical paths, the way commercial Path-Based Analysis (PBA) does.

For each top-N GBA setup path, walk the expanded path and, for every
combinational gate arc, drive the EXISTING OpenSTA arc delay calculator
(ArcDelayCalc::gateDelay with GraphDelayCalc::parasiticLoad inputs)
twice: once with the GBA worst-at-pin input slew and once with the
path-specific slew propagated along this path. The summed gate-delay
difference is the recovered pessimism; PBA slack = GBA slack + recovered.

PBA slack >= GBA slack is guaranteed by construction: the path-specific
slew is <= the worst-at-pin slew and gate delay is monotonic in input
slew, so each PBA gate delay <= the matching GBA gate delay (computed via
the same calculator call for self-consistency, with a defensive per-gate
clamp at 0).

Delay calculation is not reimplemented; the OpenSTA calculators are
driven directly. No src/sta files are modified. report_checks (GBA)
output is unchanged (verified in-test and by external diff).

Scope: setup only (the command errors on hold, which has the opposite
slack sign and a different pessimism source); gate-delay pessimism only
(wire/CRPR/clock paths keep GBA values). See PBA_INVESTIGATION.md and
AGENT_REPORT.md.

Adds regression test dbSta/report_pba_slack on routed gcd_nangate45
(CMake + Bazel) asserting the columns render, PBA slack >= GBA slack and
recovered >= 0 on every path, and that report_checks is unchanged.


Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add a report-only OpenROAD-layer command, report_cppr, that surfaces the
clock reconvergence pessimism removal (CPPR/CRPR) credit per timing check.

OpenSTA already implements CRPR end-to-end (search/Crpr.cc, CheckCrpr) and
enables it by default under OCV analysis. This change does NOT reimplement
it; it exposes the engine's authoritative raw-vs-adjusted slack split in one
auditable table using the public PathEnd API:
  * raw slack  = PathEnd::slackNoCrpr (common-path pessimism double-counted)
  * cppr slack = PathEnd::slack       (common-path credit applied = GBA result)
  * credit     = cppr slack - raw slack (>= 0; CPPR only relaxes)
It also independently identifies the deepest shared clock pin (the branch
point) via the public Path/PathExpanded API for attributability.

Report-only: does not mutate the timing graph and does not change
crpr_enabled. No src/sta edits. The feature is purely additive, so the
default report_checks/GBA output is byte-identical to baseline (verified).

New regression test report_cppr (dual CMake+Bazel registration) on a
reconvergent clock-tree design under OCV derate asserts: a positive credit
on the reg1->reg2 check whose common pin is the shared branch point
(ckbuf1/Z), credit == raw+credit invariant, credit equals OpenSTA's own
report_checks CRPR value, and report_checks output unchanged by report_cppr.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
…djustment

Slice 1 of crosstalk-aware timing: turn the coupling-capacitance (CC)
segments rcx already extracts into an actual stage-delay adjustment, not
just a report. A victim net's effective capacitance grows when a coupled
aggressor switches in the same timing window (Miller effect), so the
victim's stage delay increases.

New, flag-gated, default-OFF commands (dbSta layer; no src/sta edit):

  set_xtalk_delay_factor [-enable|-disable] [-k factor]
                         [-guardband s] [-max_nets n] [-corner i]
  report_xtalk_delay     [-k factor] [-guardband s] [-max_nets n]
                         [-corner i]

Model (switching-factor effective-C): for each top-N coupled victim, every
CC segment to an aggressor whose switching window overlaps the victim's
(reusing the existing SI-window infrastructure: si_net_window /
si_windows_overlap) is "active" and has its stored coupling cap scaled by
(1 + k). k is the user knob; k = 1 is the classic ~2x Miller bound, k = 0
is an explicit no-op, and -1 < k < 0 models a net-decoupling bound. The
added effective cap dC = k * Cc_active is realized by bloating the stored
coupling capacitors (snapshotting originals), exactly like the noise-delay
slice, so report_checks sees the degraded stage delay after reduction. The
implied per-stage delta (Rdrv * dC) is reported for auditability.

Default OFF (never enabled) is byte-identical to baseline: nothing is
mutated; disabling restores every bloated cap exactly and invalidates
delays. Proven against the documented flag-off timing report.

Adds src/rcx/test/coupling_xtalk_delay.tcl (sky130hs gcd, real extracted
coupling) asserting: disabled == baseline exactly, k>0 degrades setup TNS,
disable restores exactly, the delta scales linearly with k (hand calc:
dDelay = Rdrv * k * Cc_active), k=0 is a no-op, and a wider guardband can
only grow the active coupling cap. Registered in both CMake and Bazel.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Extend the slice-1 coupling-cap effective-C stage-delay adjustment with two
flag-gated capabilities whose defaults reproduce slice 1 byte-for-byte. Both
live in the dbSta layer; no src/sta edit.

1. Per-edge switching DIRECTION (-direction). Slice 1 assumed worst-case
   same-direction coupling on every overlapping aggressor (effective cap
   *= 1+k). Slice 2 classifies each victim/aggressor pair by the dominant
   overlapping switching edge using per-edge (rise/fall) arrival windows
   (new si_net_edge_window / si_window_overlap_amount, built on the existing
   SI-window infra): same-polarity edges aggravate (factor 1+k), opposite-
   polarity edges decouple via the Miller effect (factor 1-k). The signed
   effective-cap delta becomes k*(CcSame - CcOpp). Default off => every active
   segment uses 1+k, exactly slice 1.

2. Bounded iterative RE-CONVERGENCE (-iterations, default 1). A victim's delay
   depends on aggressor arrival windows, which depend on aggressor delays. Run
   a small fixed number of refinement passes so the windows settle; each pass
   restores prior bloat, re-decides active segments/directions from the latest
   timing, re-reduces touched victims and invalidates delays. Per-pass setup
   TNS movement is reported so convergence is visible. iterations=1 is exactly
   the slice-1 single pass (and skips the extra TNS query for byte-identity).

The XtalkDelayState/XtalkDelayResult gain direction/iterations knobs and
same/opposite split fields. New read-only introspection helpers expose the
direction-aware dDelay, the same/opposite segment counts and the same/opposite
active coupling caps for hand-calc assertions.

Proofs (measured on this build):
* Flag-off timing report is byte-identical to the baseline report (normalized
  HEAD line) -- the feature never mutates anything until enabled.
* iterations=1 + direction off reproduces slice-1 coupling_xtalk_delay TNS
  exactly; the slice-1 regression still passes unchanged.

Adds src/rcx/test/coupling_xtalk_direction.tcl (sky130hs gcd, real extracted
coupling) asserting: slice-1 equivalence at iterations=1/direction off; a
same-direction-dominated victim (+) and an opposite-direction-dominated victim
(-) get opposite-sign deltas; CcSame+CcOpp == CcActive; the signed delta
matches the hand calc dDelay = Rdrv*k*(CcSame-CcOpp) to <1e-6 rel; a
zero-opposite victim is identical with direction on/off; and bounded
re-convergence moves setup TNS monotonically and settles to a fixed point
within a few passes without becoming optimistic. Registered in CMake and Bazel.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Extend report_pba_slack (setup-only, additive PBA pessimism recovery) to
hold (min) checks, add per-endpoint aggregation, and a closure decision
surface that separates genuine post-PBA violations from GBA-pessimism
artifacts.

- recoverGatePessimism() generalized over MinMax. For hold the GBA gate
  delay is the MINIMUM (best/fastest slew) and the path-specific delay is
  >= that, so recovered = sum(PBA_gd - GBA_gd) >= 0 (mirror of the setup
  GBA_gd - PBA_gd). pba_slack = gba_slack + recovered >= gba_slack holds
  for both checks. findPathEnds is driven with MinMaxAll::min()/hold=true
  for hold.
- New: computePbaEndpoints()/summarizeClosure() and the reports
  reportPbaEndpoints() (negative->positive summary) and reportPbaClosure()
  (lists endpoints still failing after PBA = the real violations).
- Tcl: report_pba_slack gains -setup/-hold/-endpoints; new
  report_pba_closure command. Default behavior (report_pba_slack with no
  flags = setup per-path) is unchanged.
- All in the dbSta/OpenROAD layer using OpenSTA's existing Search/
  PathExpanded/ArcDelayCalc APIs; no src/sta edit.

Additive guarantee: flag-off GBA timing is byte-identical to baseline
(report_checks/report_wns/report_tns diff empty after HEAD-line
normalization). Existing report_pba_slack setup .ok unchanged.

New test report_pba_hold: pba_gcd with a hold clock uncertainty engineered
so GBA reports 2 hold-failing endpoints; PBA recovers exactly 1 (pessimism
artifact) and 1 remains a genuine violation. Asserts the PBA>=GBA invariant
on every hold path, the closure counts (10/2/1/1), and that GBA min-path
report_checks output is unchanged.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Build on report-only report_cppr (slice 1) by aggregating the per-check
CRPR credit into an actionable closure surface, mirroring the
report_pba_closure pattern for cross-command consistency:

- CpprEndpointResult / CpprClosureSummary + computeCpprEndpoints,
  summarizeCpprClosure: per-endpoint raw (slackNoCrpr) vs CPPR-adjusted
  (slack) aggregation with raw->cppr recovery flags.
- report_cppr_closure command (-endpoints / -all): classifies endpoints
  failing under raw GBA into clock-reconvergence-pessimism artifacts
  (pass once CPPR removes the double-counted pessimism) vs genuine
  post-CPPR violations.

Report/analysis-only: new opt-in commands only; does not mutate the GBA
graph or default report_checks. Flag-off (no new command invoked) is
byte-identical to baseline. Credit stays the engine's own
slack - slackNoCrpr, so it always matches OpenSTA CRPR. No src/sta edit.

New regression report_cppr_closure: a reconvergent design where one
raw-failing endpoint (reg2/D) moves from the genuine-violation list to
the artifact list once CPPR is applied, while two truly-failing
endpoints (zero CRPR credit) stay genuine.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
…alent)

OpenSTA already performs incremental, lazy, levelized timing update after a
netlist edit: the dbSta ODB callbacks call the Sta edit hooks
(replaceEquivCell*/connectPinAfter/disconnectPinBefore) which mark only the
affected vertices invalid, and the next timing query runs a cone-limited BFS
that recomputes just the changed fanout. This change does NOT reimplement any
of that and does NOT touch src/sta.

It adds an additive, report-only command report_incremental_sta (+ a
machine-readable helper) that, after a bounded ECO edit:
  * identifies the affected fanout cone of the edited cells by walking the
    timing graph, reporting how many endpoints are in it vs the full count
    (the incremental-work proof), and
  * reports WNS/TNS and per-endpoint slacks taken straight from OpenSTA's own
    incremental query API.

Correctness oracle (new regression tests on 2 designs, cppr + gcd): apply ECO
resizes, read incremental slacks, then delays_invalid + full from-scratch
re-run; incremental WNS/TNS and every per-endpoint slack are bit-for-bit
identical to the full re-run. Tests also assert only the affected cone is
flagged in-cone and that report_checks (the default full-STA path) is
unchanged by running the command.

Default/flag-off is byte-identical to the integration binary (additive only;
no existing code path modified). All dbSta+rsz ctests pass (331/331).



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add report_closure: a single closure verdict that composes the existing
PBA gate-slew pessimism recovery and CPPR common-path credit per endpoint.
For each endpoint failing under the raw (pre-CPPR, pre-PBA) baseline it
applies BOTH recoveries and classifies it as:
  * GENUINE  -- still failing after both recoveries, or
  * artifact -- cleared by pessimism recovery, labeled with the mechanism
                that cleared it (CPPR / PBA / BOTH).

Reuses computePbaEndpoints() and computeCpprEndpoints() (joined per
endpoint) -- does not reimplement PBA or CPPR. Reports the combined
recovered slack per endpoint plus a verdict summary (total / raw-failing /
cleared-by-CPPR / cleared-by-PBA / cleared-by-both / genuine).

Additive and default-OFF: no src/sta edit, no existing code path changed,
flag-off output byte-identical to baseline. New STA 2107 message id
(2102-2106 already taken). New regression test closure.def exercises one
CPPR-recoverable, one PBA-recoverable and one genuine endpoint.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Extend the existing crosstalk-aware effective-C delay machinery (the
xtalk-delay slices that target setup/max) to the hold/min path, behind a
new default-OFF -hold flag.

A same-direction aggressor switching with the victim REDUCES the
effective coupling cap ((1-k) instead of (1+k) for setup), so the victim
arrives EARLIER and erodes hold slack. With -hold the engine uses the
mirror-image factor and applies the bloat/relief to the MIN parasitics
so report_checks -path_delay min reflects it. Reuses the existing
SI-window + CC-segment infrastructure; no extraction reimplemented.

Default OFF reproduces the setup engine byte-identically (proven via a
read_liberty/lef/def/sdc + set_timing_derate + report_checks max&min +
wns/tns probe diffed against the integration binary; identical).



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add coupling_xtalk_hold regression (gcd, sky130hs, real extracted
coupling caps), dual-registered in CMake + Bazel. Asserts:
  - hold stage-delay delta has the correct SIGN (negative = early
    arrival, the hold-relevant case) and is the exact sign mirror of the
    setup delta: |dDelay_hold| == dDelay_setup == Rdrv*k*CcActive,
  - the delta is linear in k,
  - enabling -hold pulls the victim net's min-path arrival earlier
    (the adjustment reaches min/hold timing),
  - disabling restores baseline min timing exactly (byte-reversible),
  - k=0 with -hold is an explicit no-op.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add the MODE dimension on top of slice-1's cross-corner report_mcmm_slack,
consuming OpenSTA's existing Mode/Scene model (no src/sta edit).

- report_mcmm_slack -by_mode (additive, default OFF): surfaces the limiting
  MODE next to the limiting corner -- the true cross-mode x corner (mode,
  corner) pair per endpoint -- and prints a per-mode worst-slack breakdown.
- computeMcmmSlackByMode(): per-mode worst slack over each Mode::scenes(),
  read-only, reusing slice-1's public Search path-end API.
- Machine-readable test hooks mcmm_mode_report_lines / mcmm_per_mode_lines.
- With -by_mode off, output is byte-identical to slice 1.

OpenSTA already provides the mode/scene model (Mode/Scene, StaState::modes,
multiMode) and the user setup surface (set_mode, define_scene -mode,
get_modes). Slice 2 only consumes it.



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
New regression report_mcmm_slack_by_mode: func (clk 0.3) and test (clk 0.2)
modes, each with fast/slow corners. Asserts:
 - per-mode worst slack == min over that mode's scenes, slow corner limiting;
 - true cross-mode x corner worst == min over all scenes, limited by the
   tighter mode's slow corner (test, test_slow);
 - test mode worst is exactly 0.1 ns tighter than func (distinct SDC proof);
 - slice-1 worst-slack numbers unchanged by the added mode dimension.

Registered in CMake (CMakeLists.txt) and Bazel (BUILD).



Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Comment-only cleanup: remove dangling references to internal
scratch design notes (*_INVESTIGATION.md, AGENT_REPORT.md)
that are not part of the tree. No functional change.

Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add a first-slice functional signal-integrity (noise/glitch) report.
The existing SI work covered the timing/delay half of crosstalk
(set_coupling_miller_factor, set_si_timing_window); this adds the
functional half: estimate the peak noise bump injected on a quiet
victim net by its switching aggressor(s) through the extracted coupling
caps, and flag nets whose bump exceeds a noise threshold.

New commands:
- report_noise [-threshold frac] [-max_nets n] [-corner i] [-vdd v]
- set_noise_threshold frac   (default 0.3*Vdd)

Model (full derivation in NOISE_INVESTIGATION.md):
  charge-share peak  Vbump_share = Vdd * Cc / (Cc + Cgnd)
  driver/edge atten  k = tau_aggr / (tau_aggr + tau_victim) in (0,1]
  Vbump = Vbump_share * k
where Cc/Cgnd come from dbNet coupling/total caps and Rdrv from Liberty
driveResistance(). The refinement only ever reduces the charge-share
bound, so the report is never optimistic.

The feature is purely additive and read-only: it never mutates Cc,
never reduces parasitics, and never invalidates delays. Verified that
report_checks output and worst-case TNS are byte-identical before and
after running report_noise.

Test: src/rcx/test/coupling_si_noise.tcl (PASSFAIL, CMake + Bazel)
runs on gcd with real extracted coupling and asserts the report ranks
by bump, the model is monotonic in the Cc/(Cc+Cgnd) ratio, the
threshold is monotonic, and timing is untouched.


Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Turn the read-only report_noise crosstalk bump into an OPTIONAL,
flag-gated delay PUSH on the victim net so report_checks reflects
noise-degraded timing when enabled. Default (disabled) reproduces
byte-identical baseline timing.

Model (NOISE_TMG_INVESTIGATION.md):
  bump (V)   reused from noise_estimate_victim (charge-share * k)
  push (s)   = scale * bump * slew_victim / Vdd  (linear-ramp shift)
  apply      dC = push / Rdrv, realized by bloating the victim's
             coupling caps via Parasitics::setCapacitorValue (originals
             snapshotted), then deleteReducedParasitics + delaysInvalid.
             Reuses the SI-window slice's reversible machinery; no
             src/sta changes.

Commands (src/dbSta/src/dbSta.tcl):
  set_noise_delay -enable|-disable [-scale k] [-max_nets N] [-corner i] [-vdd v]
  report_noise_delay [-max_nets N] [-corner i] [-vdd v]
  noise_delay_push_for_net_cmd (test introspection)

Correctness:
  * DISABLED == byte-identical baseline (report_checks/TNS/WNS).
  * ENABLED degrades setup TNS/WNS in the expected direction; a
    zero-coupling net gets zero push; model non-negative & monotonic
    in the bump.
  * Undriven / no-Liberty victims are reported but not applied (no Rdrv).

Adds rcx/test/coupling_si_noise_timing.tcl (CMake + Bazel registered),
reusing the extract + read_spef -keep_capacitive_coupling flow. Full
dbSta+rcx ctest suite green (101/101).


Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant