report_checks -endpoint_path_count -slack_min

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-01-15 09:17:14 -07:00
parent 44e7316da1
commit 70bb5e9440
5 changed files with 42 additions and 11 deletions

View File

@ -68,8 +68,7 @@ public:
Path *path() { return &path_; } Path *path() { return &path_; }
const Path *path() const { return &path_; } const Path *path() const { return &path_; }
PathRef &pathRef() { return path_; } PathRef &pathRef() { return path_; }
virtual void setPath(PathEnumed *path, virtual void setPath(const Path *path);
const StaState *sta);
Vertex *vertex(const StaState *sta) const; Vertex *vertex(const StaState *sta) const;
const MinMax *minMax(const StaState *sta) const; const MinMax *minMax(const StaState *sta) const;
// Synonym for minMax(). // Synonym for minMax().
@ -256,8 +255,7 @@ public:
virtual Slack slackNoCrpr(const StaState *sta) const; virtual Slack slackNoCrpr(const StaState *sta) const;
virtual int exceptPathCmp(const PathEnd *path_end, virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const; const StaState *sta) const;
virtual void setPath(PathEnumed *path, virtual void setPath(const Path *path);
const StaState *sta);
protected: protected:
PathEndClkConstrained(Path *path, PathEndClkConstrained(Path *path,

View File

@ -61,6 +61,7 @@ public:
void pushEnds(PathEndSeq &path_ends); void pushEnds(PathEndSeq &path_ends);
// Predicate to determine if a PathEnd is worth saving. // Predicate to determine if a PathEnd is worth saving.
bool saveable(PathEnd *path_end); bool saveable(PathEnd *path_end);
bool enumMinSlackUnderMin(PathEnd *path_end);
int maxPaths() const { return group_path_count_; } int maxPaths() const { return group_path_count_; }
PathGroupIterator *iterator(); PathGroupIterator *iterator();
// This does NOT delete the path ends. // This does NOT delete the path ends.

View File

@ -51,8 +51,7 @@ PathEnd::~PathEnd()
} }
void void
PathEnd::setPath(PathEnumed *path, PathEnd::setPath(const Path *path)
const StaState *)
{ {
path_.init(path); path_.init(path);
} }
@ -523,8 +522,7 @@ PathEndClkConstrained::PathEndClkConstrained(Path *path,
} }
void void
PathEndClkConstrained::setPath(PathEnumed *path, PathEndClkConstrained::setPath(const Path *path)
const StaState *)
{ {
path_.init(path); path_.init(path);
crpr_valid_ = false; crpr_valid_ = false;

View File

@ -377,7 +377,7 @@ PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div,
path_enum_->makeDivertedPath(path_end_->path(), &before_div_, after_div, path_enum_->makeDivertedPath(path_end_->path(), &before_div_, after_div,
div_arc, div_path, after_div_copy); div_arc, div_path, after_div_copy);
div_end = path_end_->copy(); div_end = path_end_->copy();
div_end->setPath(div_path, this); div_end->setPath(div_path);
} }
void void

View File

@ -122,6 +122,38 @@ PathGroup::saveable(PathEnd *path_end)
return false; return false;
} }
// endpoint_path_count > 1 with slack_min requires
// saving endpoints with slack > slack_min so that
// path enumeration can find them. Use the patg end
// with the min(max) delay to prune ends that cannot
// onion peel down to slack_min.
bool
PathGroup::enumMinSlackUnderMin(PathEnd *path_end)
{
if (compare_slack_
&& endpoint_path_count_ > 1
&& slack_min_ > -INF) {
const Path *path = path_end->path();
PathAnalysisPt *other_ap = path->pathAnalysisPt(sta_)->tgtClkAnalysisPt();
const Tag *tag = path->tag(sta_);
VertexPathIterator other_iter(path->vertex(sta_),
path->transition(sta_),
other_ap, sta_);
while (other_iter.hasNext()) {
PathVertex *other = other_iter.next();
if (tagMatchCrpr(other->tag(sta_), tag)) {
PathEnd *end_min = path_end->copy();
end_min->setPath(other);
bool slack_under = fuzzyGreater(end_min->slackNoCrpr(sta_), slack_min_);
delete end_min;
if (slack_under)
return true;
}
}
}
return false;
}
void void
PathGroup::insert(PathEnd *path_end) PathGroup::insert(PathEnd *path_end)
{ {
@ -700,7 +732,8 @@ MakePathEndsAll::vertexEnd(Vertex *)
path_end->path()->tag(sta_)->index()); path_end->path()->tag(sta_)->index());
// Give the group a copy of the path end because // Give the group a copy of the path end because
// it may delete it during pruning. // it may delete it during pruning.
if (group->saveable(path_end)) { if (group->saveable(path_end)
|| group->enumMinSlackUnderMin(path_end)) {
group->insert(path_end->copy()); group->insert(path_end->copy());
unique_ends.insert(path_end); unique_ends.insert(path_end);
n++; n++;
@ -787,7 +820,8 @@ PathGroups::enumPathEnds(PathGroup *group,
PathGroupIterator *end_iter = group->iterator(); PathGroupIterator *end_iter = group->iterator();
while (end_iter->hasNext()) { while (end_iter->hasNext()) {
PathEnd *end = end_iter->next(); PathEnd *end = end_iter->next();
if (group->saveable(end)) if (group->saveable(end)
|| group->enumMinSlackUnderMin(end))
path_enum.insert(end); path_enum.insert(end);
} }
delete end_iter; delete end_iter;