PathVisitor is-a StaState instead of haa-a
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
c43cd616db
commit
0448425fae
|
|
@ -637,7 +637,7 @@ public:
|
||||||
|
|
||||||
// Class for visiting fanin/fanout paths of a vertex.
|
// Class for visiting fanin/fanout paths of a vertex.
|
||||||
// This used by forward/backward search to find arrival/required path times.
|
// This used by forward/backward search to find arrival/required path times.
|
||||||
class PathVisitor : public VertexVisitor
|
class PathVisitor : public VertexVisitor, public StaState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Uses search->evalPred() for search predicate.
|
// Uses search->evalPred() for search predicate.
|
||||||
|
|
@ -691,7 +691,6 @@ protected:
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const PathAnalysisPt *path_ap) = 0;
|
const PathAnalysisPt *path_ap) = 0;
|
||||||
SearchPred *pred_;
|
SearchPred *pred_;
|
||||||
const StaState *sta_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Visitor called during forward search to record an
|
// Visitor called during forward search to record an
|
||||||
|
|
|
||||||
|
|
@ -856,26 +856,22 @@ VertexVisitor *
|
||||||
GenclkSrcArrivalVisitor::copy() const
|
GenclkSrcArrivalVisitor::copy() const
|
||||||
{
|
{
|
||||||
return new GenclkSrcArrivalVisitor(gclk_, insert_iter_, genclk_info_,
|
return new GenclkSrcArrivalVisitor(gclk_, insert_iter_, genclk_info_,
|
||||||
always_to_endpoints_, pred_, sta_);
|
always_to_endpoints_, pred_, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GenclkSrcArrivalVisitor::visit(Vertex *vertex)
|
GenclkSrcArrivalVisitor::visit(Vertex *vertex)
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
Genclks *genclks = search_->genclks();
|
||||||
const Network *sdc_network = sta_->sdcNetwork();
|
debugPrint(debug_, "genclk", 2, "find gen clk insert arrival %s",
|
||||||
const Graph *graph = sta_->graph();
|
vertex->name(sdc_network_));
|
||||||
Search *search = sta_->search();
|
|
||||||
Genclks *genclks = search->genclks();
|
|
||||||
debugPrint(debug, "genclk", 2, "find gen clk insert arrival %s",
|
|
||||||
vertex->name(sdc_network));
|
|
||||||
tag_bldr_->init(vertex);
|
tag_bldr_->init(vertex);
|
||||||
has_fanin_one_ = graph->hasFaninOne(vertex);
|
has_fanin_one_ = graph_->hasFaninOne(vertex);
|
||||||
genclks->copyGenClkSrcPaths(vertex, tag_bldr_);
|
genclks->copyGenClkSrcPaths(vertex, tag_bldr_);
|
||||||
visitFaninPaths(vertex);
|
visitFaninPaths(vertex);
|
||||||
// Propagate beyond the clock tree to reach generated clk roots.
|
// Propagate beyond the clock tree to reach generated clk roots.
|
||||||
insert_iter_->enqueueAdjacentVertices(vertex, &srch_pred_);
|
insert_iter_->enqueueAdjacentVertices(vertex, &srch_pred_);
|
||||||
search->setVertexArrivals(vertex, tag_bldr_);
|
search_->setVertexArrivals(vertex, tag_bldr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1191,19 +1187,15 @@ PllArrivalVisitor::PllArrivalVisitor(const StaState *sta,
|
||||||
void
|
void
|
||||||
PllArrivalVisitor::visit(Vertex *vertex)
|
PllArrivalVisitor::visit(Vertex *vertex)
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
Genclks *genclks = search_->genclks();
|
||||||
const Network *sdc_network = sta_->network();
|
debugPrint(debug_, "genclk", 2, "find gen clk pll arrival %s",
|
||||||
Graph *graph = sta_->graph();
|
vertex->name(sdc_network_));
|
||||||
Search *search = sta_->search();
|
|
||||||
Genclks *genclks = search->genclks();
|
|
||||||
debugPrint(debug, "genclk", 2, "find gen clk pll arrival %s",
|
|
||||||
vertex->name(sdc_network));
|
|
||||||
tag_bldr_->init(vertex);
|
tag_bldr_->init(vertex);
|
||||||
genclks->copyGenClkSrcPaths(vertex, tag_bldr_);
|
genclks->copyGenClkSrcPaths(vertex, tag_bldr_);
|
||||||
has_fanin_one_ = graph->hasFaninOne(vertex);
|
has_fanin_one_ = graph_->hasFaninOne(vertex);
|
||||||
visitFaninPaths(vertex);
|
visitFaninPaths(vertex);
|
||||||
pll_iter_.enqueueAdjacentVertices(vertex);
|
pll_iter_.enqueueAdjacentVertices(vertex);
|
||||||
search->setVertexArrivals(vertex, tag_bldr_);
|
search_->setVertexArrivals(vertex, tag_bldr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -276,15 +276,15 @@ PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end,
|
||||||
PathEnum *path_enum) :
|
PathEnum *path_enum) :
|
||||||
PathVisitor(path_enum),
|
PathVisitor(path_enum),
|
||||||
path_end_(path_end),
|
path_end_(path_end),
|
||||||
path_end_slack_(path_end->slack(sta_)),
|
path_end_slack_(path_end->slack(this)),
|
||||||
before_div_(before_div),
|
before_div_(before_div),
|
||||||
unique_pins_(unique_pins),
|
unique_pins_(unique_pins),
|
||||||
before_div_rf_index_(before_div_.rfIndex(sta_)),
|
before_div_rf_index_(before_div_.rfIndex(this)),
|
||||||
before_div_tag_(before_div_.tag(sta_)),
|
before_div_tag_(before_div_.tag(this)),
|
||||||
before_div_ap_index_(before_div_.pathAnalysisPtIndex(sta_)),
|
before_div_ap_index_(before_div_.pathAnalysisPtIndex(this)),
|
||||||
before_div_arrival_(before_div_.arrival(sta_)),
|
before_div_arrival_(before_div_.arrival(this)),
|
||||||
path_enum_(path_enum),
|
path_enum_(path_enum),
|
||||||
crpr_active_(sta_->sdc()->crprActive())
|
crpr_active_(sdc_->crprActive())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,10 +293,10 @@ PathEnumFaninVisitor::visitFaninPathsThru(Vertex *vertex,
|
||||||
Vertex *prev_vertex,
|
Vertex *prev_vertex,
|
||||||
TimingArc *prev_arc)
|
TimingArc *prev_arc)
|
||||||
{
|
{
|
||||||
before_div_rf_index_ = before_div_.rfIndex(sta_);
|
before_div_rf_index_ = before_div_.rfIndex(this);
|
||||||
before_div_tag_ = before_div_.tag(sta_);
|
before_div_tag_ = before_div_.tag(this);
|
||||||
before_div_ap_index_ = before_div_.pathAnalysisPtIndex(sta_);
|
before_div_ap_index_ = before_div_.pathAnalysisPtIndex(this);
|
||||||
before_div_arrival_ = before_div_.arrival(sta_);
|
before_div_arrival_ = before_div_.arrival(this);
|
||||||
prev_arc_ = prev_arc;
|
prev_arc_ = prev_arc;
|
||||||
prev_vertex_ = prev_vertex;
|
prev_vertex_ = prev_vertex;
|
||||||
visitFaninPaths(vertex);
|
visitFaninPaths(vertex);
|
||||||
|
|
@ -325,13 +325,12 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const PathAnalysisPt *path_ap)
|
const PathAnalysisPt *path_ap)
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
||||||
debugPrint(debug, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
from_path->name(this),
|
||||||
from_path->name(sta_),
|
to_vertex->name(network_),
|
||||||
to_vertex->name(sta_->network()),
|
|
||||||
to_rf->asString(),
|
to_rf->asString(),
|
||||||
delayAsString(sta_->search()->deratedDelay(from_vertex, arc, edge,
|
delayAsString(search_->deratedDelay(from_vertex, arc, edge,
|
||||||
false,path_ap),sta_));
|
false,path_ap), this));
|
||||||
// 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 (to_rf->index() == before_div_rf_index_
|
if (to_rf->index() == before_div_rf_index_
|
||||||
&& path_ap->index() == before_div_ap_index_
|
&& path_ap->index() == before_div_ap_index_
|
||||||
|
|
@ -344,7 +343,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
||||||
// 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, arc, div_end, after_div_copy);
|
makeDivertedPathEnd(from_path, arc, div_end, after_div_copy);
|
||||||
// Only enumerate paths with greater slack.
|
// Only enumerate paths with greater slack.
|
||||||
if (delayGreaterEqual(div_end->slack(sta_), path_end_slack_, sta_)) {
|
if (delayGreaterEqual(div_end->slack(this), path_end_slack_, this)) {
|
||||||
reportDiversion(arc, from_path);
|
reportDiversion(arc, from_path);
|
||||||
path_enum_->makeDiversion(div_end, after_div_copy);
|
path_enum_->makeDiversion(div_end, after_div_copy);
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +351,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
||||||
delete div_end;
|
delete div_end;
|
||||||
}
|
}
|
||||||
// Only enumerate slower/faster paths.
|
// Only enumerate slower/faster paths.
|
||||||
else if (delayLessEqual(to_arrival, before_div_arrival_, min_max, sta_)) {
|
else if (delayLessEqual(to_arrival, before_div_arrival_, min_max, this)) {
|
||||||
PathEnd *div_end;
|
PathEnd *div_end;
|
||||||
PathEnumed *after_div_copy;
|
PathEnumed *after_div_copy;
|
||||||
makeDivertedPathEnd(from_path, arc, div_end, after_div_copy);
|
makeDivertedPathEnd(from_path, arc, div_end, after_div_copy);
|
||||||
|
|
@ -374,36 +373,34 @@ 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, sta_);
|
div_end->setPath(div_path, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc,
|
PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc,
|
||||||
Path *after_div)
|
Path *after_div)
|
||||||
{
|
{
|
||||||
Debug *debug = sta_->debug();
|
if (debug_->check("path_enum", 3)) {
|
||||||
if (debug->check("path_enum", 3)) {
|
|
||||||
Report *report = sta_->report();
|
|
||||||
Path *path = path_end_->path();
|
Path *path = path_end_->path();
|
||||||
const PathAnalysisPt *path_ap = path->pathAnalysisPt(sta_);
|
const PathAnalysisPt *path_ap = path->pathAnalysisPt(this);
|
||||||
Arrival path_delay = path_enum_->cmp_slack_
|
Arrival path_delay = path_enum_->cmp_slack_
|
||||||
? path_end_->slack(sta_)
|
? path_end_->slack(this)
|
||||||
: path_end_->dataArrivalTime(sta_);
|
: path_end_->dataArrivalTime(this);
|
||||||
Arrival div_delay = path_delay - path_enum_->divSlack(&before_div_,
|
Arrival div_delay = path_delay - path_enum_->divSlack(&before_div_,
|
||||||
after_div,
|
after_div,
|
||||||
div_arc, path_ap);
|
div_arc, path_ap);
|
||||||
PathRef div_prev;
|
PathRef div_prev;
|
||||||
before_div_.prevPath(sta_, div_prev);
|
before_div_.prevPath(this, div_prev);
|
||||||
report->reportLine("path_enum: diversion %s %s %s -> %s",
|
report_->reportLine("path_enum: diversion %s %s %s -> %s",
|
||||||
path->name(sta_),
|
path->name(this),
|
||||||
path_enum_->cmp_slack_ ? "slack" : "delay",
|
path_enum_->cmp_slack_ ? "slack" : "delay",
|
||||||
delayAsString(path_delay, sta_),
|
delayAsString(path_delay, this),
|
||||||
delayAsString(div_delay, sta_));
|
delayAsString(div_delay, this));
|
||||||
report->reportLine("path_enum: from %s -> %s",
|
report_->reportLine("path_enum: from %s -> %s",
|
||||||
div_prev.name(sta_),
|
div_prev.name(this),
|
||||||
before_div_.name(sta_));
|
before_div_.name(this));
|
||||||
report->reportLine("path_enum: to %s ->e",
|
report_->reportLine("path_enum: to %s ->e",
|
||||||
after_div->name(sta_));
|
after_div->name(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ PrevPathVisitor::PrevPathVisitor(const Path *path,
|
||||||
VertexVisitor *
|
VertexVisitor *
|
||||||
PrevPathVisitor::copy() const
|
PrevPathVisitor::copy() const
|
||||||
{
|
{
|
||||||
return new PrevPathVisitor(path_, pred_, sta_);
|
return new PrevPathVisitor(path_, pred_, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -396,14 +396,14 @@ PrevPathVisitor::visitFromToPath(const Pin *,
|
||||||
&& (dcalc_tol_ > 0.0
|
&& (dcalc_tol_ > 0.0
|
||||||
? std::abs(delayAsFloat(to_arrival - path_arrival_)) < dcalc_tol_
|
? std::abs(delayAsFloat(to_arrival - path_arrival_)) < dcalc_tol_
|
||||||
: delayEqual(to_arrival, path_arrival_))
|
: delayEqual(to_arrival, path_arrival_))
|
||||||
&& (tagMatch(to_tag, path_tag_, sta_)
|
&& (tagMatch(to_tag, path_tag_, this)
|
||||||
// If the filter exception became active searching from
|
// If the filter exception became active searching from
|
||||||
// from_path to to_path the tag includes the filter, but
|
// from_path to to_path the tag includes the filter, but
|
||||||
// to_vertex still has paths from previous searches that do
|
// to_vertex still has paths from previous searches that do
|
||||||
// not have the filter.
|
// not have the filter.
|
||||||
|| (!from_tag->isFilter()
|
|| (!from_tag->isFilter()
|
||||||
&& to_tag->isFilter()
|
&& to_tag->isFilter()
|
||||||
&& tagMatch(unfilteredTag(to_tag), path_tag_, sta_)))) {
|
&& tagMatch(unfilteredTag(to_tag), path_tag_, this)))) {
|
||||||
int arrival_index;
|
int arrival_index;
|
||||||
bool arrival_exists;
|
bool arrival_exists;
|
||||||
from_path->arrivalIndex(arrival_index, arrival_exists);
|
from_path->arrivalIndex(arrival_index, arrival_exists);
|
||||||
|
|
@ -420,8 +420,6 @@ PrevPathVisitor::visitFromToPath(const Pin *,
|
||||||
Tag *
|
Tag *
|
||||||
PrevPathVisitor::unfilteredTag(const Tag *tag) const
|
PrevPathVisitor::unfilteredTag(const Tag *tag) const
|
||||||
{
|
{
|
||||||
Search *search = sta_->search();
|
|
||||||
const Corners *corners = sta_->corners();
|
|
||||||
ExceptionStateSet *unfiltered_states = nullptr;
|
ExceptionStateSet *unfiltered_states = nullptr;
|
||||||
const ExceptionStateSet *states = tag->states();
|
const ExceptionStateSet *states = tag->states();
|
||||||
ExceptionStateSet::ConstIterator state_iter(states);
|
ExceptionStateSet::ConstIterator state_iter(states);
|
||||||
|
|
@ -434,8 +432,8 @@ PrevPathVisitor::unfilteredTag(const Tag *tag) const
|
||||||
unfiltered_states->insert(state);
|
unfiltered_states->insert(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return search->findTag(tag->transition(),
|
return search_->findTag(tag->transition(),
|
||||||
corners->findPathAnalysisPt(tag->pathAPIndex()),
|
corners_->findPathAnalysisPt(tag->pathAPIndex()),
|
||||||
tag->clkInfo(),
|
tag->clkInfo(),
|
||||||
tag->isClock(),
|
tag->isClock(),
|
||||||
tag->inputDelay(),
|
tag->inputDelay(),
|
||||||
|
|
|
||||||
349
search/Search.cc
349
search/Search.cc
|
|
@ -384,6 +384,7 @@ Search::copyState(const StaState *sta)
|
||||||
// Notify sub-components.
|
// Notify sub-components.
|
||||||
arrival_iter_->copyState(sta);
|
arrival_iter_->copyState(sta);
|
||||||
required_iter_->copyState(sta);
|
required_iter_->copyState(sta);
|
||||||
|
arrival_visitor_->copyState(sta);
|
||||||
visit_path_ends_->copyState(sta);
|
visit_path_ends_->copyState(sta);
|
||||||
gated_clk_->copyState(sta);
|
gated_clk_->copyState(sta);
|
||||||
check_crpr_->copyState(sta);
|
check_crpr_->copyState(sta);
|
||||||
|
|
@ -1030,16 +1031,15 @@ ArrivalVisitor::ArrivalVisitor(bool always_to_endpoints,
|
||||||
void
|
void
|
||||||
ArrivalVisitor::init0()
|
ArrivalVisitor::init0()
|
||||||
{
|
{
|
||||||
tag_bldr_ = new TagGroupBldr(true, sta_);
|
tag_bldr_ = new TagGroupBldr(true, this);
|
||||||
tag_bldr_no_crpr_ = new TagGroupBldr(false, sta_);
|
tag_bldr_no_crpr_ = new TagGroupBldr(false, this);
|
||||||
adj_pred_ = new SearchThru(tag_bldr_, sta_);
|
adj_pred_ = new SearchThru(tag_bldr_, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ArrivalVisitor::init(bool always_to_endpoints)
|
ArrivalVisitor::init(bool always_to_endpoints)
|
||||||
{
|
{
|
||||||
Search *search = sta_->search();
|
init(always_to_endpoints, search_ ? search_->evalPred() : nullptr);
|
||||||
init(always_to_endpoints, search ? search->evalPred() : nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1048,14 +1048,14 @@ ArrivalVisitor::init(bool always_to_endpoints,
|
||||||
{
|
{
|
||||||
always_to_endpoints_ = always_to_endpoints;
|
always_to_endpoints_ = always_to_endpoints;
|
||||||
pred_ = pred;
|
pred_ = pred;
|
||||||
crpr_active_ = sta_->sdc()->crprActive();
|
crpr_active_ = sdc_->crprActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexVisitor *
|
VertexVisitor *
|
||||||
ArrivalVisitor::copy() const
|
ArrivalVisitor::copy() const
|
||||||
{
|
{
|
||||||
return new ArrivalVisitor(always_to_endpoints_, pred_, sta_);
|
return new ArrivalVisitor(always_to_endpoints_, pred_, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrivalVisitor::~ArrivalVisitor()
|
ArrivalVisitor::~ArrivalVisitor()
|
||||||
|
|
@ -1074,40 +1074,34 @@ ArrivalVisitor::setAlwaysToEndpoints(bool to_endpoints)
|
||||||
void
|
void
|
||||||
ArrivalVisitor::visit(Vertex *vertex)
|
ArrivalVisitor::visit(Vertex *vertex)
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "search", 2, "find arrivals %s",
|
||||||
const Network *network = sta_->network();
|
vertex->name(sdc_network_));
|
||||||
const Network *sdc_network = sta_->sdcNetwork();
|
|
||||||
const Graph *graph = sta_->graph();
|
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
Search *search = sta_->search();
|
|
||||||
debugPrint(debug, "search", 2, "find arrivals %s",
|
|
||||||
vertex->name(sdc_network));
|
|
||||||
Pin *pin = vertex->pin();
|
Pin *pin = vertex->pin();
|
||||||
tag_bldr_->init(vertex);
|
tag_bldr_->init(vertex);
|
||||||
has_fanin_one_ = graph->hasFaninOne(vertex);
|
has_fanin_one_ = graph_->hasFaninOne(vertex);
|
||||||
if (crpr_active_
|
if (crpr_active_
|
||||||
&& !has_fanin_one_)
|
&& !has_fanin_one_)
|
||||||
tag_bldr_no_crpr_->init(vertex);
|
tag_bldr_no_crpr_->init(vertex);
|
||||||
|
|
||||||
visitFaninPaths(vertex);
|
visitFaninPaths(vertex);
|
||||||
if (crpr_active_
|
if (crpr_active_
|
||||||
&& search->crprPathPruningEnabled()
|
&& search_->crprPathPruningEnabled()
|
||||||
&& !vertex->crprPathPruningDisabled()
|
&& !vertex->crprPathPruningDisabled()
|
||||||
&& !has_fanin_one_)
|
&& !has_fanin_one_)
|
||||||
pruneCrprArrivals();
|
pruneCrprArrivals();
|
||||||
|
|
||||||
// Insert paths that originate here.
|
// Insert paths that originate here.
|
||||||
if (!network->isTopLevelPort(pin)
|
if (!network_->isTopLevelPort(pin)
|
||||||
&& sdc->hasInputDelay(pin))
|
&& sdc_->hasInputDelay(pin))
|
||||||
// set_input_delay on internal pin.
|
// set_input_delay on internal pin.
|
||||||
search->seedInputSegmentArrival(pin, vertex, tag_bldr_);
|
search_->seedInputSegmentArrival(pin, vertex, tag_bldr_);
|
||||||
if (sdc->isPathDelayInternalStartpoint(pin))
|
if (sdc_->isPathDelayInternalStartpoint(pin))
|
||||||
// set_min/max_delay -from internal pin.
|
// set_min/max_delay -from internal pin.
|
||||||
search->makeUnclkedPaths(vertex, false, true, tag_bldr_);
|
search_->makeUnclkedPaths(vertex, false, true, tag_bldr_);
|
||||||
if (sdc->isLeafPinClock(pin))
|
if (sdc_->isLeafPinClock(pin))
|
||||||
// set_min/max_delay -to internal pin also a clock src. Bizzaroland.
|
// set_min/max_delay -to internal pin also a clock src. Bizzaroland.
|
||||||
// Re-seed the clock arrivals on top of the propagated paths.
|
// Re-seed the clock arrivals on top of the propagated paths.
|
||||||
search->seedClkArrivals(pin, vertex, tag_bldr_);
|
search_->seedClkArrivals(pin, vertex, tag_bldr_);
|
||||||
// Register/latch clock pin that is not connected to a declared clock.
|
// Register/latch clock pin that is not connected to a declared clock.
|
||||||
// Seed with unclocked tag, zero arrival and allow search thru reg
|
// Seed with unclocked tag, zero arrival and allow search thru reg
|
||||||
// clk->q edges.
|
// clk->q edges.
|
||||||
|
|
@ -1115,30 +1109,30 @@ ArrivalVisitor::visit(Vertex *vertex)
|
||||||
// For example, "set_max_delay -to" from an unclocked source register.
|
// For example, "set_max_delay -to" from an unclocked source register.
|
||||||
bool is_clk = tag_bldr_->hasClkTag();
|
bool is_clk = tag_bldr_->hasClkTag();
|
||||||
if (vertex->isRegClk() && !is_clk) {
|
if (vertex->isRegClk() && !is_clk) {
|
||||||
debugPrint(debug, "search", 2, "arrival seed unclked reg clk %s",
|
debugPrint(debug_, "search", 2, "arrival seed unclked reg clk %s",
|
||||||
network->pathName(pin));
|
network_->pathName(pin));
|
||||||
search->makeUnclkedPaths(vertex, true, false, tag_bldr_);
|
search_->makeUnclkedPaths(vertex, true, false, tag_bldr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arrivals_changed = search->arrivalsChanged(vertex, tag_bldr_);
|
bool arrivals_changed = search_->arrivalsChanged(vertex, tag_bldr_);
|
||||||
// If vertex is a latch data input arrival that changed from the
|
// If vertex is a latch data input arrival that changed from the
|
||||||
// previous eval pass enqueue the latch outputs to be re-evaled on the
|
// previous eval pass enqueue the latch outputs to be re-evaled on the
|
||||||
// next pass.
|
// next pass.
|
||||||
if (network->isLatchData(pin)) {
|
if (network_->isLatchData(pin)) {
|
||||||
if (arrivals_changed
|
if (arrivals_changed
|
||||||
&& network->isLatchData(pin))
|
&& network_->isLatchData(pin))
|
||||||
search->enqueueLatchDataOutputs(vertex);
|
search_->enqueueLatchDataOutputs(vertex);
|
||||||
}
|
}
|
||||||
if (!search->arrivalsAtEndpointsExist()
|
if (!search_->arrivalsAtEndpointsExist()
|
||||||
|| always_to_endpoints_
|
|| always_to_endpoints_
|
||||||
|| arrivals_changed)
|
|| arrivals_changed)
|
||||||
search->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_);
|
search_->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_);
|
||||||
if (arrivals_changed) {
|
if (arrivals_changed) {
|
||||||
debugPrint(debug, "search", 4, "arrival changed");
|
debugPrint(debug_, "search", 4, "arrival changed");
|
||||||
// Only update arrivals when delays change by more than
|
// Only update arrivals when delays change by more than
|
||||||
// fuzzyEqual can distinguish.
|
// fuzzyEqual can distinguish.
|
||||||
search->setVertexArrivals(vertex, tag_bldr_);
|
search_->setVertexArrivals(vertex, tag_bldr_);
|
||||||
search->tnsInvalid(vertex);
|
search_->tnsInvalid(vertex);
|
||||||
constrainedRequiredsInvalid(vertex, is_clk);
|
constrainedRequiredsInvalid(vertex, is_clk);
|
||||||
}
|
}
|
||||||
enqueueRefPinInputDelays(pin);
|
enqueueRefPinInputDelays(pin);
|
||||||
|
|
@ -1151,37 +1145,33 @@ void
|
||||||
ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex,
|
ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex,
|
||||||
bool is_clk)
|
bool is_clk)
|
||||||
{
|
{
|
||||||
Search *search = sta_->search();
|
|
||||||
Pin *pin = vertex->pin();
|
Pin *pin = vertex->pin();
|
||||||
const Network *network = sta_->network();
|
if (network_->isLoad(pin)
|
||||||
if (network->isLoad(pin)
|
&& search_->requiredsExist()) {
|
||||||
&& search->requiredsExist()) {
|
if (is_clk && network_->isCheckClk(pin)) {
|
||||||
const Graph *graph = sta_->graph();
|
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
if (is_clk && network->isCheckClk(pin)) {
|
|
||||||
VertexOutEdgeIterator edge_iter(vertex, graph);
|
|
||||||
while (edge_iter.hasNext()) {
|
while (edge_iter.hasNext()) {
|
||||||
Edge *edge = edge_iter.next();
|
Edge *edge = edge_iter.next();
|
||||||
if (edge->role()->isTimingCheck()) {
|
if (edge->role()->isTimingCheck()) {
|
||||||
Vertex *to_vertex = edge->to(graph);
|
Vertex *to_vertex = edge->to(graph_);
|
||||||
search->requiredInvalid(to_vertex);
|
search_->requiredInvalid(to_vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Data checks (vertex does not need to be a clk).
|
// Data checks (vertex does not need to be a clk).
|
||||||
DataCheckSet *data_checks = sdc->dataChecksFrom(pin);
|
DataCheckSet *data_checks = sdc_->dataChecksFrom(pin);
|
||||||
if (data_checks) {
|
if (data_checks) {
|
||||||
for (DataCheck *data_check : *data_checks) {
|
for (DataCheck *data_check : *data_checks) {
|
||||||
Pin *to = data_check->to();
|
Pin *to = data_check->to();
|
||||||
search->requiredInvalid(to);
|
search_->requiredInvalid(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Gated clocks.
|
// Gated clocks.
|
||||||
if (is_clk && sdc->gatedClkChecksEnabled()) {
|
if (is_clk && sdc_->gatedClkChecksEnabled()) {
|
||||||
PinSet enable_pins;
|
PinSet enable_pins;
|
||||||
search->gatedClk()->gatedClkEnables(vertex, enable_pins);
|
search_->gatedClk()->gatedClkEnables(vertex, enable_pins);
|
||||||
for (Pin *enable : enable_pins)
|
for (Pin *enable : enable_pins)
|
||||||
search->requiredInvalid(enable);
|
search_->requiredInvalid(enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1232,18 +1222,16 @@ ArrivalVisitor::visitFromToPath(const Pin *,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const PathAnalysisPt *)
|
const PathAnalysisPt *)
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "search", 3, " %s",
|
||||||
const Network *sdc_network = sta_->sdcNetwork();
|
from_vertex->name(sdc_network_));
|
||||||
debugPrint(debug, "search", 3, " %s",
|
debugPrint(debug_, "search", 3, " %s -> %s %s",
|
||||||
from_vertex->name(sdc_network));
|
|
||||||
debugPrint(debug, "search", 3, " %s -> %s %s",
|
|
||||||
from_rf->asString(),
|
from_rf->asString(),
|
||||||
to_rf->asString(),
|
to_rf->asString(),
|
||||||
min_max->asString());
|
min_max->asString());
|
||||||
debugPrint(debug, "search", 3, " from tag: %s",
|
debugPrint(debug_, "search", 3, " from tag: %s",
|
||||||
from_tag->asString(sta_));
|
from_tag->asString(this));
|
||||||
debugPrint(debug, "search", 3, " to tag : %s",
|
debugPrint(debug_, "search", 3, " to tag : %s",
|
||||||
to_tag->asString(sta_));
|
to_tag->asString(this));
|
||||||
ClkInfo *to_clk_info = to_tag->clkInfo();
|
ClkInfo *to_clk_info = to_tag->clkInfo();
|
||||||
bool to_is_clk = to_tag->isClock();
|
bool to_is_clk = to_tag->isClock();
|
||||||
Arrival arrival;
|
Arrival arrival;
|
||||||
|
|
@ -1251,16 +1239,16 @@ ArrivalVisitor::visitFromToPath(const Pin *,
|
||||||
Tag *tag_match;
|
Tag *tag_match;
|
||||||
tag_bldr_->tagMatchArrival(to_tag, tag_match, arrival, arrival_index);
|
tag_bldr_->tagMatchArrival(to_tag, tag_match, arrival, arrival_index);
|
||||||
if (tag_match == nullptr
|
if (tag_match == nullptr
|
||||||
|| delayGreater(to_arrival, arrival, min_max, sta_)) {
|
|| delayGreater(to_arrival, arrival, min_max, this)) {
|
||||||
debugPrint(debug, "search", 3, " %s + %s = %s %s %s",
|
debugPrint(debug_, "search", 3, " %s + %s = %s %s %s",
|
||||||
delayAsString(from_path->arrival(sta_), sta_),
|
delayAsString(from_path->arrival(this), this),
|
||||||
delayAsString(arc_delay, sta_),
|
delayAsString(arc_delay, this),
|
||||||
delayAsString(to_arrival, sta_),
|
delayAsString(to_arrival, this),
|
||||||
min_max == MinMax::max() ? ">" : "<",
|
min_max == MinMax::max() ? ">" : "<",
|
||||||
tag_match ? delayAsString(arrival, sta_) : "MIA");
|
tag_match ? delayAsString(arrival, this) : "MIA");
|
||||||
PathVertexRep prev_path;
|
PathVertexRep prev_path;
|
||||||
if (to_tag->isClock() || to_tag->isGenClkSrcPath())
|
if (to_tag->isClock() || to_tag->isGenClkSrcPath())
|
||||||
prev_path.init(from_path, sta_);
|
prev_path.init(from_path, this);
|
||||||
tag_bldr_->setMatchArrival(to_tag, tag_match,
|
tag_bldr_->setMatchArrival(to_tag, tag_match,
|
||||||
to_arrival, arrival_index,
|
to_arrival, arrival_index,
|
||||||
&prev_path);
|
&prev_path);
|
||||||
|
|
@ -1271,7 +1259,7 @@ ArrivalVisitor::visitFromToPath(const Pin *,
|
||||||
tag_bldr_no_crpr_->tagMatchArrival(to_tag, tag_match,
|
tag_bldr_no_crpr_->tagMatchArrival(to_tag, tag_match,
|
||||||
arrival, arrival_index);
|
arrival, arrival_index);
|
||||||
if (tag_match == nullptr
|
if (tag_match == nullptr
|
||||||
|| delayGreater(to_arrival, arrival, min_max, sta_)) {
|
|| delayGreater(to_arrival, arrival, min_max, this)) {
|
||||||
tag_bldr_no_crpr_->setMatchArrival(to_tag, tag_match,
|
tag_bldr_no_crpr_->setMatchArrival(to_tag, tag_match,
|
||||||
to_arrival, arrival_index,
|
to_arrival, arrival_index,
|
||||||
&prev_path);
|
&prev_path);
|
||||||
|
|
@ -1284,9 +1272,8 @@ ArrivalVisitor::visitFromToPath(const Pin *,
|
||||||
void
|
void
|
||||||
ArrivalVisitor::pruneCrprArrivals()
|
ArrivalVisitor::pruneCrprArrivals()
|
||||||
{
|
{
|
||||||
const Debug *debug = sta_->debug();
|
|
||||||
ArrivalMap::Iterator arrival_iter(tag_bldr_->arrivalMap());
|
ArrivalMap::Iterator arrival_iter(tag_bldr_->arrivalMap());
|
||||||
CheckCrpr *crpr = sta_->search()->checkCrpr();
|
CheckCrpr *crpr = search_->checkCrpr();
|
||||||
while (arrival_iter.hasNext()) {
|
while (arrival_iter.hasNext()) {
|
||||||
Tag *tag;
|
Tag *tag;
|
||||||
int arrival_index;
|
int arrival_index;
|
||||||
|
|
@ -1294,7 +1281,7 @@ ArrivalVisitor::pruneCrprArrivals()
|
||||||
ClkInfo *clk_info = tag->clkInfo();
|
ClkInfo *clk_info = tag->clkInfo();
|
||||||
if (!tag->isClock()
|
if (!tag->isClock()
|
||||||
&& clk_info->hasCrprClkPin()) {
|
&& clk_info->hasCrprClkPin()) {
|
||||||
PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta_);
|
PathAnalysisPt *path_ap = tag->pathAnalysisPt(this);
|
||||||
const MinMax *min_max = path_ap->pathMinMax();
|
const MinMax *min_max = path_ap->pathMinMax();
|
||||||
Tag *tag_no_crpr;
|
Tag *tag_no_crpr;
|
||||||
Arrival max_arrival;
|
Arrival max_arrival;
|
||||||
|
|
@ -1307,15 +1294,15 @@ ArrivalVisitor::pruneCrprArrivals()
|
||||||
Arrival max_arrival_max_crpr = (min_max == MinMax::max())
|
Arrival max_arrival_max_crpr = (min_max == MinMax::max())
|
||||||
? max_arrival - max_crpr
|
? max_arrival - max_crpr
|
||||||
: max_arrival + max_crpr;
|
: max_arrival + max_crpr;
|
||||||
debugPrint(debug, "search", 4, " cmp %s %s - %s = %s",
|
debugPrint(debug_, "search", 4, " cmp %s %s - %s = %s",
|
||||||
tag->asString(sta_),
|
tag->asString(this),
|
||||||
delayAsString(max_arrival, sta_),
|
delayAsString(max_arrival, this),
|
||||||
delayAsString(max_crpr, sta_),
|
delayAsString(max_crpr, this),
|
||||||
delayAsString(max_arrival_max_crpr, sta_));
|
delayAsString(max_arrival_max_crpr, this));
|
||||||
Arrival arrival = tag_bldr_->arrival(arrival_index);
|
Arrival arrival = tag_bldr_->arrival(arrival_index);
|
||||||
if (delayGreater(max_arrival_max_crpr, arrival, min_max, sta_)) {
|
if (delayGreater(max_arrival_max_crpr, arrival, min_max, this)) {
|
||||||
debugPrint(debug, "search", 3, " pruned %s",
|
debugPrint(debug_, "search", 3, " pruned %s",
|
||||||
tag->asString(sta_));
|
tag->asString(this));
|
||||||
tag_bldr_->deleteArrival(tag);
|
tag_bldr_->deleteArrival(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1329,14 +1316,12 @@ ArrivalVisitor::pruneCrprArrivals()
|
||||||
void
|
void
|
||||||
ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin)
|
ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
InputDelaySet *input_delays = sdc_->refPinInputDelays(ref_pin);
|
||||||
InputDelaySet *input_delays = sdc->refPinInputDelays(ref_pin);
|
|
||||||
if (input_delays) {
|
if (input_delays) {
|
||||||
const Graph *graph = sta_->graph();
|
|
||||||
for (InputDelay *input_delay : *input_delays) {
|
for (InputDelay *input_delay : *input_delays) {
|
||||||
const Pin *pin = input_delay->pin();
|
const Pin *pin = input_delay->pin();
|
||||||
Vertex *vertex, *bidirect_drvr_vertex;
|
Vertex *vertex, *bidirect_drvr_vertex;
|
||||||
graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||||
seedInputDelayArrival(pin, vertex, input_delay);
|
seedInputDelayArrival(pin, vertex, input_delay);
|
||||||
if (bidirect_drvr_vertex)
|
if (bidirect_drvr_vertex)
|
||||||
seedInputDelayArrival(pin, bidirect_drvr_vertex, input_delay);
|
seedInputDelayArrival(pin, bidirect_drvr_vertex, input_delay);
|
||||||
|
|
@ -1349,15 +1334,13 @@ ArrivalVisitor::seedInputDelayArrival(const Pin *pin,
|
||||||
Vertex *vertex,
|
Vertex *vertex,
|
||||||
InputDelay *input_delay)
|
InputDelay *input_delay)
|
||||||
{
|
{
|
||||||
TagGroupBldr tag_bldr(true, sta_);
|
TagGroupBldr tag_bldr(true, this);
|
||||||
Search *search = sta_->search();
|
|
||||||
Network *network = sta_->network();
|
|
||||||
tag_bldr.init(vertex);
|
tag_bldr.init(vertex);
|
||||||
search->seedInputDelayArrival(pin, vertex, input_delay,
|
search_->seedInputDelayArrival(pin, vertex, input_delay,
|
||||||
!network->isTopLevelPort(pin), &tag_bldr);
|
!network_->isTopLevelPort(pin), &tag_bldr);
|
||||||
search->setVertexArrivals(vertex, &tag_bldr);
|
search_->setVertexArrivals(vertex, &tag_bldr);
|
||||||
search->arrivalIterator()->enqueueAdjacentVertices(vertex,
|
search_->arrivalIterator()->enqueueAdjacentVertices(vertex,
|
||||||
search->searchAdj());
|
search_->searchAdj());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1958,15 +1941,15 @@ Search::inputDelayTag(const Pin *pin,
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PathVisitor::PathVisitor(const StaState *sta) :
|
PathVisitor::PathVisitor(const StaState *sta) :
|
||||||
pred_(sta->search()->evalPred()),
|
StaState(sta),
|
||||||
sta_(sta)
|
pred_(sta->search()->evalPred())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PathVisitor::PathVisitor(SearchPred *pred,
|
PathVisitor::PathVisitor(SearchPred *pred,
|
||||||
const StaState *sta) :
|
const StaState *sta) :
|
||||||
pred_(pred),
|
StaState(sta),
|
||||||
sta_(sta)
|
pred_(pred)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1974,11 +1957,10 @@ void
|
||||||
PathVisitor::visitFaninPaths(Vertex *to_vertex)
|
PathVisitor::visitFaninPaths(Vertex *to_vertex)
|
||||||
{
|
{
|
||||||
if (pred_->searchTo(to_vertex)) {
|
if (pred_->searchTo(to_vertex)) {
|
||||||
const Graph *graph = sta_->graph();
|
VertexInEdgeIterator edge_iter(to_vertex, graph_);
|
||||||
VertexInEdgeIterator edge_iter(to_vertex, graph);
|
|
||||||
while (edge_iter.hasNext()) {
|
while (edge_iter.hasNext()) {
|
||||||
Edge *edge = edge_iter.next();
|
Edge *edge = edge_iter.next();
|
||||||
Vertex *from_vertex = edge->from(graph);
|
Vertex *from_vertex = edge->from(graph_);
|
||||||
const Pin *from_pin = from_vertex->pin();
|
const Pin *from_pin = from_vertex->pin();
|
||||||
if (pred_->searchFrom(from_vertex)
|
if (pred_->searchFrom(from_vertex)
|
||||||
&& pred_->searchThru(edge)) {
|
&& pred_->searchThru(edge)) {
|
||||||
|
|
@ -1995,16 +1977,15 @@ PathVisitor::visitFanoutPaths(Vertex *from_vertex)
|
||||||
{
|
{
|
||||||
const Pin *from_pin = from_vertex->pin();
|
const Pin *from_pin = from_vertex->pin();
|
||||||
if (pred_->searchFrom(from_vertex)) {
|
if (pred_->searchFrom(from_vertex)) {
|
||||||
const Graph *graph = sta_->graph();
|
VertexOutEdgeIterator edge_iter(from_vertex, graph_);
|
||||||
VertexOutEdgeIterator edge_iter(from_vertex, graph);
|
|
||||||
while (edge_iter.hasNext()) {
|
while (edge_iter.hasNext()) {
|
||||||
Edge *edge = edge_iter.next();
|
Edge *edge = edge_iter.next();
|
||||||
Vertex *to_vertex = edge->to(graph);
|
Vertex *to_vertex = edge->to(graph_);
|
||||||
const Pin *to_pin = to_vertex->pin();
|
const Pin *to_pin = to_vertex->pin();
|
||||||
if (pred_->searchTo(to_vertex)
|
if (pred_->searchTo(to_vertex)
|
||||||
&& pred_->searchThru(edge)) {
|
&& pred_->searchThru(edge)) {
|
||||||
debugPrint(sta_->debug(), "search", 3,
|
debugPrint(debug_, "search", 3, " %s",
|
||||||
" %s", to_vertex->name(sta_->network()));
|
to_vertex->name(network_));
|
||||||
if (!visitEdge(from_pin, from_vertex, edge, to_pin, to_vertex))
|
if (!visitEdge(from_pin, from_vertex, edge, to_pin, to_vertex))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2019,16 +2000,15 @@ PathVisitor::visitEdge(const Pin *from_pin,
|
||||||
const Pin *to_pin,
|
const Pin *to_pin,
|
||||||
Vertex *to_vertex)
|
Vertex *to_vertex)
|
||||||
{
|
{
|
||||||
Search *search = sta_->search();
|
TagGroup *from_tag_group = search_->tagGroup(from_vertex);
|
||||||
TagGroup *from_tag_group = search->tagGroup(from_vertex);
|
|
||||||
if (from_tag_group) {
|
if (from_tag_group) {
|
||||||
TimingArcSet *arc_set = edge->timingArcSet();
|
TimingArcSet *arc_set = edge->timingArcSet();
|
||||||
VertexPathIterator from_iter(from_vertex, search);
|
VertexPathIterator from_iter(from_vertex, search_);
|
||||||
while (from_iter.hasNext()) {
|
while (from_iter.hasNext()) {
|
||||||
PathVertex *from_path = from_iter.next();
|
PathVertex *from_path = from_iter.next();
|
||||||
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(sta_);
|
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(this);
|
||||||
const MinMax *min_max = path_ap->pathMinMax();
|
const MinMax *min_max = path_ap->pathMinMax();
|
||||||
const RiseFall *from_rf = from_path->transition(sta_);
|
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);
|
||||||
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
|
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
|
||||||
|
|
@ -2079,27 +2059,23 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const PathAnalysisPt *path_ap)
|
const PathAnalysisPt *path_ap)
|
||||||
{
|
{
|
||||||
Network *network = sta_->network();
|
|
||||||
Sdc *sdc = sta_->sdc();
|
|
||||||
Search *search = sta_->search();
|
|
||||||
Latches *latches = sta_->latches();
|
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
Tag *from_tag = from_path->tag(sta_);
|
Tag *from_tag = from_path->tag(this);
|
||||||
ClkInfo *from_clk_info = from_tag->clkInfo();
|
ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||||
Tag *to_tag = nullptr;
|
Tag *to_tag = nullptr;
|
||||||
ClockEdge *clk_edge = from_clk_info->clkEdge();
|
ClockEdge *clk_edge = from_clk_info->clkEdge();
|
||||||
Clock *clk = from_clk_info->clock();
|
Clock *clk = from_clk_info->clock();
|
||||||
Arrival from_arrival = from_path->arrival(sta_);
|
Arrival from_arrival = from_path->arrival(this);
|
||||||
ArcDelay arc_delay = 0.0;
|
ArcDelay arc_delay = 0.0;
|
||||||
Arrival to_arrival;
|
Arrival to_arrival;
|
||||||
if (from_clk_info->isGenClkSrcPath()) {
|
if (from_clk_info->isGenClkSrcPath()) {
|
||||||
if (!sdc->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
if (!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
||||||
&& (sdc->clkThruTristateEnabled()
|
&& (sdc_->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()))) {
|
|| role == TimingRole::tristateDisable()))) {
|
||||||
Clock *gclk = from_tag->genClkSrcPathClk(sta_);
|
Clock *gclk = from_tag->genClkSrcPathClk(this);
|
||||||
if (gclk) {
|
if (gclk) {
|
||||||
Genclks *genclks = search->genclks();
|
Genclks *genclks = search_->genclks();
|
||||||
VertexSet *fanins = genclks->fanins(gclk);
|
VertexSet *fanins = genclks->fanins(gclk);
|
||||||
// Note: encountering a latch d->q edge means find the
|
// Note: encountering a latch d->q edge means find the
|
||||||
// latch feedback edges, but they are referenced for
|
// latch feedback edges, but they are referenced for
|
||||||
|
|
@ -2112,20 +2088,20 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
|| !gclk->combinational())
|
|| !gclk->combinational())
|
||||||
&& fanins->hasKey(to_vertex)
|
&& fanins->hasKey(to_vertex)
|
||||||
&& !(fdbk_edges && fdbk_edges->hasKey(edge))) {
|
&& !(fdbk_edges && fdbk_edges->hasKey(edge))) {
|
||||||
to_tag = search->thruClkTag(from_path, from_tag, true, edge, to_rf,
|
to_tag = search_->thruClkTag(from_path, from_tag, true, edge, to_rf,
|
||||||
min_max, path_ap);
|
min_max, path_ap);
|
||||||
if (to_tag) {
|
if (to_tag) {
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge, true,
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, true,
|
||||||
path_ap);
|
path_ap);
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// PLL out to feedback path.
|
// PLL out to feedback path.
|
||||||
to_tag = search->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||||
if (to_tag) {
|
if (to_tag) {
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge, true,
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, true,
|
||||||
path_ap);
|
path_ap);
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
}
|
}
|
||||||
|
|
@ -2134,30 +2110,30 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
}
|
}
|
||||||
else if (role->genericRole() == TimingRole::regClkToQ()) {
|
else if (role->genericRole() == TimingRole::regClkToQ()) {
|
||||||
if (clk == nullptr
|
if (clk == nullptr
|
||||||
|| !sdc->clkStopPropagation(from_pin, clk)) {
|
|| !sdc_->clkStopPropagation(from_pin, clk)) {
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||||
// Propagate from unclocked reg/latch clk pins, which have no
|
// Propagate from unclocked reg/latch clk pins, which have no
|
||||||
// clk but are distinguished with a segment_start flag.
|
// clk but are distinguished with a segment_start flag.
|
||||||
if ((clk_edge == nullptr
|
if ((clk_edge == nullptr
|
||||||
&& from_tag->isSegmentStart())
|
&& from_tag->isSegmentStart())
|
||||||
// Do not propagate paths from input ports with default
|
// Do not propagate paths from input ports with default
|
||||||
// input arrival clk thru CLK->Q edges.
|
// input arrival clk thru CLK->Q edges.
|
||||||
|| (clk != sdc->defaultArrivalClock()
|
|| (clk != sdc_->defaultArrivalClock()
|
||||||
// Only propagate paths from clocks that have not
|
// Only propagate paths from clocks that have not
|
||||||
// passed thru reg/latch D->Q edges.
|
// passed thru reg/latch D->Q edges.
|
||||||
&& from_tag->isClock())) {
|
&& from_tag->isClock())) {
|
||||||
const RiseFall *clk_rf = clk_edge ? clk_edge->transition() : nullptr;
|
const RiseFall *clk_rf = clk_edge ? clk_edge->transition() : nullptr;
|
||||||
ClkInfo *to_clk_info = from_clk_info;
|
ClkInfo *to_clk_info = from_clk_info;
|
||||||
if (network->direction(to_pin)->isInternal())
|
if (network_->direction(to_pin)->isInternal())
|
||||||
to_clk_info = search->clkInfoWithCrprClkPath(from_clk_info,
|
to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info,
|
||||||
from_path, path_ap);
|
from_path, path_ap);
|
||||||
to_tag = search->fromRegClkTag(from_pin, from_rf, clk, clk_rf,
|
to_tag = search_->fromRegClkTag(from_pin, from_rf, clk, clk_rf,
|
||||||
to_clk_info, to_pin, to_rf, min_max,
|
to_clk_info, to_pin, to_rf, min_max,
|
||||||
path_ap);
|
path_ap);
|
||||||
if (to_tag)
|
if (to_tag)
|
||||||
to_tag = search->thruTag(to_tag, edge, to_rf, min_max, path_ap);
|
to_tag = search_->thruTag(to_tag, edge, to_rf, min_max, path_ap);
|
||||||
from_arrival = search->clkPathArrival(from_path, from_clk_info,
|
from_arrival = search_->clkPathArrival(from_path, from_clk_info,
|
||||||
clk_edge, min_max, path_ap);
|
clk_edge, min_max, path_ap);
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2166,43 +2142,43 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
}
|
}
|
||||||
else if (edge->role() == TimingRole::latchDtoQ()) {
|
else if (edge->role() == TimingRole::latchDtoQ()) {
|
||||||
if (min_max == MinMax::max()) {
|
if (min_max == MinMax::max()) {
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||||
latches->latchOutArrival(from_path, arc, edge, path_ap,
|
latches_->latchOutArrival(from_path, arc, edge, path_ap,
|
||||||
to_tag, arc_delay, to_arrival);
|
to_tag, arc_delay, to_arrival);
|
||||||
if (to_tag)
|
if (to_tag)
|
||||||
to_tag = search->thruTag(to_tag, edge, to_rf, min_max, path_ap);
|
to_tag = search_->thruTag(to_tag, edge, to_rf, min_max, path_ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (from_tag->isClock()) {
|
else if (from_tag->isClock()) {
|
||||||
ClockSet *clks = sdc->findLeafPinClocks(from_pin);
|
ClockSet *clks = sdc_->findLeafPinClocks(from_pin);
|
||||||
// Disable edges from hierarchical clock source pins that do
|
// Disable edges from hierarchical clock source pins that do
|
||||||
// not go thru the hierarchical pin and edges from clock source pins
|
// not go thru the hierarchical pin and edges from clock source pins
|
||||||
// that traverse a hierarchical source pin of a different clock.
|
// that traverse a hierarchical source pin of a different clock.
|
||||||
// Clock arrivals used as data also need to be disabled.
|
// Clock arrivals used as data also need to be disabled.
|
||||||
if (!(role == TimingRole::wire()
|
if (!(role == TimingRole::wire()
|
||||||
&& sdc->clkDisabledByHpinThru(clk, from_pin, to_pin))
|
&& sdc_->clkDisabledByHpinThru(clk, from_pin, to_pin))
|
||||||
// Generated clock source pins have arrivals for the source clock.
|
// Generated clock source pins have arrivals for the source clock.
|
||||||
// Do not propagate them past the generated clock source pin.
|
// Do not propagate them past the generated clock source pin.
|
||||||
&& !(clks
|
&& !(clks
|
||||||
&& !clks->hasKey(from_tag->clock()))) {
|
&& !clks->hasKey(from_tag->clock()))) {
|
||||||
// Propagate arrival as non-clock at the end of the clock tree.
|
// Propagate arrival as non-clock at the end of the clock tree.
|
||||||
bool to_propagates_clk =
|
bool to_propagates_clk =
|
||||||
!sdc->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
||||||
&& (sdc->clkThruTristateEnabled()
|
&& (sdc_->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()));
|
|| role == TimingRole::tristateDisable()));
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge,
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge,
|
||||||
to_propagates_clk, path_ap);
|
to_propagates_clk, path_ap);
|
||||||
to_tag = search->thruClkTag(from_path, from_tag, to_propagates_clk,
|
to_tag = search_->thruClkTag(from_path, from_tag, to_propagates_clk,
|
||||||
edge, to_rf, min_max, path_ap);
|
edge, to_rf, min_max, path_ap);
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arc_delay = search->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||||
if (!delayEqual(arc_delay, min_max->initValue())) {
|
if (!delayEqual(arc_delay, min_max->initValue())) {
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
to_tag = search->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (to_tag)
|
if (to_tag)
|
||||||
|
|
@ -3402,30 +3378,28 @@ RequiredVisitor::~RequiredVisitor()
|
||||||
VertexVisitor *
|
VertexVisitor *
|
||||||
RequiredVisitor::copy() const
|
RequiredVisitor::copy() const
|
||||||
{
|
{
|
||||||
return new RequiredVisitor(sta_);
|
return new RequiredVisitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RequiredVisitor::visit(Vertex *vertex)
|
RequiredVisitor::visit(Vertex *vertex)
|
||||||
{
|
{
|
||||||
Search *search = sta_->search();
|
debugPrint(debug_, "search", 2, "find required %s",
|
||||||
const Debug *debug = sta_->debug();
|
vertex->name(network_));
|
||||||
debugPrint(debug, "search", 2, "find required %s",
|
required_cmp_->requiredsInit(vertex, this);
|
||||||
vertex->name(sta_->network()));
|
|
||||||
required_cmp_->requiredsInit(vertex, sta_);
|
|
||||||
vertex->setRequiredsPruned(false);
|
vertex->setRequiredsPruned(false);
|
||||||
// Back propagate requireds from fanout.
|
// Back propagate requireds from fanout.
|
||||||
visitFanoutPaths(vertex);
|
visitFanoutPaths(vertex);
|
||||||
// Check for constraints at endpoints that set required times.
|
// Check for constraints at endpoints that set required times.
|
||||||
if (search->isEndpoint(vertex)) {
|
if (search_->isEndpoint(vertex)) {
|
||||||
FindEndRequiredVisitor seeder(required_cmp_, sta_);
|
FindEndRequiredVisitor seeder(required_cmp_, this);
|
||||||
visit_path_ends_->visitPathEnds(vertex, &seeder);
|
visit_path_ends_->visitPathEnds(vertex, &seeder);
|
||||||
}
|
}
|
||||||
bool changed = required_cmp_->requiredsSave(vertex, sta_);
|
bool changed = required_cmp_->requiredsSave(vertex, this);
|
||||||
search->tnsInvalid(vertex);
|
search_->tnsInvalid(vertex);
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
search->requiredIterator()->enqueueAdjacentVertices(vertex);
|
search_->requiredIterator()->enqueueAdjacentVertices(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -3446,58 +3420,57 @@ RequiredVisitor::visitFromToPath(const Pin *,
|
||||||
{
|
{
|
||||||
// Don't propagate required times through latch D->Q edges.
|
// Don't propagate required times through latch D->Q edges.
|
||||||
if (edge->role() != TimingRole::latchDtoQ()) {
|
if (edge->role() != TimingRole::latchDtoQ()) {
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "search", 3, " %s -> %s %s",
|
||||||
debugPrint(debug, "search", 3, " %s -> %s %s",
|
|
||||||
from_rf->asString(),
|
from_rf->asString(),
|
||||||
to_rf->asString(),
|
to_rf->asString(),
|
||||||
min_max->asString());
|
min_max->asString());
|
||||||
debugPrint(debug, "search", 3, " from tag %2u: %s",
|
debugPrint(debug_, "search", 3, " from tag %2u: %s",
|
||||||
from_tag->index(),
|
from_tag->index(),
|
||||||
from_tag->asString(sta_));
|
from_tag->asString(this));
|
||||||
int arrival_index;
|
int arrival_index;
|
||||||
bool arrival_exists;
|
bool arrival_exists;
|
||||||
from_path->arrivalIndex(arrival_index, arrival_exists);
|
from_path->arrivalIndex(arrival_index, arrival_exists);
|
||||||
const MinMax *req_min = min_max->opposite();
|
const MinMax *req_min = min_max->opposite();
|
||||||
TagGroup *to_tag_group = sta_->search()->tagGroup(to_vertex);
|
TagGroup *to_tag_group = search_->tagGroup(to_vertex);
|
||||||
// Check to see if to_tag was pruned.
|
// Check to see if to_tag was pruned.
|
||||||
if (to_tag_group && to_tag_group->hasTag(to_tag)) {
|
if (to_tag_group && to_tag_group->hasTag(to_tag)) {
|
||||||
PathVertex to_path(to_vertex, to_tag, sta_);
|
PathVertex to_path(to_vertex, to_tag, this);
|
||||||
Required to_required = to_path.required(sta_);
|
Required to_required = to_path.required(this);
|
||||||
Required from_required = to_required - arc_delay;
|
Required from_required = to_required - arc_delay;
|
||||||
debugPrint(debug, "search", 3, " to tag %2u: %s",
|
debugPrint(debug_, "search", 3, " to tag %2u: %s",
|
||||||
to_tag->index(),
|
to_tag->index(),
|
||||||
to_tag->asString(sta_));
|
to_tag->asString(this));
|
||||||
debugPrint(debug, "search", 3, " %s - %s = %s %s %s",
|
debugPrint(debug_, "search", 3, " %s - %s = %s %s %s",
|
||||||
delayAsString(to_required, sta_),
|
delayAsString(to_required, this),
|
||||||
delayAsString(arc_delay, sta_),
|
delayAsString(arc_delay, this),
|
||||||
delayAsString(from_required, sta_),
|
delayAsString(from_required, this),
|
||||||
min_max == MinMax::max() ? "<" : ">",
|
min_max == MinMax::max() ? "<" : ">",
|
||||||
delayAsString(required_cmp_->required(arrival_index), sta_));
|
delayAsString(required_cmp_->required(arrival_index), this));
|
||||||
required_cmp_->requiredSet(arrival_index, from_required, req_min, sta_);
|
required_cmp_->requiredSet(arrival_index, from_required, req_min, this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (sta_->search()->crprApproxMissingRequireds()) {
|
if (search_->crprApproxMissingRequireds()) {
|
||||||
// Arrival on to_vertex that differs by crpr_pin was pruned.
|
// Arrival on to_vertex that differs by crpr_pin was pruned.
|
||||||
// Find an arrival that matches everything but the crpr_pin
|
// Find an arrival that matches everything but the crpr_pin
|
||||||
// as an appromate required.
|
// as an appromate required.
|
||||||
VertexPathIterator to_iter(to_vertex, to_rf, path_ap, sta_);
|
VertexPathIterator to_iter(to_vertex, to_rf, path_ap, this);
|
||||||
while (to_iter.hasNext()) {
|
while (to_iter.hasNext()) {
|
||||||
PathVertex *to_path = to_iter.next();
|
PathVertex *to_path = to_iter.next();
|
||||||
Tag *to_path_tag = to_path->tag(sta_);
|
Tag *to_path_tag = to_path->tag(this);
|
||||||
if (tagMatchNoCrpr(to_path_tag, to_tag)) {
|
if (tagMatchNoCrpr(to_path_tag, to_tag)) {
|
||||||
Required to_required = to_path->required(sta_);
|
Required to_required = to_path->required(this);
|
||||||
Required from_required = to_required - arc_delay;
|
Required from_required = to_required - arc_delay;
|
||||||
debugPrint(debug, "search", 3, " to tag %2u: %s",
|
debugPrint(debug_, "search", 3, " to tag %2u: %s",
|
||||||
to_path_tag->index(),
|
to_path_tag->index(),
|
||||||
to_path_tag->asString(sta_));
|
to_path_tag->asString(this));
|
||||||
debugPrint(debug, "search", 3, " %s - %s = %s %s %s",
|
debugPrint(debug_, "search", 3, " %s - %s = %s %s %s",
|
||||||
delayAsString(to_required, sta_),
|
delayAsString(to_required, this),
|
||||||
delayAsString(arc_delay, sta_),
|
delayAsString(arc_delay, this),
|
||||||
delayAsString(from_required, sta_),
|
delayAsString(from_required, this),
|
||||||
min_max == MinMax::max() ? "<" : ">",
|
min_max == MinMax::max() ? "<" : ">",
|
||||||
delayAsString(required_cmp_->required(arrival_index),
|
delayAsString(required_cmp_->required(arrival_index),
|
||||||
sta_));
|
this));
|
||||||
required_cmp_->requiredSet(arrival_index, from_required, req_min, sta_);
|
required_cmp_->requiredSet(arrival_index, from_required, req_min, this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -231,8 +231,8 @@ PathGroupPathVisitor::~PathGroupPathVisitor()
|
||||||
VertexVisitor *
|
VertexVisitor *
|
||||||
PathGroupPathVisitor::copy() const
|
PathGroupPathVisitor::copy() const
|
||||||
{
|
{
|
||||||
return new PathGroupPathVisitor(visitor_, bkwd_iter_, matching_path_map_,
|
return new PathGroupPathVisitor(visitor_, bkwd_iter_,
|
||||||
sta_);
|
matching_path_map_, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -241,9 +241,8 @@ PathGroupPathVisitor::visit(Vertex *vertex)
|
||||||
vertex_matches_ = false;
|
vertex_matches_ = false;
|
||||||
visitFanoutPaths(vertex);
|
visitFanoutPaths(vertex);
|
||||||
if (vertex_matches_) {
|
if (vertex_matches_) {
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "visit_path_group", 1, "visit %s",
|
||||||
debugPrint(debug, "visit_path_group", 1, "visit %s",
|
vertex->name(network_));
|
||||||
vertex->name(sta_->network()));
|
|
||||||
visitor_->visit(vertex);
|
visitor_->visit(vertex);
|
||||||
bkwd_iter_->enqueueAdjacentVertices(vertex);
|
bkwd_iter_->enqueueAdjacentVertices(vertex);
|
||||||
}
|
}
|
||||||
|
|
@ -270,31 +269,29 @@ PathGroupPathVisitor::visitFromToPath(const Pin *,
|
||||||
int arrival_index;
|
int arrival_index;
|
||||||
bool arrival_exists;
|
bool arrival_exists;
|
||||||
from_path->arrivalIndex(arrival_index, arrival_exists);
|
from_path->arrivalIndex(arrival_index, arrival_exists);
|
||||||
PathVertex to_path(to_vertex, to_tag, sta_);
|
PathVertex to_path(to_vertex, to_tag, this);
|
||||||
if (!to_path.isNull()) {
|
if (!to_path.isNull()) {
|
||||||
if (matching_paths->hasKey(&to_path)) {
|
if (matching_paths->hasKey(&to_path)) {
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "visit_path_group", 2, "match %s %s -> %s %s",
|
||||||
debugPrint(debug, "visit_path_group", 2, "match %s %s -> %s %s",
|
from_vertex->name(network_),
|
||||||
from_vertex->name(sta_->network()),
|
from_tag->asString(this),
|
||||||
from_tag->asString(sta_),
|
to_vertex->name(network_),
|
||||||
to_vertex->name(sta_->network()),
|
to_tag->asString(this));
|
||||||
to_tag->asString(sta_));
|
|
||||||
fromMatches(from_vertex, from_tag, arrival_index);
|
fromMatches(from_vertex, from_tag, arrival_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VertexPathIterator to_iter(to_vertex, to_rf, path_ap, sta_);
|
VertexPathIterator to_iter(to_vertex, to_rf, path_ap, this);
|
||||||
while (to_iter.hasNext()) {
|
while (to_iter.hasNext()) {
|
||||||
PathVertex *to_path = to_iter.next();
|
PathVertex *to_path = to_iter.next();
|
||||||
if (tagMatchNoCrpr(to_path->tag(sta_), to_tag)
|
if (tagMatchNoCrpr(to_path->tag(this), to_tag)
|
||||||
&& matching_paths->hasKey(to_path)) {
|
&& matching_paths->hasKey(to_path)) {
|
||||||
const Debug *debug = sta_->debug();
|
debugPrint(debug_, "visit_path_group", 2,
|
||||||
debugPrint(debug, "visit_path_group", 2,
|
|
||||||
"match crpr %s %s -> %s %s",
|
"match crpr %s %s -> %s %s",
|
||||||
from_vertex->name(sta_->network()),
|
from_vertex->name(network_),
|
||||||
from_tag->asString(sta_),
|
from_tag->asString(this),
|
||||||
to_vertex->name(sta_->network()),
|
to_vertex->name(network_),
|
||||||
to_tag->asString(sta_));
|
to_tag->asString(this));
|
||||||
fromMatches(from_vertex, from_tag, arrival_index);
|
fromMatches(from_vertex, from_tag, arrival_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +307,7 @@ PathGroupPathVisitor::fromMatches(Vertex *from_vertex,
|
||||||
{
|
{
|
||||||
vertex_matches_ = true;
|
vertex_matches_ = true;
|
||||||
vertexPathSetMapInsertPath(matching_path_map_, from_vertex,
|
vertexPathSetMapInsertPath(matching_path_map_, from_vertex,
|
||||||
from_tag, from_arrival_index, sta_);
|
from_tag, from_arrival_index, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue