diff --git a/search/Genclks.cc b/search/Genclks.cc index 10f67951..72dc103f 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -109,7 +109,8 @@ GenclkInfo::setFoundLatchFdbkEdges(bool found) Genclks::Genclks(StaState *sta) : StaState(sta), - found_insertion_delays_(false) + found_insertion_delays_(false), + vertex_src_paths_map_(graph_) { } @@ -124,6 +125,7 @@ Genclks::clear() { found_insertion_delays_ = false; genclk_info_map_.deleteContentsClear(); + vertex_src_paths_map_.clear(); clearSrcPaths(); } @@ -846,21 +848,27 @@ Genclks::findSrcArrivals(Clock *gclk, insert_iter.visit(levelize_->maxLevel(), &arrival_visitor); } -// Copy existing generated clock source paths from vertex to tag_bldr. +// Copy generated clock source paths to tag_bldr. void Genclks::copyGenClkSrcPaths(Vertex *vertex, TagGroupBldr *tag_bldr) { - Path *paths = graph_->paths(vertex); - if (paths) { - TagGroup *tag_group = search_->tagGroup(vertex); - if (tag_group) { - for (auto const [tag, path_index] : *tag_group->pathIndexMap()) { - if (tag->isGenClkSrcPath()) { - Path &path = paths[path_index]; - tag_bldr->insertPath(path); - } + auto itr = vertex_src_paths_map_.find(vertex); + if (itr != vertex_src_paths_map_.end()) { + 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) { + Path *prev_vpath = Path::vertexPath(prev_path, this); + src_path.setPrevPath(prev_vpath); } + debugPrint(debug_, "genclk", 3, "vertex %s insert genclk %s src path %s %ss", + src_path.vertex(this)->to_string(this).c_str(), + src_path.tag(this)->genClkSrcPathClk(this)->name(), + src_path.tag(this)->pathAnalysisPt(this)->pathMinMax()->to_string().c_str(), + src_path.tag(this)->to_string(true, false, this).c_str()); + tag_bldr->insertPath(src_path); } } } @@ -941,10 +949,20 @@ Genclks::recordSrcPaths(Clock *gclk) } } } - if (!found_src_paths - // Don't warn if the master clock is ideal. - && gclk->masterClk() - && gclk->masterClk()->isPropagated()) + if (found_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); + p = p->prevPath(); + } + } + } + } + // Don't warn if the master clock is ideal. + else if (gclk->masterClk() + && gclk->masterClk()->isPropagated()) report_->warn(1062, "generated clock %s source pin %s missing paths from master clock %s.", gclk->name(), network_->pathName(gclk_pin), diff --git a/search/Genclks.hh b/search/Genclks.hh index 12e2626a..083fe28f 100644 --- a/search/Genclks.hh +++ b/search/Genclks.hh @@ -27,7 +27,7 @@ #include "Map.hh" #include "Transition.hh" #include "NetworkClass.hh" -#include "GraphClass.hh" +#include "Graph.hh" #include "SdcClass.hh" #include "SearchClass.hh" #include "StaState.hh" @@ -51,6 +51,7 @@ public: typedef Map GenclkInfoMap; typedef Map, ClockPinPairLess> GenclkSrcPathMap; +typedef std::map, VertexIdLess> VertexGenclkSrcPathsMap; class Genclks : public StaState { @@ -133,6 +134,7 @@ private: bool found_insertion_delays_; GenclkSrcPathMap genclk_src_paths_; GenclkInfoMap genclk_info_map_; + VertexGenclkSrcPathsMap vertex_src_paths_map_; }; } // namespace diff --git a/search/Search.cc b/search/Search.cc index 18bbf9ef..11434eb5 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -1408,6 +1408,7 @@ ArrivalVisitor::seedInputDelayArrival(const Pin *pin, { TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); + search_->genclks()->copyGenClkSrcPaths(vertex, &tag_bldr); search_->seedInputDelayArrival(pin, vertex, input_delay, !network_->isTopLevelPort(pin), &tag_bldr); search_->setVertexArrivals(vertex, &tag_bldr); @@ -1479,6 +1480,7 @@ Search::seedArrival(Vertex *vertex) else if (isInputArrivalSrchStart(vertex)) { TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); + genclks_->copyGenClkSrcPaths(vertex, &tag_bldr); seedInputArrival(pin, vertex, &tag_bldr); setVertexArrivals(vertex, &tag_bldr); if (!tag_bldr.empty()) @@ -1495,6 +1497,7 @@ Search::seedArrival(Vertex *vertex) network_->pathName(pin)); TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); + genclks_->copyGenClkSrcPaths(vertex, &tag_bldr); if (makeUnclkedPaths(vertex, is_reg_clk, false, &tag_bldr)) // Only search downstream if there are no false paths from here. arrival_iter_->enqueueAdjacentVertices(vertex, search_adj_); @@ -1736,6 +1739,7 @@ Search::seedInputArrival(const Pin *pin, // There can be multiple arrivals for a pin with wrt different clocks. TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); + genclks_->copyGenClkSrcPaths(vertex, &tag_bldr); InputDelaySet *input_delays = sdc_->inputDelaysLeafPin(pin); if (input_delays) { for (InputDelay *input_delay : *input_delays) { @@ -3220,7 +3224,6 @@ Search::findRequireds(Level level) seedInvalidRequireds(); int required_count = required_iter_->visitParallel(level, &req_visitor); deleteTagsPrev(); - genclks_->updateSrcPathPrevs(); requireds_exist_ = true; debugPrint(debug_, "search", 1, "found %d requireds", required_count); stats.report("Find requireds");