report -unique_edges_to_endpoint
commit d8bb65d6e87cf95b3eada82b315351867b50fa01
Author: James Cherry <cherry@parallaxsw.com>
Date: Tue Nov 4 12:25:56 2025 -0700
report -unique_edges_to_endpoint doc
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 2979eda02f4f2fb38da4a5df9e9ece0d00951b6f
Author: James Cherry <cherry@parallaxsw.com>
Date: Mon Nov 3 11:51:02 2025 -0700
redirect report_check_types
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 55960d4a63a999fc08f311c53fb053e4d54d1029
Author: James Cherry <cherry@parallaxsw.com>
Date: Mon Nov 3 11:28:15 2025 -0700
report -unique_edges_to_endpoint
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 8c56b5c2c08f546fee02e017a87cd94480dbabfc
Author: James Cherry <cherry@parallaxsw.com>
Date: Sun Nov 2 16:05:28 2025 -0700
PathEnum cleanup
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit c02b96a9c7b6e7c9ce99ee76a211f365bcda7428
Author: James Cherry <cherry@parallaxsw.com>
Date: Sun Nov 2 11:16:34 2025 -0700
PathEnum cleanup
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
f6523bd9c6
commit
97b711c7c4
|
|
@ -12,6 +12,11 @@ build directory instead of `app/`.
|
||||||
The set_max_delay and set_min_delay commands now support the -probe option.
|
The set_max_delay and set_min_delay commands now support the -probe option.
|
||||||
With -probe these commands do not break paths at internal (non-startpoint) pins.
|
With -probe these commands do not break paths at internal (non-startpoint) pins.
|
||||||
|
|
||||||
|
The report_checks command now supports a -unique_edges_to_endpoint option
|
||||||
|
to remove paths through identical pins and rise/fall edges.
|
||||||
|
|
||||||
|
report_checks [-unique_edges_to_endpoint]
|
||||||
|
|
||||||
Release 2.6.1 2025/03/30
|
Release 2.6.1 2025/03/30
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
|
||||||
2329
doc/OpenSTA.fodt
2329
doc/OpenSTA.fodt
File diff suppressed because it is too large
Load Diff
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -53,6 +53,7 @@ public:
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const StaState *sta);
|
const StaState *sta);
|
||||||
// Path group that compares arrival time, sorted by min_max.
|
// Path group that compares arrival time, sorted by min_max.
|
||||||
|
|
@ -60,6 +61,7 @@ public:
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float min_slack,
|
float min_slack,
|
||||||
float max_slack,
|
float max_slack,
|
||||||
const StaState *sta);
|
const StaState *sta);
|
||||||
|
|
@ -83,6 +85,7 @@ protected:
|
||||||
size_t group_path_count,
|
size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float min_slack,
|
float min_slack,
|
||||||
float max_slack,
|
float max_slack,
|
||||||
bool cmp_slack,
|
bool cmp_slack,
|
||||||
|
|
@ -96,6 +99,7 @@ protected:
|
||||||
size_t group_path_count_;
|
size_t group_path_count_;
|
||||||
size_t endpoint_path_count_;
|
size_t endpoint_path_count_;
|
||||||
bool unique_pins_;
|
bool unique_pins_;
|
||||||
|
bool unique_edges_;
|
||||||
float slack_min_;
|
float slack_min_;
|
||||||
float slack_max_;
|
float slack_max_;
|
||||||
PathEndSeq path_ends_;
|
PathEndSeq path_ends_;
|
||||||
|
|
@ -112,6 +116,7 @@ public:
|
||||||
PathGroups(int group_path_count,
|
PathGroups(int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
|
|
@ -148,6 +153,7 @@ protected:
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max);
|
const MinMaxAll *min_max);
|
||||||
void makeGroupPathEnds(ExceptionTo *to,
|
void makeGroupPathEnds(ExceptionTo *to,
|
||||||
|
|
@ -162,6 +168,7 @@ protected:
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
bool cmp_slack);
|
bool cmp_slack);
|
||||||
|
|
||||||
void pushGroupPathEnds(PathEndSeq &path_ends);
|
void pushGroupPathEnds(PathEndSeq &path_ends);
|
||||||
|
|
@ -171,6 +178,7 @@ protected:
|
||||||
void makeGroups(int group_path_count,
|
void makeGroups(int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
|
|
@ -185,6 +193,7 @@ protected:
|
||||||
int group_path_count_;
|
int group_path_count_;
|
||||||
int endpoint_path_count_;
|
int endpoint_path_count_;
|
||||||
bool unique_pins_;
|
bool unique_pins_;
|
||||||
|
bool unique_edges_;
|
||||||
float slack_min_;
|
float slack_min_;
|
||||||
float slack_max_;
|
float slack_max_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ public:
|
||||||
size_t group_path_count,
|
size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
|
|
@ -169,18 +170,6 @@ public:
|
||||||
|
|
||||||
PathGroupSeq pathGroups(const PathEnd *path_end) const;
|
PathGroupSeq pathGroups(const PathEnd *path_end) const;
|
||||||
void deletePathGroups();
|
void deletePathGroups();
|
||||||
void makePathGroups(int group_path_count,
|
|
||||||
int endpoint_path_count,
|
|
||||||
bool unique_pins,
|
|
||||||
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,
|
virtual ExceptionPath *exceptionTo(ExceptionPathType type,
|
||||||
const Path *path,
|
const Path *path,
|
||||||
const Pin *pin,
|
const Pin *pin,
|
||||||
|
|
|
||||||
|
|
@ -821,9 +821,12 @@ public:
|
||||||
// Number of paths to report for
|
// Number of paths to report for
|
||||||
// each endpoint.
|
// each endpoint.
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
// endpoint_path_count paths report unique pins
|
// endpoint_path_count paths report paths with
|
||||||
// without rise/fall variations.
|
// unique pins.
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
// endpoint_path_count paths report paths with
|
||||||
|
// unique pins and rise/fall edges.
|
||||||
|
bool unique_edges,
|
||||||
// Min/max bounds for slack of
|
// Min/max bounds for slack of
|
||||||
// returned path ends.
|
// returned path ends.
|
||||||
float slack_min,
|
float slack_min,
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ namespace sta {
|
||||||
// after_div<--------+
|
// after_div<--------+
|
||||||
// |
|
// |
|
||||||
// <--...--before_div<--...--path<---path_end
|
// <--...--before_div<--...--path<---path_end
|
||||||
|
//
|
||||||
class Diversion
|
class Diversion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -105,6 +106,7 @@ deleteDiversionPathEnd(Diversion *div)
|
||||||
PathEnum::PathEnum(size_t group_path_count,
|
PathEnum::PathEnum(size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
bool cmp_slack,
|
bool cmp_slack,
|
||||||
const StaState *sta) :
|
const StaState *sta) :
|
||||||
StaState(sta),
|
StaState(sta),
|
||||||
|
|
@ -112,6 +114,7 @@ PathEnum::PathEnum(size_t group_path_count,
|
||||||
group_path_count_(group_path_count),
|
group_path_count_(group_path_count),
|
||||||
endpoint_path_count_(endpoint_path_count),
|
endpoint_path_count_(endpoint_path_count),
|
||||||
unique_pins_(unique_pins),
|
unique_pins_(unique_pins),
|
||||||
|
unique_edges_(unique_edges),
|
||||||
div_queue_(DiversionGreater(sta)),
|
div_queue_(DiversionGreater(sta)),
|
||||||
div_count_(0),
|
div_count_(0),
|
||||||
inserts_pruned_(false),
|
inserts_pruned_(false),
|
||||||
|
|
@ -230,6 +233,7 @@ PathEnum::reportDiversionPath(Diversion *div)
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
typedef std::set<std::pair<const Vertex*, const TimingArc*>> VisitedFanins;
|
typedef std::set<std::pair<const Vertex*, const TimingArc*>> VisitedFanins;
|
||||||
|
typedef std::pair<const Vertex*, const RiseFall*> VertexEdge;
|
||||||
|
|
||||||
class PathEnumFaninVisitor : public PathVisitor
|
class PathEnumFaninVisitor : public PathVisitor
|
||||||
{
|
{
|
||||||
|
|
@ -237,6 +241,7 @@ public:
|
||||||
PathEnumFaninVisitor(PathEnd *path_end,
|
PathEnumFaninVisitor(PathEnd *path_end,
|
||||||
Path *before_div,
|
Path *before_div,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
PathEnum *path_enum);
|
PathEnum *path_enum);
|
||||||
virtual VertexVisitor *copy() const override;
|
virtual VertexVisitor *copy() const override;
|
||||||
void visitFaninPathsThru(Path *before_div,
|
void visitFaninPathsThru(Path *before_div,
|
||||||
|
|
@ -271,6 +276,7 @@ private:
|
||||||
const Pin *to_pin,
|
const Pin *to_pin,
|
||||||
Vertex *to_vertex) override;
|
Vertex *to_vertex) override;
|
||||||
virtual void visit(Vertex *) override {} // Not used.
|
virtual void visit(Vertex *) override {} // Not used.
|
||||||
|
void insertUniqueEdgeDiv(Diversion *div);
|
||||||
void reportDiversion(const Edge *edge,
|
void reportDiversion(const Edge *edge,
|
||||||
const TimingArc *div_arc,
|
const TimingArc *div_arc,
|
||||||
Path *after_div);
|
Path *after_div);
|
||||||
|
|
@ -278,6 +284,7 @@ private:
|
||||||
PathEnd *path_end_;
|
PathEnd *path_end_;
|
||||||
Path *before_div_;
|
Path *before_div_;
|
||||||
bool unique_pins_;
|
bool unique_pins_;
|
||||||
|
bool unique_edges_;
|
||||||
PathEnum *path_enum_;
|
PathEnum *path_enum_;
|
||||||
|
|
||||||
Slack path_end_slack_;
|
Slack path_end_slack_;
|
||||||
|
|
@ -289,16 +296,19 @@ private:
|
||||||
Vertex *prev_vertex_;
|
Vertex *prev_vertex_;
|
||||||
bool crpr_active_;
|
bool crpr_active_;
|
||||||
VisitedFanins visited_fanins_;
|
VisitedFanins visited_fanins_;
|
||||||
|
std::map<VertexEdge, Diversion*> unique_edge_divs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
||||||
Path *before_div,
|
Path *before_div,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
PathEnum *path_enum) :
|
PathEnum *path_enum) :
|
||||||
PathVisitor(path_enum),
|
PathVisitor(path_enum),
|
||||||
path_end_(path_end),
|
path_end_(path_end),
|
||||||
before_div_(before_div),
|
before_div_(before_div),
|
||||||
unique_pins_(unique_pins),
|
unique_pins_(unique_pins),
|
||||||
|
unique_edges_(unique_edges),
|
||||||
path_enum_(path_enum),
|
path_enum_(path_enum),
|
||||||
|
|
||||||
path_end_slack_(path_end->slack(this)),
|
path_end_slack_(path_end->slack(this)),
|
||||||
|
|
@ -310,6 +320,13 @@ PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexVisitor *
|
||||||
|
PathEnumFaninVisitor::copy() const
|
||||||
|
{
|
||||||
|
return new PathEnumFaninVisitor(path_end_, before_div_, unique_pins_,
|
||||||
|
unique_edges_, path_enum_);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div,
|
PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div,
|
||||||
Vertex *prev_vertex,
|
Vertex *prev_vertex,
|
||||||
|
|
@ -324,7 +341,13 @@ PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div,
|
||||||
prev_arc_ = prev_arc;
|
prev_arc_ = prev_arc;
|
||||||
prev_vertex_ = prev_vertex;
|
prev_vertex_ = prev_vertex;
|
||||||
visited_fanins_.clear();
|
visited_fanins_.clear();
|
||||||
|
unique_edge_divs_.clear();
|
||||||
visitFaninPaths(before_div_->vertex(this));
|
visitFaninPaths(before_div_->vertex(this));
|
||||||
|
|
||||||
|
if (unique_edges_) {
|
||||||
|
for (auto [vertex_edge, div] : unique_edge_divs_)
|
||||||
|
path_enum_->insert(div);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialize PathVisitor::visitEdge to filter paths/arcs to
|
// Specialize PathVisitor::visitEdge to filter paths/arcs to
|
||||||
|
|
@ -342,12 +365,14 @@ PathEnumFaninVisitor::visitEdge(const Pin *from_pin,
|
||||||
VertexPathIterator from_iter(from_vertex, search_);
|
VertexPathIterator from_iter(from_vertex, search_);
|
||||||
while (from_iter.hasNext()) {
|
while (from_iter.hasNext()) {
|
||||||
Path *from_path = from_iter.next();
|
Path *from_path = from_iter.next();
|
||||||
|
// Filter paths by path ap.
|
||||||
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(this);
|
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(this);
|
||||||
if (path_ap->index() == before_div_ap_index_) {
|
if (path_ap->index() == before_div_ap_index_) {
|
||||||
const MinMax *min_max = path_ap->pathMinMax();
|
const MinMax *min_max = path_ap->pathMinMax();
|
||||||
const RiseFall *from_rf = from_path->transition(this);
|
const RiseFall *from_rf = from_path->transition(this);
|
||||||
TimingArc *arc1, *arc2;
|
TimingArc *arc1, *arc2;
|
||||||
arc_set->arcsFrom(from_rf, arc1, arc2);
|
arc_set->arcsFrom(from_rf, arc1, arc2);
|
||||||
|
// Filter arcs by to edge.
|
||||||
if (arc1 && arc1->toEdge()->asRiseFall()->index() == before_div_rf_index_) {
|
if (arc1 && arc1->toEdge()->asRiseFall()->index() == before_div_rf_index_) {
|
||||||
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
|
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
|
||||||
edge, arc1, to_pin, to_vertex,
|
edge, arc1, to_pin, to_vertex,
|
||||||
|
|
@ -366,13 +391,6 @@ PathEnumFaninVisitor::visitEdge(const Pin *from_pin,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexVisitor *
|
|
||||||
PathEnumFaninVisitor::copy() const
|
|
||||||
{
|
|
||||||
return new PathEnumFaninVisitor(path_end_, before_div_, unique_pins_,
|
|
||||||
path_enum_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
||||||
Vertex *from_vertex,
|
Vertex *from_vertex,
|
||||||
|
|
@ -393,42 +411,49 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
||||||
// These paths fanin to before_div_ so we know to_vertex matches.
|
// These paths fanin to before_div_ so we know to_vertex matches.
|
||||||
if ((!unique_pins_ || from_vertex != prev_vertex_)
|
if ((!unique_pins_ || from_vertex != prev_vertex_)
|
||||||
&& arc != prev_arc_
|
&& arc != prev_arc_
|
||||||
&& Tag::matchNoCrpr(to_tag, before_div_tag_)) {
|
&& Tag::matchNoCrpr(to_tag, before_div_tag_)
|
||||||
|
// Ignore paths that only differ by crpr from same vertex/edge.
|
||||||
|
&& (!crpr_active_
|
||||||
|
|| visited_fanins_.find({from_vertex, arc}) == visited_fanins_.end())) {
|
||||||
debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
||||||
from_path->to_string(this).c_str(),
|
from_path->to_string(this).c_str(),
|
||||||
to_vertex->to_string(this).c_str(),
|
to_vertex->to_string(this).c_str(),
|
||||||
to_rf->to_string().c_str(),
|
to_rf->to_string().c_str(),
|
||||||
delayAsString(search_->deratedDelay(from_vertex, arc, edge,
|
delayAsString(search_->deratedDelay(from_vertex, arc, edge,
|
||||||
false,path_ap), this));
|
false,path_ap), this));
|
||||||
if (crpr_active_) {
|
|
||||||
// Ingore paths that only differ by crpr from same vertex/edge.
|
|
||||||
if (visited_fanins_.find({from_vertex, arc}) == visited_fanins_.end()) {
|
|
||||||
PathEnd *div_end;
|
PathEnd *div_end;
|
||||||
Path *after_div_copy;
|
Path *after_div_copy;
|
||||||
// Make the diverted path end to check slack with from_path crpr.
|
// Make the diverted path end to check slack with from_path crpr.
|
||||||
makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy);
|
makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy);
|
||||||
if (div_end) {
|
|
||||||
reportDiversion(edge, arc, from_path);
|
reportDiversion(edge, arc, from_path);
|
||||||
path_enum_->makeDiversion(div_end, after_div_copy);
|
Diversion *div = new Diversion(div_end, after_div_copy);
|
||||||
|
if (unique_edges_)
|
||||||
|
insertUniqueEdgeDiv(div);
|
||||||
|
else
|
||||||
|
path_enum_->insert(div);
|
||||||
|
if (crpr_active_)
|
||||||
visited_fanins_.emplace(from_vertex, arc);
|
visited_fanins_.emplace(from_vertex, arc);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
debugPrint(debug_, "path_enum", 3, " pruned %s %s",
|
debugPrint(debug_, "path_enum", 3, " pruned %s %s",
|
||||||
edge->to_string(this).c_str(),
|
edge->to_string(this).c_str(),
|
||||||
arc->to_string().c_str());
|
arc->to_string().c_str());
|
||||||
}
|
|
||||||
else {
|
|
||||||
PathEnd *div_end;
|
|
||||||
Path *after_div_copy;
|
|
||||||
makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy);
|
|
||||||
reportDiversion(edge, arc, from_path);
|
|
||||||
path_enum_->makeDiversion(div_end, after_div_copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PathEnumFaninVisitor::insertUniqueEdgeDiv(Diversion *div)
|
||||||
|
{
|
||||||
|
Slack div_slack = div->pathEnd()->slack(this);
|
||||||
|
const Path *div_path = div->divPath();
|
||||||
|
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()
|
||||||
|
|| div_slack > itr->second->pathEnd()->slack(this))
|
||||||
|
itr->second = div;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div,
|
PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div,
|
||||||
Edge *div_edge,
|
Edge *div_edge,
|
||||||
|
|
@ -440,13 +465,9 @@ PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div,
|
||||||
Path *div_path;
|
Path *div_path;
|
||||||
path_enum_->makeDivertedPath(path_end_->path(), before_div_, after_div,
|
path_enum_->makeDivertedPath(path_end_->path(), before_div_, after_div,
|
||||||
div_edge, div_arc, div_path, after_div_copy);
|
div_edge, div_arc, div_path, after_div_copy);
|
||||||
if (after_div_copy) {
|
|
||||||
div_end = path_end_->copy();
|
div_end = path_end_->copy();
|
||||||
div_end->setPath(div_path);
|
div_end->setPath(div_path);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
div_end = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PathEnumFaninVisitor::reportDiversion(const Edge *div_edge,
|
PathEnumFaninVisitor::reportDiversion(const Edge *div_edge,
|
||||||
|
|
@ -476,21 +497,11 @@ PathEnumFaninVisitor::reportDiversion(const Edge *div_edge,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A diversion is an alternate path formed by changing the previous
|
|
||||||
// path/arc of before_div to after_div/div_arc in path.
|
|
||||||
//
|
|
||||||
// div_arc
|
|
||||||
// after_div<--------+
|
|
||||||
// |
|
|
||||||
// <--...--before_div<--...--path<---path_end
|
|
||||||
void
|
void
|
||||||
PathEnum::makeDiversion(PathEnd *div_end,
|
PathEnum::insert(Diversion *div)
|
||||||
Path *after_div_copy)
|
|
||||||
{
|
{
|
||||||
Diversion *div = new Diversion(div_end, after_div_copy);
|
|
||||||
div_queue_.push(div);
|
div_queue_.push(div);
|
||||||
div_count_++;
|
div_count_++;
|
||||||
|
|
||||||
if (div_queue_.size() > group_path_count_ * 2)
|
if (div_queue_.size() > group_path_count_ * 2)
|
||||||
// We have more potenial paths than we will need.
|
// We have more potenial paths than we will need.
|
||||||
pruneDiversionQueue();
|
pruneDiversionQueue();
|
||||||
|
|
@ -550,7 +561,7 @@ PathEnum::divSlack(Path *before_div,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
report()->error(1370, "path diversion missing edge.");
|
report_->error(1370, "path diversion missing edge.");
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -564,7 +575,8 @@ PathEnum::makeDiversions(PathEnd *path_end,
|
||||||
Path *path = before;
|
Path *path = before;
|
||||||
Path *prev_path = path->prevPath();
|
Path *prev_path = path->prevPath();
|
||||||
TimingArc *prev_arc = path->prevArc(this);
|
TimingArc *prev_arc = path->prevArc(this);
|
||||||
PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, this);
|
PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_,
|
||||||
|
unique_edges_, this);
|
||||||
while (prev_path) {
|
while (prev_path) {
|
||||||
// Fanin visitor does all the work.
|
// Fanin visitor does all the work.
|
||||||
// While visiting the fanins the fanin_visitor finds the
|
// While visiting the fanins the fanin_visitor finds the
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ public:
|
||||||
PathEnum(size_t group_path_count,
|
PathEnum(size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
bool cmp_slack,
|
bool cmp_slack,
|
||||||
const StaState *sta);
|
const StaState *sta);
|
||||||
// Insert path ends that are enumerated in slack/arrival order.
|
// Insert path ends that are enumerated in slack/arrival order.
|
||||||
|
|
@ -72,8 +73,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void makeDiversions(PathEnd *path_end,
|
void makeDiversions(PathEnd *path_end,
|
||||||
Path *before);
|
Path *before);
|
||||||
void makeDiversion(PathEnd *div_end,
|
void insert(Diversion *div);
|
||||||
Path *after_div_copy);
|
|
||||||
void makeDivertedPath(Path *path,
|
void makeDivertedPath(Path *path,
|
||||||
Path *before_div,
|
Path *before_div,
|
||||||
Path *after_div,
|
Path *after_div,
|
||||||
|
|
@ -97,6 +97,7 @@ private:
|
||||||
size_t group_path_count_;
|
size_t group_path_count_;
|
||||||
size_t endpoint_path_count_;
|
size_t endpoint_path_count_;
|
||||||
bool unique_pins_;
|
bool unique_pins_;
|
||||||
|
bool unique_edges_;
|
||||||
DiversionQueue div_queue_;
|
DiversionQueue div_queue_;
|
||||||
int div_count_;
|
int div_count_;
|
||||||
// Number of paths returned for each endpoint (limit to endpoint_path_count).
|
// Number of paths returned for each endpoint (limit to endpoint_path_count).
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,14 @@ PathGroup::makePathGroupSlack(const char *name,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
const StaState *sta)
|
const StaState *sta)
|
||||||
{
|
{
|
||||||
return new PathGroup(name, group_path_count, endpoint_path_count, unique_pins,
|
return new PathGroup(name, group_path_count, endpoint_path_count,
|
||||||
slack_min, slack_max, true, MinMax::min(), sta);
|
unique_pins, unique_edges, slack_min, slack_max,
|
||||||
|
true, MinMax::min(), sta);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathGroup *
|
PathGroup *
|
||||||
|
|
@ -66,17 +68,20 @@ PathGroup::makePathGroupArrival(const char *name,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const StaState *sta)
|
const StaState *sta)
|
||||||
{
|
{
|
||||||
return new PathGroup(name, group_path_count, endpoint_path_count, unique_pins,
|
return new PathGroup(name, group_path_count, endpoint_path_count,
|
||||||
0.0, 0.0, false, min_max, sta);
|
unique_pins, unique_edges, 0.0, 0.0,
|
||||||
|
false, min_max, sta);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathGroup::PathGroup(const char *name,
|
PathGroup::PathGroup(const char *name,
|
||||||
size_t group_path_count,
|
size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool cmp_slack,
|
bool cmp_slack,
|
||||||
|
|
@ -86,6 +91,7 @@ PathGroup::PathGroup(const char *name,
|
||||||
group_path_count_(group_path_count),
|
group_path_count_(group_path_count),
|
||||||
endpoint_path_count_(endpoint_path_count),
|
endpoint_path_count_(endpoint_path_count),
|
||||||
unique_pins_(unique_pins),
|
unique_pins_(unique_pins),
|
||||||
|
unique_edges_(unique_edges),
|
||||||
slack_min_(slack_min),
|
slack_min_(slack_min),
|
||||||
slack_max_(slack_max),
|
slack_max_(slack_max),
|
||||||
min_max_(min_max),
|
min_max_(min_max),
|
||||||
|
|
@ -252,6 +258,7 @@ const char *PathGroups::unconstrained_group_name_ = "unconstrained";
|
||||||
PathGroups::PathGroups(int group_path_count,
|
PathGroups::PathGroups(int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
|
|
@ -267,14 +274,15 @@ PathGroups::PathGroups(int group_path_count,
|
||||||
group_path_count_(group_path_count),
|
group_path_count_(group_path_count),
|
||||||
endpoint_path_count_(endpoint_path_count),
|
endpoint_path_count_(endpoint_path_count),
|
||||||
unique_pins_(unique_pins),
|
unique_pins_(unique_pins),
|
||||||
|
unique_edges_(unique_edges),
|
||||||
slack_min_(slack_min),
|
slack_min_(slack_min),
|
||||||
slack_max_(slack_max)
|
slack_max_(slack_max)
|
||||||
{
|
{
|
||||||
makeGroups(group_path_count, endpoint_path_count, unique_pins,
|
makeGroups(group_path_count, endpoint_path_count, unique_pins, unique_edges,
|
||||||
slack_min, slack_max, group_names,
|
slack_min, slack_max, group_names,
|
||||||
setup, recovery, clk_gating_setup, unconstrained,
|
setup, recovery, clk_gating_setup, unconstrained,
|
||||||
MinMax::max());
|
MinMax::max());
|
||||||
makeGroups(group_path_count, endpoint_path_count, unique_pins,
|
makeGroups(group_path_count, endpoint_path_count, unique_pins, unique_edges,
|
||||||
slack_min, slack_max, group_names,
|
slack_min, slack_max, group_names,
|
||||||
hold, removal, clk_gating_hold, unconstrained,
|
hold, removal, clk_gating_hold, unconstrained,
|
||||||
MinMax::min());
|
MinMax::min());
|
||||||
|
|
@ -284,6 +292,7 @@ void
|
||||||
PathGroups::makeGroups(int group_path_count,
|
PathGroups::makeGroups(int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
|
|
@ -301,6 +310,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
group_path_count,
|
group_path_count,
|
||||||
endpoint_path_count,
|
endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins,
|
||||||
|
unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
this);
|
this);
|
||||||
named_map_[mm_index][name] = group;
|
named_map_[mm_index][name] = group;
|
||||||
|
|
@ -314,6 +324,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
group_path_count,
|
group_path_count,
|
||||||
endpoint_path_count,
|
endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins,
|
||||||
|
unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
this);
|
this);
|
||||||
clk_map_[mm_index][clk] = group;
|
clk_map_[mm_index][clk] = group;
|
||||||
|
|
@ -327,6 +338,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
group_path_count,
|
group_path_count,
|
||||||
endpoint_path_count,
|
endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins,
|
||||||
|
unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
this);
|
this);
|
||||||
else
|
else
|
||||||
|
|
@ -338,6 +350,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
group_path_count,
|
group_path_count,
|
||||||
endpoint_path_count,
|
endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins,
|
||||||
|
unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
this);
|
this);
|
||||||
else
|
else
|
||||||
|
|
@ -349,6 +362,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
group_path_count,
|
group_path_count,
|
||||||
endpoint_path_count,
|
endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins,
|
||||||
|
unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
this);
|
this);
|
||||||
else
|
else
|
||||||
|
|
@ -359,7 +373,7 @@ PathGroups::makeGroups(int group_path_count,
|
||||||
unconstrained_[mm_index] =
|
unconstrained_[mm_index] =
|
||||||
PathGroup::makePathGroupArrival(unconstrained_group_name_,
|
PathGroup::makePathGroupArrival(unconstrained_group_name_,
|
||||||
group_path_count, endpoint_path_count,
|
group_path_count, endpoint_path_count,
|
||||||
unique_pins, min_max, this);
|
unique_pins, unique_edges, min_max, this);
|
||||||
else
|
else
|
||||||
unconstrained_[mm_index] = nullptr;
|
unconstrained_[mm_index] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -576,8 +590,8 @@ PathGroups::makePathEnds(ExceptionTo *to,
|
||||||
bool sort_by_slack)
|
bool sort_by_slack)
|
||||||
{
|
{
|
||||||
Stats stats(debug_, report_);
|
Stats stats(debug_, report_);
|
||||||
makeGroupPathEnds(to, group_path_count_, endpoint_path_count_, unique_pins_,
|
makeGroupPathEnds(to, group_path_count_, endpoint_path_count_,
|
||||||
corner, min_max);
|
unique_pins_, unique_edges_, corner, min_max);
|
||||||
|
|
||||||
PathEndSeq path_ends;
|
PathEndSeq path_ends;
|
||||||
pushGroupPathEnds(path_ends);
|
pushGroupPathEnds(path_ends);
|
||||||
|
|
@ -805,6 +819,7 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max)
|
const MinMaxAll *min_max)
|
||||||
{
|
{
|
||||||
|
|
@ -822,27 +837,33 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
|
||||||
const char *name = name_group.first;
|
const char *name = name_group.first;
|
||||||
PathGroup *group = findPathGroup(name, path_min_max);
|
PathGroup *group = findPathGroup(name, path_min_max);
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto clk : sdc_->clks()) {
|
for (auto clk : sdc_->clks()) {
|
||||||
PathGroup *group = findPathGroup(clk, path_min_max);
|
PathGroup *group = findPathGroup(clk, path_min_max);
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathGroup *group = unconstrained_[mm_index];
|
PathGroup *group = unconstrained_[mm_index];
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, false);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, false);
|
||||||
group = path_delay_[mm_index];
|
group = path_delay_[mm_index];
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, true);
|
||||||
group = gated_clk_[mm_index];
|
group = gated_clk_[mm_index];
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, true);
|
||||||
group = async_[mm_index];
|
group = async_[mm_index];
|
||||||
if (group)
|
if (group)
|
||||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
enumPathEnds(group, group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -852,12 +873,13 @@ PathGroups::enumPathEnds(PathGroup *group,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
bool cmp_slack)
|
bool cmp_slack)
|
||||||
{
|
{
|
||||||
// Insert the worst max_path path ends in the group into a path
|
// Insert the worst max_path path ends in the group into a path
|
||||||
// enumerator.
|
// enumerator.
|
||||||
PathEnum path_enum(group_path_count, endpoint_path_count,
|
PathEnum path_enum(group_path_count, endpoint_path_count,
|
||||||
unique_pins, cmp_slack, this);
|
unique_pins, unique_edges, cmp_slack, this);
|
||||||
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();
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,7 @@ Search::findPathEnds(ExceptionFrom *from,
|
||||||
size_t group_path_count,
|
size_t group_path_count,
|
||||||
size_t endpoint_path_count,
|
size_t endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
|
|
@ -466,11 +467,15 @@ Search::findPathEnds(ExceptionFrom *from,
|
||||||
recovery = removal = false;
|
recovery = removal = false;
|
||||||
if (!variables_->gatedClkChecksEnabled())
|
if (!variables_->gatedClkChecksEnabled())
|
||||||
clk_gating_setup = clk_gating_hold = false;
|
clk_gating_setup = clk_gating_hold = false;
|
||||||
makePathGroups(group_path_count, endpoint_path_count, unique_pins,
|
path_groups_ = new PathGroups(group_path_count, endpoint_path_count,
|
||||||
|
unique_pins, unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
group_names, setup, hold,
|
group_names,
|
||||||
|
setup, hold,
|
||||||
recovery, removal,
|
recovery, removal,
|
||||||
clk_gating_setup, clk_gating_hold);
|
clk_gating_setup, clk_gating_hold,
|
||||||
|
unconstrained_paths_,
|
||||||
|
this);
|
||||||
ensureDownstreamClkPins();
|
ensureDownstreamClkPins();
|
||||||
PathEndSeq path_ends = path_groups_->makePathEnds(to, unconstrained_paths_,
|
PathEndSeq path_ends = path_groups_->makePathEnds(to, unconstrained_paths_,
|
||||||
corner, min_max,
|
corner, min_max,
|
||||||
|
|
@ -4126,31 +4131,6 @@ Search::wnsSlack(Vertex *vertex,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
|
||||||
Search::makePathGroups(int group_path_count,
|
|
||||||
int endpoint_path_count,
|
|
||||||
bool unique_pins,
|
|
||||||
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,
|
|
||||||
slack_min, slack_max,
|
|
||||||
group_names,
|
|
||||||
setup, hold,
|
|
||||||
recovery, removal,
|
|
||||||
clk_gating_setup, clk_gating_hold,
|
|
||||||
unconstrained_paths_,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Search::deletePathGroups()
|
Search::deletePathGroups()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -372,6 +372,7 @@ find_path_ends(ExceptionFrom *from,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
|
|
@ -387,7 +388,7 @@ find_path_ends(ExceptionFrom *from,
|
||||||
PathEndSeq ends = sta->findPathEnds(from, thrus, to, unconstrained,
|
PathEndSeq ends = sta->findPathEnds(from, thrus, to, unconstrained,
|
||||||
corner, delay_min_max,
|
corner, delay_min_max,
|
||||||
group_path_count, endpoint_path_count,
|
group_path_count, endpoint_path_count,
|
||||||
unique_pins,
|
unique_pins, unique_edges,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
sort_by_slack,
|
sort_by_slack,
|
||||||
groups->size() ? groups : nullptr,
|
groups->size() ? groups : nullptr,
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ define_cmd_args "find_timing_paths" \
|
||||||
[-group_path_count path_count] \
|
[-group_path_count path_count] \
|
||||||
[-endpoint_path_count path_count]\
|
[-endpoint_path_count path_count]\
|
||||||
[-unique_paths_to_endpoint]\
|
[-unique_paths_to_endpoint]\
|
||||||
|
[-unique_edges_to_endpoint]\
|
||||||
[-slack_max slack_max]\
|
[-slack_max slack_max]\
|
||||||
[-slack_min slack_min]\
|
[-slack_min slack_min]\
|
||||||
[-sort_by_slack]\
|
[-sort_by_slack]\
|
||||||
|
|
@ -121,7 +122,9 @@ proc find_timing_paths_cmd { cmd args_var } {
|
||||||
-path_delay -corner -group_count -endpoint_count \
|
-path_delay -corner -group_count -endpoint_count \
|
||||||
-group_path_count -endpoint_path_count \
|
-group_path_count -endpoint_path_count \
|
||||||
-slack_max -slack_min -path_group} \
|
-slack_max -slack_min -path_group} \
|
||||||
flags {-unconstrained -sort_by_slack -unique_paths_to_endpoint} 0
|
flags {-unconstrained -sort_by_slack \
|
||||||
|
-unique_paths_to_endpoint \
|
||||||
|
-unique_edges_to_endpoint} 0
|
||||||
|
|
||||||
set min_max "max"
|
set min_max "max"
|
||||||
set end_rf "rise_fall"
|
set end_rf "rise_fall"
|
||||||
|
|
@ -195,6 +198,7 @@ proc find_timing_paths_cmd { cmd args_var } {
|
||||||
}
|
}
|
||||||
|
|
||||||
set unique_pins [info exists flags(-unique_paths_to_endpoint)]
|
set unique_pins [info exists flags(-unique_paths_to_endpoint)]
|
||||||
|
set unique_edges [info exists flags(-unique_edges_to_endpoint)]
|
||||||
|
|
||||||
set slack_min "-1e+30"
|
set slack_min "-1e+30"
|
||||||
if [info exist keys(-slack_min)] {
|
if [info exist keys(-slack_min)] {
|
||||||
|
|
@ -229,7 +233,8 @@ proc find_timing_paths_cmd { cmd args_var } {
|
||||||
|
|
||||||
set path_ends [find_path_ends $from $thrus $to $unconstrained \
|
set path_ends [find_path_ends $from $thrus $to $unconstrained \
|
||||||
$corner $min_max \
|
$corner $min_max \
|
||||||
$group_path_count $endpoint_path_count $unique_pins \
|
$group_path_count $endpoint_path_count \
|
||||||
|
$unique_pins $unique_edges \
|
||||||
$slack_min $slack_max \
|
$slack_min $slack_max \
|
||||||
$sort_by_slack $groups \
|
$sort_by_slack $groups \
|
||||||
1 1 1 1 1 1]
|
1 1 1 1 1 1]
|
||||||
|
|
@ -574,7 +579,7 @@ proc_redirect report_check_types {
|
||||||
set slack_max $sta::float_inf
|
set slack_max $sta::float_inf
|
||||||
}
|
}
|
||||||
set path_ends [find_path_ends "NULL" {} "NULL" 0 \
|
set path_ends [find_path_ends "NULL" {} "NULL" 0 \
|
||||||
$corner $path_min_max $group_path_count 1 0 \
|
$corner $path_min_max $group_path_count 1 1 0 \
|
||||||
$slack_min $slack_max \
|
$slack_min $slack_max \
|
||||||
0 {} \
|
0 {} \
|
||||||
$setup $hold \
|
$setup $hold \
|
||||||
|
|
|
||||||
|
|
@ -2464,6 +2464,7 @@ Sta::findPathEnds(ExceptionFrom *from,
|
||||||
int group_path_count,
|
int group_path_count,
|
||||||
int endpoint_path_count,
|
int endpoint_path_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
|
bool unique_edges,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
|
|
@ -2477,8 +2478,10 @@ Sta::findPathEnds(ExceptionFrom *from,
|
||||||
{
|
{
|
||||||
searchPreamble();
|
searchPreamble();
|
||||||
return search_->findPathEnds(from, thrus, to, unconstrained,
|
return search_->findPathEnds(from, thrus, to, unconstrained,
|
||||||
corner, min_max, group_path_count, endpoint_path_count,
|
corner, min_max, group_path_count,
|
||||||
unique_pins, slack_min, slack_max,
|
endpoint_path_count,
|
||||||
|
unique_pins, unique_edges,
|
||||||
|
slack_min, slack_max,
|
||||||
sort_by_slack, group_names,
|
sort_by_slack, group_names,
|
||||||
setup, hold,
|
setup, hold,
|
||||||
recovery, removal,
|
recovery, removal,
|
||||||
|
|
@ -2727,8 +2730,10 @@ Sta::findGroupPathPins(const char *group_path_name)
|
||||||
nullptr, nullptr, nullptr, false,
|
nullptr, nullptr, nullptr, false,
|
||||||
// corner, min_max,
|
// corner, min_max,
|
||||||
nullptr, MinMaxAll::max(),
|
nullptr, MinMaxAll::max(),
|
||||||
// group_path_count, endpoint_path_count, unique_pins
|
// group_path_count, endpoint_path_count
|
||||||
1, 1, false,
|
1, 1,
|
||||||
|
// unique_pins, unique_edges
|
||||||
|
true, true,
|
||||||
-INF, INF, // slack_min, slack_max,
|
-INF, INF, // slack_min, slack_max,
|
||||||
false, // sort_by_slack
|
false, // sort_by_slack
|
||||||
nullptr, // group_names
|
nullptr, // group_names
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue