From 8fb0cc305d5f164e358ba85397dd1e99ecb6eec8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 25 Oct 2025 11:44:23 -0700 Subject: [PATCH] Sta::endpointSlack Signed-off-by: James Cherry --- include/sta/PathGroup.hh | 6 ++-- search/PathGroup.cc | 77 ++++++++++++++++++++++++++++------------ search/Sta.cc | 12 ++----- 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/include/sta/PathGroup.hh b/include/sta/PathGroup.hh index b37d2503..ca4ea606 100644 --- a/include/sta/PathGroup.hh +++ b/include/sta/PathGroup.hh @@ -107,7 +107,6 @@ protected: class PathGroups : public StaState { public: - PathGroups(const StaState *sta); PathGroups(int group_path_count, int endpoint_path_count, bool unique_pins, @@ -135,6 +134,8 @@ public: PathGroup *findPathGroup(const Clock *clock, const MinMax *min_max) const; PathGroup *pathGroup(const PathEnd *path_end) const; + static std::string pathGroupName(const PathEnd *path_end, + const StaState *sta); static const char *asyncPathGroupName() { return async_group_name_; } static const char *pathDelayGroupName() { return path_delay_group_name_; } static const char *gatedClkGroupName() { return gated_clk_group_name_; } @@ -178,7 +179,8 @@ protected: const MinMax *min_max); bool reportGroup(const char *group_name, PathGroupNameSet *group_names) const; - GroupPath *groupPathTo(const PathEnd *path_end) const; + static GroupPath *groupPathTo(const PathEnd *path_end, + const StaState *sta); int group_path_count_; int endpoint_path_count_; diff --git a/search/PathGroup.cc b/search/PathGroup.cc index c7dabd6b..79054f2c 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -248,22 +248,6 @@ const char *PathGroups::gated_clk_group_name_ = "gated clock"; const char *PathGroups::async_group_name_ = "asynchronous"; const char *PathGroups::unconstrained_group_name_ = "unconstrained"; -PathGroups::PathGroups(const StaState *sta) : - StaState(sta), - group_path_count_(0), - endpoint_path_count_(0), - unique_pins_(false), - slack_min_(-INF), - slack_max_(INF) -{ - makeGroups(group_path_count_, endpoint_path_count_, unique_pins_, - slack_min_, slack_max_, nullptr, - true, true, true, true, MinMax::max()); - makeGroups(group_path_count_, endpoint_path_count_, unique_pins_, - slack_min_, slack_max_, nullptr, - true, true, true, true, MinMax::min()); -} - PathGroups::PathGroups(int group_path_count, int endpoint_path_count, bool unique_pins, @@ -419,7 +403,7 @@ PathGroups::pathGroup(const PathEnd *path_end) const { const MinMax *min_max = path_end->minMax(this); int mm_index = min_max->index(); - GroupPath *group_path = groupPathTo(path_end); + GroupPath *group_path = groupPathTo(path_end, this); if (path_end->isUnconstrained()) return unconstrained_[mm_index]; // GroupPaths have precedence. @@ -462,16 +446,63 @@ PathGroups::pathGroup(const PathEnd *path_end) const } } +// Mirrors PathGroups::pathGroup. +std::string +PathGroups::pathGroupName(const PathEnd *path_end, + const StaState *sta) +{ + GroupPath *group_path = groupPathTo(path_end, sta); + if (path_end->isUnconstrained()) + return unconstrained_group_name_; + // GroupPaths have precedence. + else if (group_path) { + if (group_path->isDefault()) + return path_delay_group_name_; + else + return group_path->name(); + } + else if (path_end->isCheck() || path_end->isLatchCheck()) { + const TimingRole *check_role = path_end->checkRole(sta); + const Clock *tgt_clk = path_end->targetClk(sta); + if (check_role == TimingRole::removal() + || check_role == TimingRole::recovery()) + return async_group_name_; + else + return tgt_clk->name(); + } + else if (path_end->isOutputDelay() + || path_end->isDataCheck()) + return path_end->targetClk(sta)->name(); + else if (path_end->isGatedClock()) + return gated_clk_group_name_; + else if (path_end->isPathDelay()) { + // Path delays that end at timing checks are part of the target clk group + // unless -ignore_clock_latency is true. + PathDelay *path_delay = path_end->pathDelay(); + const Clock *tgt_clk = path_end->targetClk(sta); + if (tgt_clk + && !path_delay->ignoreClkLatency()) + return tgt_clk->name(); + else + return path_delay_group_name_; + } + else { + sta->report()->critical(1391, "unknown path end type"); + return nullptr; + } +} + GroupPath * -PathGroups::groupPathTo(const PathEnd *path_end) const +PathGroups::groupPathTo(const PathEnd *path_end, + const StaState *sta) { const Path *path = path_end->path(); - const Pin *pin = path->pin(this); + const Pin *pin = path->pin(sta); ExceptionPath *exception = - search_->exceptionTo(ExceptionPathType::group_path, path, - pin, path->transition(this), - path_end->targetClkEdge(this), - path->minMax(this), false, false); + sta->search()->exceptionTo(ExceptionPathType::group_path, path, + pin, path->transition(sta), + path_end->targetClkEdge(sta), + path->minMax(sta), false, false); return dynamic_cast(exception); } diff --git a/search/Sta.cc b/search/Sta.cc index e976807e..7aa1f26e 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -3036,7 +3036,6 @@ class EndpointPathEndVisitor : public PathEndVisitor { public: EndpointPathEndVisitor(const std::string &path_group_name, - const PathGroups &path_groups, const MinMax *min_max, const StaState *sta); PathEndVisitor *copy() const; @@ -3045,18 +3044,15 @@ public: private: const std::string &path_group_name_; - const PathGroups &path_groups_; const MinMax *min_max_; Slack slack_; const StaState *sta_; }; EndpointPathEndVisitor::EndpointPathEndVisitor(const std::string &path_group_name, - const PathGroups &path_groups, const MinMax *min_max, const StaState *sta) : path_group_name_(path_group_name), - path_groups_(path_groups), min_max_(min_max), slack_(MinMax::min()->initValue()), sta_(sta) @@ -3066,14 +3062,14 @@ EndpointPathEndVisitor::EndpointPathEndVisitor(const std::string &path_group_nam PathEndVisitor * EndpointPathEndVisitor::copy() const { - return new EndpointPathEndVisitor(path_group_name_, path_groups_, min_max_, sta_); + return new EndpointPathEndVisitor(path_group_name_, min_max_, sta_); } void EndpointPathEndVisitor::visit(PathEnd *path_end) { if (path_end->minMax(sta_) == min_max_ - && path_groups_.pathGroup(path_end)->name() == path_group_name_) { + && PathGroups::pathGroupName(path_end, sta_) == path_group_name_) { Slack end_slack = path_end->slack(sta_); if (delayLess(end_slack, slack_, sta_)) slack_ = end_slack; @@ -3089,10 +3085,8 @@ Sta::endpointSlack(const Pin *pin, Vertex *vertex = graph_->pinLoadVertex(pin); if (vertex) { findRequired(vertex); - // Make path groups to use PathGroups::pathGroup(PathEnd). - PathGroups path_groups(this); VisitPathEnds visit_ends(this); - EndpointPathEndVisitor path_end_visitor(path_group_name, path_groups, min_max, this); + EndpointPathEndVisitor path_end_visitor(path_group_name, min_max, this); visit_ends.visitPathEnds(vertex, &path_end_visitor); return path_end_visitor.slack(); }