From e9ecb6cefb7d25ea6325227b41cdd47cda4a03d5 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 20 Jun 2025 10:24:06 -0700 Subject: [PATCH 1/7] README typo Signed-off-by: James Cherry --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbf82ce8..47db78e1 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ git clone https://github.com/parallaxsw/OpenSTA.git cd OpenSTA mkdir build cd build -cmake -DCUDD_DIR= ,. +cmake -DCUDD_DIR= .. make ``` The default build type is release to compile optimized code. From b431135550126e3ccfca9f95a0919e65c6c24aa0 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 20 Jun 2025 10:29:12 -0700 Subject: [PATCH 2/7] PropertyRegistry use string ref args Signed-off-by: James Cherry --- include/sta/Property.hh | 11 +++++------ search/Property.cc | 7 +++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/sta/Property.hh b/include/sta/Property.hh index 7e19b15c..ae94d715 100644 --- a/include/sta/Property.hh +++ b/include/sta/Property.hh @@ -46,17 +46,16 @@ template class PropertyRegistry { public: - void defineProperty(const std::string property, - std::function handler); + typedef std::function PropertyHandler; + void defineProperty(const std::string &property, + PropertyHandler handler); PropertyValue getProperty(TYPE object, - const std::string property, + const std::string &property, const char *type_name, Sta *sta); private: - std::map> registry_; + std::map registry_; }; class Properties diff --git a/search/Property.cc b/search/Property.cc index 1613e3ae..308803a9 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -1384,7 +1384,7 @@ Properties::defineProperty(std::string property, template PropertyValue PropertyRegistry::getProperty(TYPE object, - const std::string property, + const std::string &property, const char *type_name, Sta *sta) @@ -1398,9 +1398,8 @@ PropertyRegistry::getProperty(TYPE object, template void -PropertyRegistry::defineProperty(const std::string property, - std::function handler) +PropertyRegistry::defineProperty(const std::string &property, + PropertyHandler handler) { registry_[property] = handler; } From f3b785361d82824b4838def17d36637cdc4557a8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 20 Jun 2025 16:15:54 -0700 Subject: [PATCH 3/7] equiv cells only require timing arc equivs missing functions Signed-off-by: James Cherry --- include/sta/EquivCells.hh | 6 ++--- liberty/EquivCells.cc | 53 +++++++++++++++++++++++---------------- liberty/LibertyReader.cc | 9 +++++-- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/include/sta/EquivCells.hh b/include/sta/EquivCells.hh index af6c1766..2b201d2b 100644 --- a/include/sta/EquivCells.hh +++ b/include/sta/EquivCells.hh @@ -67,10 +67,10 @@ bool equivCellPorts(const LibertyCell *cell1, const LibertyCell *cell2); -// Predicate that is true when the ports and their functions match. +// Predicate that is true cell functions match. bool -equivCellPortsAndFuncs(const LibertyCell *cell1, - const LibertyCell *cell2); +equivCellFuncs(const LibertyCell *cell1, + const LibertyCell *cell2); // Predicate that is true when the timing arc sets match. bool diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index e7c2c0fd..84e57cc0 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -71,6 +71,8 @@ static unsigned hashCellPgPorts(const LibertyCell *cell); static unsigned hashPgPort(const LibertyPgPort *port); +static bool +cellHasFuncs(const LibertyCell *cell); static bool equivCellPgPorts(const LibertyCell *cell1, @@ -329,35 +331,44 @@ bool equivCells(const LibertyCell *cell1, const LibertyCell *cell2) { - return equivCellPortsAndFuncs(cell1, cell2) + return equivCellPorts(cell1, cell2) + && equivCellFuncs(cell1, cell2) && equivCellPgPorts(cell1, cell2) && equivCellSequentials(cell1, cell2) && equivCellStatetables(cell1, cell2) - && equivCellTimingArcSets(cell1, cell2); + // Reqwuire timing arc equivalence if there are no functions. + && (cellHasFuncs(cell1) + || equivCellTimingArcSets(cell1, cell2)); +} + +static bool +cellHasFuncs(const LibertyCell *cell) +{ + LibertyCellPortIterator port_iter(cell); + while (port_iter.hasNext()) { + LibertyPort *port = port_iter.next(); + if (port->function()) + return true; + } + return false; } bool -equivCellPortsAndFuncs(const LibertyCell *cell1, - const LibertyCell *cell2) +equivCellFuncs(const LibertyCell *cell1, + const LibertyCell *cell2) { - if (cell1->portCount() != cell2->portCount()) - return false; - else { - LibertyCellPortIterator port_iter1(cell1); - while (port_iter1.hasNext()) { - LibertyPort *port1 = port_iter1.next(); - const char *name = port1->name(); - LibertyPort *port2 = cell2->findLibertyPort(name); - if (!(port2 - && LibertyPort::equiv(port1, port2) - && FuncExpr::equiv(port1->function(), port2->function()) - && FuncExpr::equiv(port1->tristateEnable(), - port2->tristateEnable()))){ - return false; - } - } - return true; + LibertyCellPortIterator port_iter1(cell1); + while (port_iter1.hasNext()) { + LibertyPort *port1 = port_iter1.next(); + const char *name = port1->name(); + LibertyPort *port2 = cell2->findLibertyPort(name); + if (!(port2 + && FuncExpr::equiv(port1->function(), port2->function()) + && FuncExpr::equiv(port1->tristateEnable(), + port2->tristateEnable()))) + return false; } + return true; } bool diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 0d7e66de..06288752 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -2303,8 +2303,13 @@ void LibertyReader::checkScaledCell(LibertyGroup *group) { if (equivCellPorts(cell_, scaled_cell_owner_)) { - if (!equivCellPortsAndFuncs(cell_, scaled_cell_owner_)) - libWarn(1206, group, "scaled_cell %s, %s port functions do not match cell port functions.", + if (!equivCellPorts(cell_, scaled_cell_owner_)) + libWarn(1206, group, "scaled_cell %s, %s ports do not match cell ports", + cell_->name(), + op_cond_->name()); + if (!equivCellFuncs(cell_, scaled_cell_owner_)) + libWarn(1206, group, + "scaled_cell %s, %s port functions do not match cell port functions.", cell_->name(), op_cond_->name()); } From f8e287caf4cfd4f867eee8fde3a5230902e3d9d8 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 21 Jun 2025 14:27:05 -0700 Subject: [PATCH 4/7] Properties::defineProperty Signed-off-by: James Cherry --- include/sta/Property.hh | 45 +++++++++++++++++------------------------ search/Property.cc | 45 +++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 54 deletions(-) diff --git a/include/sta/Property.hh b/include/sta/Property.hh index ae94d715..aa9270ae 100644 --- a/include/sta/Property.hh +++ b/include/sta/Property.hh @@ -98,33 +98,24 @@ public: // [] (const Instance *, Sta *) -> PropertyValue { // return PropertyValue("bar"); // }); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); - void defineProperty(std::string property, - std::function handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); + void defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler); protected: PropertyValue portSlew(const Port *port, diff --git a/search/Property.cc b/search/Property.cc index 308803a9..3e5f740c 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -1308,73 +1308,64 @@ Properties::capacitancePropertyValue(float cap) //////////////////////////////////////////////////////////////// void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_library_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_liberty_library_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_cell_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_liberty_cell_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_port_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_liberty_port_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_instance_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_pin_.defineProperty(property, handler); } void -Properties::defineProperty(std::string property, - std::function handler) +Properties::defineProperty(std::string &property, + PropertyRegistry::PropertyHandler handler) { registry_net_.defineProperty(property, handler); } From c5b62b5cc8c65d0e734f37028e2ef4dedc9b783a Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 23 Jun 2025 08:19:27 -0700 Subject: [PATCH 5/7] liberty valgrind issues Signed-off-by: James Cherry --- liberty/FuncExpr.cc | 8 ++++++-- liberty/Liberty.cc | 4 +--- liberty/LibertyReader.cc | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/liberty/FuncExpr.cc b/liberty/FuncExpr.cc index 91139a44..67de253c 100644 --- a/liberty/FuncExpr.cc +++ b/liberty/FuncExpr.cc @@ -254,8 +254,12 @@ FuncExpr::bitSubExpr(int bit_offset) return makePort(port); } else { - LibertyPort *port = port_->findLibertyMember(bit_offset); - return makePort(port); + if (bit_offset < port_->size()) { + LibertyPort *port = port_->findLibertyMember(bit_offset); + return makePort(port); + } + else + return nullptr; } } else diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index aad0a8bd..364e5dae 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -130,15 +130,13 @@ LibertyLibrary::~LibertyLibrary() wireloads_.deleteContents(); wire_load_selections_.deleteContents(); delete units_; + // Also deletes default_ocv_derate_ ocv_derate_map_.deleteContents(); delete buffers_; delete inverters_; driver_waveform_map_.deleteContents(); delete driver_waveform_default_; - - delete default_ocv_derate_; - default_ocv_derate_ = nullptr; } LibertyCell * diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 06288752..dd730770 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -4909,7 +4909,7 @@ LibertyReader::visitWhen(LibertyAttr *attr) false, "when", attr); } } - if (timing_) { + if (timing_ && !in_ccsn_) { const char *func = getAttrString(attr); if (func) { TimingArcAttrs *attrs = timing_->attrs().get(); From 72e1c10198df7da713f7f0b4ae2742f455fa0b4f Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 23 Jun 2025 16:08:21 -0700 Subject: [PATCH 6/7] state Path::prevPath ref Signed-off-by: James Cherry --- search/Search.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/search/Search.cc b/search/Search.cc index b2bc6796..18bbf9ef 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -1276,8 +1276,7 @@ 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) - || path1->prevPath() != path2->prevPath()) + || path1->prevArc(this) != path2->prevArc(this)) return true; } return false; From 6a28a3dd52dc32d18db095ee28f006310dff63a6 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 23 Jun 2025 16:09:31 -0700 Subject: [PATCH 7/7] report -from genclk root trashes genclk src path resolves #257 commit 686dde27c31e93e17b61252226d37cb110267267 Author: James Cherry Date: Sun Jun 22 14:16:20 2025 -0700 Search::findRequireds rm Genclks::updateSrcPathPrevs Signed-off-by: James Cherry commit e1b44502bff7271fd2bf696a55cb8dead252134a Author: James Cherry Date: Sun Jun 22 10:38:49 2025 -0700 genclks copy src paths Signed-off-by: James Cherry Signed-off-by: James Cherry --- search/Genclks.cc | 48 ++++++++++++++++++++++++++++++++--------------- search/Genclks.hh | 4 +++- search/Search.cc | 5 ++++- 3 files changed, 40 insertions(+), 17 deletions(-) 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");