From 37b304384371df1f35f0bc2ce77268605dda82ff Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 6 Nov 2025 08:56:53 -0700 Subject: [PATCH 1/3] ssta compile Signed-off-by: James Cherry --- search/ClkInfo.cc | 4 ++-- search/PathEnum.cc | 2 +- search/Search.i | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/search/ClkInfo.cc b/search/ClkInfo.cc index 76e21287..a8679101 100644 --- a/search/ClkInfo.cc +++ b/search/ClkInfo.cc @@ -179,9 +179,9 @@ ClkInfo::to_string(const StaState *sta) const result += network->pathName(gen_clk_src_); } - if (insertion_ > 0.0) { + if (delayGreater(insertion_, 0.0, sta)) { result += " insert"; - result += std::to_string(insertion_); + result += delayAsString(insertion_, sta); } if (uncertainties_) { diff --git a/search/PathEnum.cc b/search/PathEnum.cc index 07293827..a0c860fe 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -450,7 +450,7 @@ PathEnumFaninVisitor::insertUniqueEdgeDiv(Diversion *div) const RiseFall *div_rf = div_path->transition(this); auto itr = unique_edge_divs_.find({div_vertex, div_rf}); if (itr == unique_edge_divs_.end() - || div_slack > itr->second->pathEnd()->slack(this)) + || delayGreater(div_slack, itr->second->pathEnd()->slack(this), this)) itr->second = div; } diff --git a/search/Search.i b/search/Search.i index 9be59d15..3e2e761a 100644 --- a/search/Search.i +++ b/search/Search.i @@ -260,7 +260,7 @@ endpoint_slack(const Pin *pin, sta->ensureLibLinked(); if (sta->isGroupPathName(path_group_name)) { Slack slack = sta->endpointSlack(pin, std::string(path_group_name), min_max); - return sta->units()->timeUnit()->staToUser(slack); + return sta->units()->timeUnit()->staToUser(delayAsFloat(slack)); } else { sta->report()->error(1577, "%s is not a known path group name.", From 351b8287a7211a651a8b34ae79748964507c43c6 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 6 Nov 2025 12:34:53 -0700 Subject: [PATCH 2/3] issue 322 revisited Signed-off-by: James Cherry --- liberty/TimingArc.cc | 25 +++++++++++++++++-------- search/PathEnum.cc | 12 +++++++++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index b03b5cc6..f203a4af 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -565,14 +565,23 @@ TimingArc::~TimingArc() string TimingArc::to_string() const { - string str = set_->from()->name(); - str += " "; - str += from_rf_->to_string(); - str += " -> "; - str += set_->to()->name(); - str += " "; - str += to_rf_->to_string(); - return str; + if (set_->role()->isWire()) { + string str = "wire "; + str += from_rf_->to_string(); + str += " -> "; + str += to_rf_->to_string(); + return str; + } + else { + string str = set_->from()->name(); + str += " "; + str += from_rf_->to_string(); + str += " -> "; + str += set_->to()->name(); + str += " "; + str += to_rf_->to_string(); + return str; + } } GateTimingModel * diff --git a/search/PathEnum.cc b/search/PathEnum.cc index a0c860fe..e3d6ac85 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -394,7 +394,7 @@ PathEnumFaninVisitor::visitEdge(const Pin *from_pin, bool PathEnumFaninVisitor::visitFromToPath(const Pin *, Vertex *from_vertex, - const RiseFall *, + const RiseFall *from_rf, Tag *, Path *from_path, const Arrival &, @@ -410,6 +410,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, { // These paths fanin to before_div_ so we know to_vertex matches. if ((!unique_pins_ || from_vertex != prev_vertex_) + && (!unique_edges_ || from_rf != prev_arc_->fromEdge()->asRiseFall()) && arc != prev_arc_ && Tag::matchNoCrpr(to_tag, before_div_tag_) // Ignore paths that only differ by crpr from same vertex/edge. @@ -449,9 +450,14 @@ PathEnumFaninVisitor::insertUniqueEdgeDiv(Diversion *div) const Vertex *div_vertex = div_path->vertex(this); const RiseFall *div_rf = div_path->transition(this); auto itr = unique_edge_divs_.find({div_vertex, div_rf}); - if (itr == unique_edge_divs_.end() - || delayGreater(div_slack, itr->second->pathEnd()->slack(this), this)) + if (itr == unique_edge_divs_.end()) + unique_edge_divs_[{div_vertex, div_rf}] = div; + else if (delayGreater(div_slack, itr->second->pathEnd()->slack(this), this)) { + deleteDiversionPathEnd(itr->second); itr->second = div; + } + else + deleteDiversionPathEnd(div); } void From 845729ad9f914d7e398ab80f400327d7ef39c9df Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 6 Nov 2025 16:46:05 -0700 Subject: [PATCH 3/3] restore Search::makePathGroups Signed-off-by: James Cherry --- include/sta/Search.hh | 14 ++++++++++++++ search/Search.cc | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 9e925d1b..9308b31d 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -170,6 +170,19 @@ public: PathGroupSeq pathGroups(const PathEnd *path_end) const; void deletePathGroups(); + void makePathGroups(int group_path_count, + int endpoint_path_count, + bool unique_pins, + bool unique_edges, + float min_slack, + float max_slack, + PathGroupNameSet *group_names, + bool setup, + bool hold, + bool recovery, + bool removal, + bool clk_gating_setup, + bool clk_gating_hold); virtual ExceptionPath *exceptionTo(ExceptionPathType type, const Path *path, const Pin *pin, @@ -281,6 +294,7 @@ public: BfsFwdIterator *arrivalIterator() const { return arrival_iter_; } BfsBkwdIterator *requiredIterator() const { return required_iter_; } bool arrivalsAtEndpointsExist()const{return arrivals_at_endpoints_exist_;} + // Used by OpenROAD. bool makeUnclkedPaths(Vertex *vertex, bool is_segment_start, bool require_exception, diff --git a/search/Search.cc b/search/Search.cc index e6e02fdb..fbe347c0 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -467,15 +467,12 @@ Search::findPathEnds(ExceptionFrom *from, recovery = removal = false; if (!variables_->gatedClkChecksEnabled()) clk_gating_setup = clk_gating_hold = false; - path_groups_ = new PathGroups(group_path_count, endpoint_path_count, - unique_pins, unique_edges, - slack_min, slack_max, - group_names, - setup, hold, - recovery, removal, - clk_gating_setup, clk_gating_hold, - unconstrained_paths_, - this); + makePathGroups(group_path_count, endpoint_path_count, + unique_pins, unique_edges, + slack_min, slack_max, + group_names, setup, hold, + recovery, removal, + clk_gating_setup, clk_gating_hold); ensureDownstreamClkPins(); PathEndSeq path_ends = path_groups_->makePathEnds(to, unconstrained_paths_, corner, min_max, @@ -509,6 +506,32 @@ Search::findFilteredArrivals(ExceptionFrom *from, findAllArrivals(thru_latches); } +void +Search::makePathGroups(int group_path_count, + int endpoint_path_count, + bool unique_pins, + bool unique_edges, + float slack_min, + float slack_max, + PathGroupNameSet *group_names, + bool setup, + bool hold, + bool recovery, + bool removal, + bool clk_gating_setup, + bool clk_gating_hold) +{ + path_groups_ = new PathGroups(group_path_count, endpoint_path_count, + unique_pins, unique_edges, + slack_min, slack_max, + group_names, + setup, hold, + recovery, removal, + clk_gating_setup, clk_gating_hold, + unconstrained_paths_, + this); +} + // From/thrus/to are used to make a filter exception. If the last // search used a filter arrival/required times were only found for a // subset of the paths. Delete the paths that have a filter