search: POCV per-stage sigma holder + LVF variance injection + LVF-library gate (stacks on #383)#385
Conversation
Add a flag-gated hook (AocvDepthDerate interface + Search::deratedDelayData) so the OCV derate applied to data-path combinational arcs during forward arrival propagation can be selected by the path's accumulated combinational depth instead of the flat SDC factor. When no hook is installed (the default) deratedDelayData forwards verbatim to deratedDelay, so timing is byte-identical to upstream. Only data-path combinational cell arcs are depth-derated; clock/reg/latch/check arcs keep the flat derate. Depth is the count of combinational arcs on the live from_path prev chain + 1. All edits marked // OpenROAD-fork: AOCV. clang-format not run on src/sta/*. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add Parasitics::setCapacitorValue (default no-op) and a ConcreteParasitics override / ConcreteParasiticDevice::setValue so the OpenROAD timing-window aware coupling derate can scale individual coupling caps. Only invoked from the OpenROAD window path; stock OpenSTA behavior is unchanged. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
|
|
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
… review) Return early on a null ParasiticCapacitor instead of dereferencing it. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add a default-OFF Search::PocvSigma state holder (enabled, per-stage sigma fraction, n_sigma, active()) plus inline pocvSigma()/setPocvSigma() accessors and a pocv_sigma_ member. This is read ONLY by the OpenROAD-side report-only POCV command (report_checks_pocv / pocvAdjustPathEnd in src/dbSta); no forward-search / arrival-propagation code reads it, so with POCV inactive (the default) timing is byte-identical to upstream. Parametric POCV variation combines in quadrature (root-sum-square), which does not compose with the additive arrival sum the search propagates, so POCV is intentionally NOT a propagation hook (unlike AOCV). See POCV_INVESTIGATION.md. Header-only edit, marked // OpenROAD-fork: POCV. clang-format not run on src/sta/*. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
…ce injection Inject the synthetic per-stage POCV sigma (k*d_i)^2 into combinational data-path arc delays inside deratedDelayData when PocvSigma is in -propagate mode. The native statistical delay-ops (DelayOpsNormal) then accumulate the variance in quadrature through delaySum during the forward search, and report arrival +/- n_sigma*sqrt(variance) at the checks. - Search.hh: add PocvSigma::propagate flag + propagateActive() gate. - Search.cc: factor the scalar (mean) data-path derate into deratedDelayDataMean; deratedDelayData layers the synthetic variance on top without changing the mean. Default OFF (propagate=false) and scalar PocvMode => zero variance => timing is byte-identical to baseline. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
Add PocvSigma::from_liberty so set_pocv_sigma -from_liberty sources the per-stage delay sigma from the real Liberty LVF ocv_sigma_* tables via the native statistical delay calc (GateTableModel::gateDelayPocv under PocvMode::normal) instead of the synthetic global per_stage. In this mode propagateActive() returns false so the synthetic (k*d) injection in Search::deratedDelayData is suppressed and cannot overwrite the library-derived stdDev. Default from_liberty=false keeps the existing -propagate/-sigma behaviour and a byte-identical flag-off baseline. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
95feabe to
f41a799
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for OpenROAD-fork specific features, including SI-window aware coupling capacitor value adjustments, depth-dependent OCV derating (AOCV), and parametric OCV (POCV/LVF) parameters with propagation-time synthetic variance injection. The review feedback suggests several improvements: ensuring that POCV/LVF activation checks strictly require positive coefficients (> 0.0f) to prevent negative values, adding an early return for infinite delays in deratedDelayData to avoid potential NaN or undefined behavior, and optimizing a redundant delayAsFloat call within a critical timing loop.
| bool active() const { return enabled && per_stage != 0.0f && n_sigma != 0.0f; } | ||
| // OpenROAD-fork: LVF-lib -- library-driven mode gate. Independent of the | ||
| // synthetic per_stage; needs only enabled + a sign-off quantile (n_sigma). | ||
| bool libertyActive() const { return enabled && from_liberty && n_sigma != 0.0f; } |
There was a problem hiding this comment.
Using != 0.0f to check if per_stage and n_sigma are active can allow negative or invalid values to pass through, which could lead to incorrect statistical calculations (e.g., negative standard deviation). It is safer and more robust to ensure these coefficients are strictly positive (> 0.0f) before activating the POCV/LVF logic.
| bool active() const { return enabled && per_stage != 0.0f && n_sigma != 0.0f; } | |
| // OpenROAD-fork: LVF-lib -- library-driven mode gate. Independent of the | |
| // synthetic per_stage; needs only enabled + a sign-off quantile (n_sigma). | |
| bool libertyActive() const { return enabled && from_liberty && n_sigma != 0.0f; } | |
| bool active() const { return enabled && per_stage > 0.0f && n_sigma > 0.0f; } | |
| // OpenROAD-fork: LVF-lib -- library-driven mode gate. Independent of the | |
| // synthetic per_stage; needs only enabled + a sign-off quantile (n_sigma). | |
| bool libertyActive() const { return enabled && from_liberty && n_sigma > 0.0f; } |
| ArcDelay delay = deratedDelayDataMean(from_path, from_vertex, arc, edge, | ||
| min_max, dcalc_ap, sdc); | ||
|
|
||
| // OpenROAD-fork: LVF -- propagation-time POCV variance injection. |
There was a problem hiding this comment.
If the computed mean delay is infinite (e.g., representing an unconstrained or blocked path), performing float operations on it or passing it to makeDelay is unnecessary and could potentially lead to NaN or other undefined behavior. It is safer to check if the delay is infinite using delayInf and return early.
ArcDelay delay = deratedDelayDataMean(from_path, from_vertex, arc, edge,
min_max, dcalc_ap, sdc);
if (delayInf(delay, this))
return delay;
// OpenROAD-fork: LVF -- propagation-time POCV variance injection.| const float d = delayAsFloat(delay); // nominal stage delay mean | ||
| if (d > 0.0f) { | ||
| const float stage_sigma = k * d; // per-stage sigma = k * d_i | ||
| // makeDelay(mean, std_dev) stores std_dev^2 == (k*d_i)^2 as the variance, | ||
| // which is exactly the per-stage contribution the path accumulates in | ||
| // quadrature. The mean is preserved so the nominal arrival is unchanged. | ||
| // Any prior arc variance (e.g. from LVF liberty) is replaced by the | ||
| // synthetic model on purpose -- they are mutually exclusive configs. | ||
| delay = makeDelay(delayAsFloat(delay), stage_sigma); |
There was a problem hiding this comment.
Since delayAsFloat(delay) is already computed and stored in d, we can reuse d instead of calling delayAsFloat(delay) again. This avoids a redundant function call/conversion in a critical timing propagation loop.
const float d = delayAsFloat(delay); // nominal stage delay mean
if (d > 0.0f) {
const float stage_sigma = k * d; // per-stage sigma = k * d_i
// makeDelay(mean, std_dev) stores std_dev^2 == (k*d_i)^2 as the variance,
// which is exactly the per-stage contribution the path accumulates in
// quadrature. The mean is preserved so the nominal arrival is unchanged.
// Any prior arc variance (e.g. from LVF liberty) is replaced by the
// synthetic model on purpose -- they are mutually exclusive configs.
delay = makeDelay(d, stage_sigma);- PocvSigma::active()/libertyActive(): require per_stage/n_sigma > 0.0f (reject negative/invalid values, not just != 0). - Variance injection: guard against non-finite stage delay (std::isfinite) and reuse the already-computed mean 'd' instead of recomputing delayAsFloat. Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
f41a799 to
61875ee
Compare
|
Thanks — addressed the review (gemini review re-ran fine after the earlier error):
search/sdc/derate/crpr/multicorner + pocv/lvf suites pass (118/118). (Still a draft — stacks on #383.) |
Summary
Adds a parametric statistical-OCV (POCV / LVF) capability in three layered, default-OFF slices. With POCV inactive, timing is byte-identical to upstream.
1. POCV per-stage sigma state holder (
Search.hh)Adds a default-OFF
Search::PocvSigmastate holder (enabled, per-stage sigma fraction, n_sigma,active()) plus inlinepocvSigma()/setPocvSigma()accessors and apocv_sigma_member. Read only by an external report-only POCV command; no forward-search code reads it. Parametric POCV variation combines in quadrature (root-sum-square), which does not compose with the additive arrival sum the search propagates, so this holder is intentionally not a propagation hook.2. LVF propagation-time variance injection (
Search.cc,Search.hh)Injects the synthetic per-stage POCV sigma
(k*d_i)^2into combinational data-path arc delays insidederatedDelayDatawhenPocvSigmais in-propagatemode. The native statistical delay-ops (DelayOpsNormal) then accumulate the variance in quadrature throughdelaySumduring the forward search, reporting arrival ± n_sigma·sqrt(variance). Factors the scalar (mean) data-path derate intoderatedDelayDataMean; layers variance on top without changing the mean. Default OFF → zero variance → byte-identical baseline.3. LVF-lib library-driven POCV gate (
Search.hh)Adds
PocvSigma::from_libertysoset_pocv_sigma -from_libertysources the per-stage delay sigma from real Liberty LVFocv_sigma_*tables via the native statistical delay calc (GateTableModel::gateDelayPocvunderPocvMode::normal) instead of the synthetic global per_stage. In this modepropagateActive()returns false so the synthetic(k*d)injection is suppressed and cannot overwrite the library-derived stdDev. Defaultfrom_liberty=falsekeeps the-propagate/-sigmabehavior and a byte-identical flag-off baseline.This is a stacked PR on top of #383. It layers directly on the
deratedDelayDatahook that #383 introduces (patch 2 splits it intoderatedDelayDataMean+ variance). GitHub will show the two #383 commits here until that PR merges; after it merges I'll rebase this ontomasterand only the three POCV commits will remain. Please review/merge #383 first.Testing
tcl.power.vcd_detailed) is a pre-existing last-digit floating-point rounding diff in the power module that fails identically on unmodifiedmaster(unrelated to this change).from_liberty=falsebyte-identical baseline.Notes
clang-formatintentionally not run onsrc/sta/*per project convention.