Sta variant corner - #394
Conversation
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
…pt set_ip_trans and set_load Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for analysis corners (PVT/RC corners) to group scenes sharing operating points across modes and manage corner-scoped SDC constraints like timing derates, IO delays, clock uncertainty, and clock latency. The feedback suggests optimizing string lookups in AnalysisCornerNameMap by accepting std::string_view in makeAnalysisCorner and findAnalysisCorner to avoid unnecessary allocations, and improving the time complexity of unique delay set collection in cornerDelaySets from O(N^2) to O(N log N) using std::set.
| AnalysisCorner *makeAnalysisCorner(const std::string &name); | ||
| AnalysisCorner *findAnalysisCorner(const std::string &name) const; |
There was a problem hiding this comment.
You're using std::less<> for AnalysisCornerNameMap in AnalysisCorner.hh, which enables heterogeneous lookups (e.g., with std::string_view) to avoid std::string allocations on lookups. To fully leverage this, consider changing the signatures of makeAnalysisCorner and findAnalysisCorner to accept std::string_view instead of const std::string &.
AnalysisCorner *makeAnalysisCorner(std::string_view name);
AnalysisCorner *findAnalysisCorner(std::string_view name) const;There was a problem hiding this comment.
Applied. makeAnalysisCorner/findAnalysisCorner now take std::string_view; find goes through findStringKey (the exact idiom upstream's Sta::findMode(std::string_view) uses
| std::vector<DelaySet*> delay_sets; | ||
| for (const Scene *scene : mode->scenes()) { | ||
| DelaySet *delays = cornerDelaysLeafPin(scene, pin, delays_leaf_pin); | ||
| if (delays | ||
| && std::find(delay_sets.begin(), delay_sets.end(), delays) | ||
| == delay_sets.end()) | ||
| delay_sets.push_back(delays); | ||
| } | ||
| return delay_sets; |
There was a problem hiding this comment.
The current implementation to find unique DelaySet* uses std::find within a loop over scenes, which has a time complexity of O(N^2) where N is the number of scenes. For better performance, especially if a mode could have a large number of scenes, consider using std::set to collect unique pointers, which would have a complexity of O(N log N).
std::set<DelaySet*> unique_delay_sets;
for (const Scene *scene : mode->scenes()) {
if (auto* delays = cornerDelaysLeafPin(scene, pin, delays_leaf_pin)) {
unique_delay_sets.insert(delays);
}
}
return {unique_delay_sets.begin(), unique_delay_sets.end()};There was a problem hiding this comment.
declined: N <= scenes-per-mode (~10), distinct sets bounded by corner count, so linear dedup beats std::set's allocations at this scale, and std::set's pointer-order iteration would make enumeration order nondeterministic across runs, which we avoid in the timing engine.
|
The following work currently: The corner itself isn't in the property dispatch: no PropertyRegistry<const AnalysisCorner*>, so the following don't work yet: |
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
Summary
Adds an
analysis_cornerobject to the OpenROAD fork of OpenSTA: a namedbundle of per-corner setup data (liberty, parasitics, corner-scoped SDC)
that scenes reference. One logical mode can now be analyzed across N
corners with different derates, IO delays, clock uncertainty, and clock
latency — without defining one composed mode per (mode x corner) pair.
Scenes remain the only unit of analysis and results; the corner is a
setup-side object that computes nothing. The timing engine's data model
is unchanged.
Motivation
Per-corner data (derates, IO budgets from external blocks, uncertainty)
lives in SDC, but SDC state is per-mode. Without this feature, MCMM
flows must compose mode+corner SDC files into synthetic modes
(
func_ss,func_ff, ...): each is a fullModeinstance (ownSdc,Sim,ClkNetwork,Genclks,PathGroups) duplicated per corner, andthe generated mode names surface in
report_checksheaders,get_modes,write_sdc -mode, and every downstream script. This PR removes the needfor synthetic modes entirely: reports show the real mode, and the mode
list stays clean.
User-facing commands
All existing commands and arguments are unchanged; flows that do not use
corners are unaffected.
Design
(mode, corner), lazily created. The overlay reuses the existing Sdc
class unmodified; whitelisted SDC write commands target it when a
corner scope is active, and engine read points consult it with the
mode Sdc as fallback.
set_output_delay, set_clock_uncertainty (all forms),
set_clock_latency / insertion, and their unset forms. Everything
else — clocks, exceptions, case analysis, and all other mode-level SDC
writes — errors out in corner scope, so structural constraints can
never exist in two places.
replaces the mode's wholesale for that family's key — whole derate
table, per pin for IO delays, per clock for uncertainty, per lookup
for latency) or it doesn't (mode value applies untouched). No merging.
The only ordering is the pin-beats-clock specificity the code already
has; a corner value wins only at equal specificity.
the mode's Clock* (upstream stores it on the Clock object, which is
shared across corners); purged on remove_clock / sta::clear.
Tcl-side filtering.
Implementation / merge hygiene
search/AnalysisCorner.cc, search/AnalysisCorner.i,
tcl/AnalysisCorner.tcl.
(// ---- OpenROAD fork: analysis_corner support ----) intended to be
re-applied on upstream merges: read-point overrides in
search/Search.cc, PathEnd.cc, VisitPathEnds.cc, CheckTiming.cc,
ReportPath.cc, one-line cmdSdc() -> cmdCornerSdc() swaps in the
whitelisted write commands in sdc/Sdc.i, and one inline accessor in
Sdc.hh. Sdc.cc is untouched.
inline null/empty checks; no overlays are allocated unless a
corner-scoped SDC command runs.
Testing
liberty-spef bundles, composition), search_corner_sdc_derate
(1 mode x N corners vs equivalent synthetic-mode setup — exact
numeric equivalence asserted in-test), search_corner_sdc_bundle
(full whitelist per corner vs manual composition — exact equivalence;
corner isolation; guard errors; redefine semantics).
Known limitations (documented)
3711); per-corner RC is expected via per-corner SPEF.
computation or the clock arrival implied by corner IO delays'
-clock reference (mode values used).
wholesale per pin, no tombstones).
found in upstream behavior, not introduced here).