diff --git a/include/sta/Path.hh b/include/sta/Path.hh index 542afbe1..7316eff0 100644 --- a/include/sta/Path.hh +++ b/include/sta/Path.hh @@ -120,7 +120,6 @@ public: bool isEnum() const { return is_enum_; } void setIsEnum(bool is_enum); void checkPrevPath(const StaState *sta) const; - void checkPrevPaths(const StaState *sta) const; static Path *vertexPath(const Path *path, const StaState *sta); diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 780ef60a..d54a8a5b 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -408,6 +408,8 @@ public: TagGroupIndex tagGroupIndex(const Vertex *vertex) const; void setTagGroupIndex(const Vertex *vertex, TagGroupIndex tag_index); + void checkPrevPaths() const; + void deletePaths(Vertex *vertex); protected: void init(StaState *sta); @@ -543,7 +545,6 @@ protected: bool is_clk, const PathAnalysisPt *path_ap); void deletePaths(); - void deletePaths(Vertex *vertex); // Delete with incremental tns/wns update. void deletePathsIncr(Vertex *vertex); TagGroup *findTagGroup(TagGroupBldr *group_bldr); diff --git a/search/Crpr.cc b/search/Crpr.cc index 894a1e9b..5cf041a5 100644 --- a/search/Crpr.cc +++ b/search/Crpr.cc @@ -253,7 +253,7 @@ CheckCrpr::genClkSrcPaths(const Path *path) gclk_paths.push_back(path); Genclks *genclks = search_->genclks(); while (clk_edge->clock()->isGenerated()) { - Path *genclk_path = genclks->srcPath(clk_edge, clk_src, path_ap); + const Path *genclk_path = genclks->srcPath(clk_edge, clk_src, path_ap); if (genclk_path == nullptr) break; clk_info = genclk_path->clkInfo(this); diff --git a/search/Genclks.cc b/search/Genclks.cc index 72dc103f..a6eb014a 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -685,10 +685,10 @@ Genclks::seedSrcPins(Clock *gclk, const MinMax *min_max = path_ap->pathMinMax(); const EarlyLate *early_late = min_max; for (const RiseFall *rf : RiseFall::range()) { - Tag *tag = makeTag(gclk, master_clk, master_pin, rf, - src_filter, path_ap); Arrival insert = search_->clockInsertion(master_clk, master_pin, rf, min_max, early_late, path_ap); + Tag *tag = makeTag(gclk, master_clk, master_pin, rf, + src_filter, insert, path_ap); tag_bldr.setArrival(tag, insert); } } @@ -704,6 +704,7 @@ Genclks::makeTag(const Clock *gclk, const Pin *master_pin, const RiseFall *master_rf, FilterPath *src_filter, + Arrival insert, const PathAnalysisPt *path_ap) { ExceptionState *state = src_filter->firstState(); @@ -715,7 +716,7 @@ Genclks::makeTag(const Clock *gclk, states->insert(state); ClkInfo *clk_info = search_->findClkInfo(master_clk->edge(master_rf), master_pin, true, nullptr, true, - nullptr, 0.0, 0.0, nullptr, + nullptr, insert, 0.0, nullptr, path_ap, nullptr); return search_->findTag(master_rf, path_ap, clk_info, false, nullptr, false, states, true); @@ -855,11 +856,11 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, { auto itr = vertex_src_paths_map_.find(vertex); if (itr != vertex_src_paths_map_.end()) { - std::vector &src_paths = itr->second; + const std::vector &src_paths = itr->second; for (const Path *path : src_paths) { Path src_path = *path; Path *prev_path = src_path.prevPath(); - if (prev_path) { + if (prev_path && !prev_path->isNull()) { Path *prev_vpath = Path::vertexPath(prev_path, this); src_path.setPrevPath(prev_vpath); } @@ -921,7 +922,7 @@ Genclks::recordSrcPaths(Clock *gclk) size_t path_index = srcPathIndex(rf, path_ap); Path &src_path = src_paths[path_index]; if ((!divide_by_1 - || (inverting_path == invert)) + || (inverting_path == invert)) && (!has_edges || src_clk_rf == gclk->masterClkEdgeTr(rf)) && (src_path.isNull() @@ -934,6 +935,7 @@ Genclks::recordSrcPaths(Clock *gclk) early_late->to_string().c_str(), rf->to_string().c_str(), delayAsString(path->arrival(), this)); + // If this path is replacing another one delete the previous one. delete src_path.prevPath(); src_path = *path; Path *prev_copy = &src_path; @@ -950,11 +952,13 @@ Genclks::recordSrcPaths(Clock *gclk) } } if (found_src_paths) { + // Record vertex->genclk src paths. for (const Path &path : src_paths) { if (!path.isNull()) { const Path *p = &path; - while (p) { - vertex_src_paths_map_[p->vertex(this)].push_back(p); + while (p && !p->isNull()) { + Vertex *vertex = p->vertex(this); + vertex_src_paths_map_[vertex].push_back(p); p = p->prevPath(); } } @@ -968,6 +972,12 @@ Genclks::recordSrcPaths(Clock *gclk) network_->pathName(gclk_pin), gclk->masterClk()->name()); } + // This can be narrowed to visited vertices. + VertexIterator vertex_iter(graph_); + while (vertex_iter.hasNext()) { + Vertex *vertex = vertex_iter.next(); + search_->deletePaths(vertex); + } } bool @@ -992,7 +1002,7 @@ Genclks::matchesSrcFilter(Path *path, return false; } -Path * +const Path * Genclks::srcPath(const Path *clk_path) const { const Pin *src_pin = clk_path->pin(this); @@ -1004,7 +1014,7 @@ Genclks::srcPath(const Path *clk_path) const insert_ap); } -Path * +const Path * Genclks::srcPath(const ClockEdge *clk_edge, const Pin *src_pin, const PathAnalysisPt *path_ap) const @@ -1012,7 +1022,7 @@ Genclks::srcPath(const ClockEdge *clk_edge, return srcPath(clk_edge->clock(), src_pin, clk_edge->transition(), path_ap); } -Path * +const Path * Genclks::srcPath(const Clock *gclk, const Pin *src_pin, const RiseFall *rf, @@ -1020,14 +1030,12 @@ Genclks::srcPath(const Clock *gclk, { auto itr = genclk_src_paths_.find(ClockPinPair(gclk, src_pin)); if (itr != genclk_src_paths_.end()) { - std::vector src_paths = itr->second; + const std::vector &src_paths = itr->second; if (!src_paths.empty()) { size_t path_index = srcPathIndex(rf, path_ap); - Path &src_path = src_paths[path_index]; - if (!src_path.isNull()) { - Path *src_vpath = Path::vertexPath(src_path, this); - return src_vpath; - } + const Path *src_path = &src_paths[path_index]; + if (!src_path->isNull()) + return src_path; } } return nullptr; @@ -1042,12 +1050,14 @@ Genclks::updateSrcPathPrevs() const Path *p = &src_path; while (p) { Path *src_vpath = Path::vertexPath(p, this); - Path *prev_path = p->prevPath(); - if (prev_path) { - Path *prev_vpath = Path::vertexPath(prev_path, this); - src_vpath->setPrevPath(prev_vpath); - src_vpath->setPrevEdgeArc(p->prevEdge(this), - p->prevArc(this), this); + if (src_vpath) { + Path *prev_path = p->prevPath(); + if (prev_path) { + Path *prev_vpath = Path::vertexPath(prev_path, this); + src_vpath->setPrevPath(prev_vpath); + src_vpath->setPrevEdgeArc(p->prevEdge(this), + p->prevArc(this), this); + } } p = p->prevPath(); } @@ -1066,7 +1076,7 @@ Genclks::insertionDelay(const Clock *clk, const PathAnalysisPt *path_ap) const { PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late); - Path *src_path = srcPath(clk, pin, rf, insert_ap); + const Path *src_path = srcPath(clk, pin, rf, insert_ap); if (src_path) return src_path->arrival(); else diff --git a/search/Genclks.hh b/search/Genclks.hh index 083fe28f..29f5ccae 100644 --- a/search/Genclks.hh +++ b/search/Genclks.hh @@ -72,15 +72,15 @@ public: const EarlyLate *early_late, const PathAnalysisPt *path_ap) const; // Generated clock source path for a clock path root. - Path *srcPath(const Path *clk_path) const; + const Path *srcPath(const Path *clk_path) const; // Generated clock source path. - Path *srcPath(const ClockEdge *clk_edge, - const Pin *src_pin, - const PathAnalysisPt *path_ap) const; - Path *srcPath(const Clock *clk, - const Pin *src_pin, - const RiseFall *rf, - const PathAnalysisPt *path_ap) const; + const Path *srcPath(const ClockEdge *clk_edge, + const Pin *src_pin, + const PathAnalysisPt *path_ap) const; + const Path *srcPath(const Clock *clk, + const Pin *src_pin, + const RiseFall *rf, + const PathAnalysisPt *path_ap) const; Vertex *srcPath(const Pin *pin) const; Level clkPinMaxLevel(const Clock *clk) const; void copyGenClkSrcPaths(Vertex *vertex, @@ -113,6 +113,7 @@ private: const Pin *master_pin, const RiseFall *rf, FilterPath *src_filter, + Arrival insert, const PathAnalysisPt *path_ap); void seedSrcPins(Clock *clk, BfsBkwdIterator &iter); diff --git a/search/Path.cc b/search/Path.cc index 81172189..2aad3bc1 100644 --- a/search/Path.cc +++ b/search/Path.cc @@ -203,13 +203,17 @@ Path::init(Vertex *vertex, std::string Path::to_string(const StaState *sta) const { - const PathAnalysisPt *path_ap = pathAnalysisPt(sta); - return stringPrintTmp("%s %s %s/%d %d", - vertex(sta)->to_string(sta).c_str(), - transition(sta)->to_string().c_str(), - path_ap->pathMinMax()->to_string().c_str(), - path_ap->index(), - tagIndex(sta)); + if (isNull()) + return "null path"; + else { + const PathAnalysisPt *path_ap = pathAnalysisPt(sta); + return stringPrintTmp("%s %s %s/%d %d", + vertex(sta)->to_string(sta).c_str(), + transition(sta)->to_string().c_str(), + path_ap->pathMinMax()->to_string().c_str(), + path_ap->index(), + tagIndex(sta)); + } } bool @@ -366,10 +370,7 @@ Path::slack(const StaState *sta) const Path * Path::prevPath() const { - if (prev_path_ && prev_path_->isNull()) - return nullptr; - else - return prev_path_; + return prev_path_; } void @@ -440,19 +441,12 @@ Path::setPrevEdgeArc(Edge *prev_edge, prev_arc_idx_ = 0; } -void -Path::checkPrevPaths(const StaState *sta) const -{ - const Path *path = this; - while (path) { - path->checkPrevPath(sta); - path = path->prevPath(); - } -} - void Path::checkPrevPath(const StaState *sta) const { + if (prev_path_ && prev_path_->isNull()) + sta->report()->reportLine("path %s prev path is null.", + to_string(sta).c_str()); if (prev_path_ && !prev_path_->isNull()) { Graph *graph = sta->graph(); Edge *edge = prevEdge(sta); diff --git a/search/PathExpanded.cc b/search/PathExpanded.cc index c9cb4b74..170c280a 100644 --- a/search/PathExpanded.cc +++ b/search/PathExpanded.cc @@ -68,10 +68,9 @@ PathExpanded::expand(const Path *path, bool found_start = false; while (p) { const Path *prev_path = p->prevPath(); - const TimingArc *prev_arc = p->prevArc(sta_); - if (!found_start) { - if (prev_arc) { + if (prev_path) { + const TimingArc *prev_arc = p->prevArc(sta_); const TimingRole *prev_role = prev_arc->role(); if (prev_role == TimingRole::regClkToQ() || prev_role == TimingRole::latchEnToQ()) { diff --git a/search/ReportPath.cc b/search/ReportPath.cc index b23c03b0..5f8d5fe0 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -2391,8 +2391,8 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk, { PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late); const MinMax *min_max = path_ap->pathMinMax(); - Path *src_path = search_->genclks()->srcPath(clk, clk_pin, - clk_rf, insert_ap); + const Path *src_path = search_->genclks()->srcPath(clk, clk_pin, + clk_rf, insert_ap); if (src_path) { ClkInfo *src_clk_info = src_path->clkInfo(this); const ClockEdge *src_clk_edge = src_clk_info->clkEdge(); diff --git a/search/Search.cc b/search/Search.cc index 11434eb5..290643f1 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -1276,8 +1276,9 @@ Search::arrivalsChanged(Vertex *vertex, || path1->tag(this) != path2->tag(this) || !delayEqual(path1->arrival(), path2->arrival()) || path1->prevEdge(this) != path2->prevEdge(this) - || path1->prevArc(this) != path2->prevArc(this)) - return true; + || path1->prevArc(this) != path2->prevArc(this) + || path1->prevPath() != path2->prevPath()) + return true; } return false; } @@ -2498,7 +2499,6 @@ Search::thruClkInfo(Path *from_path, const MinMax *min_max, const PathAnalysisPt *path_ap) { - ClkInfo *to_clk_info = from_clk_info; bool changed = false; const ClockEdge *from_clk_edge = from_clk_info->clkEdge(); const RiseFall *clk_rf = from_clk_edge->transition(); @@ -2585,13 +2585,15 @@ Search::thruClkInfo(Path *from_path, changed = true; } - if (changed) - to_clk_info = findClkInfo(from_clk_edge, from_clk_info->clkSrc(), - to_clk_prop, gen_clk_src, - from_clk_info->isGenClkSrcPath(), - to_pulse_sense, to_insertion, to_latency, - to_uncertainties, path_ap, to_crpr_clk_path); - return to_clk_info; + if (changed) { + ClkInfo *to_clk_info = findClkInfo(from_clk_edge, from_clk_info->clkSrc(), + to_clk_prop, gen_clk_src, + from_clk_info->isGenClkSrcPath(), + to_pulse_sense, to_insertion, to_latency, + to_uncertainties, path_ap, to_crpr_clk_path); + return to_clk_info; + } + return from_clk_info; } // Find the tag for a path going from from_tag thru edge to to_pin. @@ -2785,6 +2787,20 @@ Search::setVertexArrivals(Vertex *vertex, } } +void +Search::checkPrevPaths() const +{ + VertexIterator vertex_iter(graph_); + while (vertex_iter.hasNext()) { + Vertex *vertex = vertex_iter.next(); + VertexPathIterator path_iter(vertex, graph_); + while (path_iter.hasNext()) { + Path *path = path_iter.next(); + path->checkPrevPath(this); + } + } +} + class ReportPathLess { public: