Sta::findPathEnds return seq
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
4b009e50dc
commit
865970e78c
|
|
@ -58,7 +58,7 @@ public:
|
||||||
const PathEndSeq &pathEnds() const { return path_ends_; }
|
const PathEndSeq &pathEnds() const { return path_ends_; }
|
||||||
void insert(PathEnd *path_end);
|
void insert(PathEnd *path_end);
|
||||||
// Push group_count into path_ends.
|
// Push group_count into path_ends.
|
||||||
void pushEnds(PathEndSeq *path_ends);
|
void pushEnds(PathEndSeq &path_ends);
|
||||||
// Predicates to determine if a PathEnd is worth saving.
|
// Predicates to determine if a PathEnd is worth saving.
|
||||||
virtual bool savable(PathEnd *path_end);
|
virtual bool savable(PathEnd *path_end);
|
||||||
int maxPaths() const { return group_count_; }
|
int maxPaths() const { return group_count_; }
|
||||||
|
|
@ -114,13 +114,12 @@ public:
|
||||||
const StaState *sta);
|
const StaState *sta);
|
||||||
~PathGroups();
|
~PathGroups();
|
||||||
// Use corner nullptr to make PathEnds for all corners.
|
// Use corner nullptr to make PathEnds for all corners.
|
||||||
// Returned PathEndSeq is owned by the caller.
|
|
||||||
// The PathEnds in the vector are owned by the PathGroups.
|
// The PathEnds in the vector are owned by the PathGroups.
|
||||||
PathEndSeq *makePathEnds(ExceptionTo *to,
|
PathEndSeq makePathEnds(ExceptionTo *to,
|
||||||
bool unconstrained_paths,
|
bool unconstrained_paths,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
bool sort_by_slack);
|
bool sort_by_slack);
|
||||||
PathGroup *findPathGroup(const char *name,
|
PathGroup *findPathGroup(const char *name,
|
||||||
const MinMax *min_max) const;
|
const MinMax *min_max) const;
|
||||||
PathGroup *findPathGroup(const Clock *clock,
|
PathGroup *findPathGroup(const Clock *clock,
|
||||||
|
|
@ -150,8 +149,8 @@ protected:
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
bool cmp_slack);
|
bool cmp_slack);
|
||||||
|
|
||||||
void pushGroupPathEnds(PathEndSeq *path_ends);
|
void pushGroupPathEnds(PathEndSeq &path_ends);
|
||||||
void pushUnconstrainedPathEnds(PathEndSeq *path_ends,
|
void pushUnconstrainedPathEnds(PathEndSeq &path_ends,
|
||||||
const MinMaxAll *min_max);
|
const MinMaxAll *min_max);
|
||||||
|
|
||||||
void makeGroups(int group_count,
|
void makeGroups(int group_count,
|
||||||
|
|
|
||||||
|
|
@ -82,27 +82,26 @@ public:
|
||||||
bool unconstrainedPaths() const { return unconstrained_paths_; }
|
bool unconstrainedPaths() const { return unconstrained_paths_; }
|
||||||
// from/thrus/to are owned and deleted by Search.
|
// from/thrus/to are owned and deleted by Search.
|
||||||
// Use corner nullptr to report timing for all corners.
|
// Use corner nullptr to report timing for all corners.
|
||||||
// Returned sequence is owned by the caller.
|
|
||||||
// PathEnds are owned by Search PathGroups and deleted on next call.
|
// PathEnds are owned by Search PathGroups and deleted on next call.
|
||||||
PathEndSeq *findPathEnds(ExceptionFrom *from,
|
PathEndSeq findPathEnds(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
bool unconstrained,
|
bool unconstrained,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
int group_count,
|
int group_count,
|
||||||
int endpoint_count,
|
int endpoint_count,
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
bool setup,
|
bool setup,
|
||||||
bool hold,
|
bool hold,
|
||||||
bool recovery,
|
bool recovery,
|
||||||
bool removal,
|
bool removal,
|
||||||
bool clk_gating_setup,
|
bool clk_gating_setup,
|
||||||
bool clk_gating_hold);
|
bool clk_gating_hold);
|
||||||
bool arrivalsValid();
|
bool arrivalsValid();
|
||||||
// Invalidate all arrival and required times.
|
// Invalidate all arrival and required times.
|
||||||
void arrivalsInvalid();
|
void arrivalsInvalid();
|
||||||
|
|
|
||||||
|
|
@ -841,45 +841,45 @@ public:
|
||||||
bool generated_clks);
|
bool generated_clks);
|
||||||
// Path from/thrus/to filter.
|
// Path from/thrus/to filter.
|
||||||
// from/thrus/to are owned and deleted by Search.
|
// from/thrus/to are owned and deleted by Search.
|
||||||
// Returned sequence is owned by the caller.
|
// PathEnds in the returned PathEndSeq are owned by Search PathGroups
|
||||||
// PathEnds are owned by Search PathGroups and deleted on next call.
|
// and deleted on next call.
|
||||||
virtual PathEndSeq *findPathEnds(ExceptionFrom *from,
|
virtual PathEndSeq findPathEnds(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
bool unconstrained,
|
bool unconstrained,
|
||||||
// Use corner nullptr to report timing
|
// Use corner nullptr to report timing
|
||||||
// for all corners.
|
// for all corners.
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
// max for setup checks.
|
// max for setup checks.
|
||||||
// min for hold checks.
|
// min for hold checks.
|
||||||
// min_max for setup and hold checks.
|
// min_max for setup and hold checks.
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
// Number of path ends to report in
|
// Number of path ends to report in
|
||||||
// each group.
|
// each group.
|
||||||
int group_count,
|
int group_count,
|
||||||
// Number of paths to report for
|
// Number of paths to report for
|
||||||
// each endpoint.
|
// each endpoint.
|
||||||
int endpoint_count,
|
int endpoint_count,
|
||||||
// endpoint_count paths report unique pins
|
// endpoint_count paths report unique pins
|
||||||
// without rise/fall variations.
|
// without rise/fall variations.
|
||||||
bool unique_pins,
|
bool unique_pins,
|
||||||
// Min/max bounds for slack of
|
// Min/max bounds for slack of
|
||||||
// returned path ends.
|
// returned path ends.
|
||||||
float slack_min,
|
float slack_min,
|
||||||
float slack_max,
|
float slack_max,
|
||||||
// Sort path ends by slack ignoring path groups.
|
// Sort path ends by slack ignoring path groups.
|
||||||
bool sort_by_slack,
|
bool sort_by_slack,
|
||||||
// Path groups to report.
|
// Path groups to report.
|
||||||
// Null or empty list reports all groups.
|
// Null or empty list reports all groups.
|
||||||
PathGroupNameSet *group_names,
|
PathGroupNameSet *group_names,
|
||||||
// Predicates to filter the type of path
|
// Predicates to filter the type of path
|
||||||
// ends returned.
|
// ends returned.
|
||||||
bool setup,
|
bool setup,
|
||||||
bool hold,
|
bool hold,
|
||||||
bool recovery,
|
bool recovery,
|
||||||
bool removal,
|
bool removal,
|
||||||
bool clk_gating_setup,
|
bool clk_gating_setup,
|
||||||
bool clk_gating_hold);
|
bool clk_gating_hold);
|
||||||
void setReportPathFormat(ReportPathFormat format);
|
void setReportPathFormat(ReportPathFormat format);
|
||||||
void setReportPathFieldOrder(StringSeq *field_names);
|
void setReportPathFieldOrder(StringSeq *field_names);
|
||||||
void setReportPathFields(bool report_input_pin,
|
void setReportPathFields(bool report_input_pin,
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,11 @@ PathGroup::prune()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathGroup::pushEnds(PathEndSeq *path_ends)
|
PathGroup::pushEnds(PathEndSeq &path_ends)
|
||||||
{
|
{
|
||||||
ensureSortedMaxPaths();
|
ensureSortedMaxPaths();
|
||||||
for (PathEnd *path_end : path_ends_)
|
for (PathEnd *path_end : path_ends_)
|
||||||
path_ends->push_back(path_end);
|
path_ends.push_back(path_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathGroupIterator *
|
PathGroupIterator *
|
||||||
|
|
@ -415,7 +415,7 @@ PathGroups::groupPathTo(const PathEnd *path_end) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathGroups::pushGroupPathEnds(PathEndSeq *path_ends)
|
PathGroups::pushGroupPathEnds(PathEndSeq &path_ends)
|
||||||
{
|
{
|
||||||
for (auto min_max : MinMax::range()) {
|
for (auto min_max : MinMax::range()) {
|
||||||
int mm_index = min_max->index();
|
int mm_index = min_max->index();
|
||||||
|
|
@ -448,7 +448,7 @@ PathGroups::pushGroupPathEnds(PathEndSeq *path_ends)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathGroups::pushUnconstrainedPathEnds(PathEndSeq *path_ends,
|
PathGroups::pushUnconstrainedPathEnds(PathEndSeq &path_ends,
|
||||||
const MinMaxAll *min_max)
|
const MinMaxAll *min_max)
|
||||||
{
|
{
|
||||||
Set<PathGroup *> groups;
|
Set<PathGroup *> groups;
|
||||||
|
|
@ -477,7 +477,7 @@ typedef Set<PathEnd*, PathEndNoCrprLess> PathEndNoCrprSet;
|
||||||
static bool
|
static bool
|
||||||
exceptionToEmpty(ExceptionTo *to);
|
exceptionToEmpty(ExceptionTo *to);
|
||||||
|
|
||||||
PathEndSeq *
|
PathEndSeq
|
||||||
PathGroups::makePathEnds(ExceptionTo *to,
|
PathGroups::makePathEnds(ExceptionTo *to,
|
||||||
bool unconstrained_paths,
|
bool unconstrained_paths,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
|
|
@ -488,16 +488,16 @@ PathGroups::makePathEnds(ExceptionTo *to,
|
||||||
makeGroupPathEnds(to, group_count_, endpoint_count_, unique_pins_,
|
makeGroupPathEnds(to, group_count_, endpoint_count_, unique_pins_,
|
||||||
corner, min_max);
|
corner, min_max);
|
||||||
|
|
||||||
PathEndSeq *path_ends = new PathEndSeq;
|
PathEndSeq path_ends;
|
||||||
pushGroupPathEnds(path_ends);
|
pushGroupPathEnds(path_ends);
|
||||||
if (sort_by_slack) {
|
if (sort_by_slack) {
|
||||||
sort(path_ends, PathEndLess(this));
|
sort(path_ends, PathEndLess(this));
|
||||||
if (static_cast<int>(path_ends->size()) > group_count_)
|
if (static_cast<int>(path_ends.size()) > group_count_)
|
||||||
path_ends->resize(group_count_);
|
path_ends.resize(group_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unconstrained_paths
|
if (unconstrained_paths
|
||||||
&& path_ends->empty())
|
&& path_ends.empty())
|
||||||
// No constrained paths, so report unconstrained paths.
|
// No constrained paths, so report unconstrained paths.
|
||||||
pushUnconstrainedPathEnds(path_ends, min_max);
|
pushUnconstrainedPathEnds(path_ends, min_max);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ Search::deletePaths(Vertex *vertex)
|
||||||
// from/thrus/to are owned and deleted by Search.
|
// from/thrus/to are owned and deleted by Search.
|
||||||
// Returned sequence is owned by the caller.
|
// Returned sequence is owned by the caller.
|
||||||
// PathEnds are owned by Search PathGroups and deleted on next call.
|
// PathEnds are owned by Search PathGroups and deleted on next call.
|
||||||
PathEndSeq *
|
PathEndSeq
|
||||||
Search::findPathEnds(ExceptionFrom *from,
|
Search::findPathEnds(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
|
|
@ -455,9 +455,9 @@ Search::findPathEnds(ExceptionFrom *from,
|
||||||
recovery, removal,
|
recovery, removal,
|
||||||
clk_gating_setup, clk_gating_hold);
|
clk_gating_setup, clk_gating_hold);
|
||||||
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,
|
||||||
sort_by_slack);
|
sort_by_slack);
|
||||||
sdc_->reportClkToClkMaxCycleWarnings();
|
sdc_->reportClkToClkMaxCycleWarnings();
|
||||||
return path_ends;
|
return path_ends;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2437,7 +2437,7 @@ Sta::setCmdCorner(Corner *corner)
|
||||||
// from/thrus/to are owned and deleted by Search.
|
// from/thrus/to are owned and deleted by Search.
|
||||||
// Returned sequence is owned by the caller.
|
// Returned sequence is owned by the caller.
|
||||||
// PathEnds are owned by Search PathGroups and deleted on next call.
|
// PathEnds are owned by Search PathGroups and deleted on next call.
|
||||||
PathEndSeq *
|
PathEndSeq
|
||||||
Sta::findPathEnds(ExceptionFrom *from,
|
Sta::findPathEnds(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
|
|
@ -2667,21 +2667,19 @@ Sta::findGroupPathPins(const char *group_path_name)
|
||||||
{
|
{
|
||||||
if (!(search_->havePathGroups()
|
if (!(search_->havePathGroups()
|
||||||
&& search_->arrivalsValid())) {
|
&& search_->arrivalsValid())) {
|
||||||
PathEndSeq *path_ends = findPathEnds(// from, thrus, to, unconstrained
|
PathEndSeq path_ends = findPathEnds(// from, thrus, to, unconstrained
|
||||||
nullptr, nullptr, nullptr, false,
|
nullptr, nullptr, nullptr, false,
|
||||||
// corner, min_max,
|
// corner, min_max,
|
||||||
nullptr, MinMaxAll::max(),
|
nullptr, MinMaxAll::max(),
|
||||||
// group_count, endpoint_count, unique_pins
|
// group_count, endpoint_count, unique_pins
|
||||||
1, 1, false,
|
1, 1, false,
|
||||||
-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
|
||||||
// setup, hold, recovery, removal,
|
// setup, hold, recovery, removal,
|
||||||
true, true, true, true,
|
true, true, true, true,
|
||||||
// clk_gating_setup, clk_gating_hold
|
// clk_gating_setup, clk_gating_hold
|
||||||
true, true);
|
true, true);
|
||||||
// No use for the path end sequence.
|
|
||||||
delete path_ends;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PathGroup *path_group = search_->findPathGroup(group_path_name,
|
PathGroup *path_group = search_->findPathGroup(group_path_name,
|
||||||
|
|
|
||||||
24
tcl/StaTcl.i
24
tcl/StaTcl.i
|
|
@ -1155,6 +1155,10 @@ using namespace sta;
|
||||||
Tcl_SetObjResult(interp, list);
|
Tcl_SetObjResult(interp, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%typemap(out) PathEndSeq {
|
||||||
|
seqTclList<PathEndSeq, PathEnd>($1, SWIGTYPE_p_PathEnd, interp);
|
||||||
|
}
|
||||||
|
|
||||||
%typemap(out) MinPulseWidthCheckSeqIterator* {
|
%typemap(out) MinPulseWidthCheckSeqIterator* {
|
||||||
Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
|
Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
|
||||||
Tcl_SetObjResult(interp, obj);
|
Tcl_SetObjResult(interp, obj);
|
||||||
|
|
@ -4153,7 +4157,7 @@ set_propagate_all_clocks(bool prop)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PathEndSeq *
|
PathEndSeq
|
||||||
find_path_ends(ExceptionFrom *from,
|
find_path_ends(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
|
|
@ -4176,15 +4180,15 @@ find_path_ends(ExceptionFrom *from,
|
||||||
{
|
{
|
||||||
cmdLinkedNetwork();
|
cmdLinkedNetwork();
|
||||||
Sta *sta = Sta::sta();
|
Sta *sta = Sta::sta();
|
||||||
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_count, endpoint_count, unique_pins,
|
group_count, endpoint_count, unique_pins,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
sort_by_slack,
|
sort_by_slack,
|
||||||
groups->size() ? groups : nullptr,
|
groups->size() ? groups : nullptr,
|
||||||
setup, hold,
|
setup, hold,
|
||||||
recovery, removal,
|
recovery, removal,
|
||||||
clk_gating_setup, clk_gating_hold);
|
clk_gating_setup, clk_gating_hold);
|
||||||
delete groups;
|
delete groups;
|
||||||
return ends;
|
return ends;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue