Sta::endpointSlack

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-10-25 11:44:23 -07:00
parent 79ddebf153
commit 8fb0cc305d
3 changed files with 61 additions and 34 deletions

View File

@ -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_;

View File

@ -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<GroupPath*>(exception);
}

View File

@ -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();
}