From 8992827b5b15e4e1eeea0d4074de64ec9a2b4ac3 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Wed, 26 Mar 2025 18:21:03 -0700 Subject: [PATCH] class Path replaces PathVertex etc commit 08c062d3dd1d0cea846407dda0b5fd75ca64329c Author: James Cherry Date: Tue Mar 25 16:17:42 2025 -0700 ApiChanges.txt Signed-off-by: James Cherry commit ef72112a00419e466e19b5c1442cac6f2835adaa Author: James Cherry Date: Sun Mar 23 12:37:10 2025 -0700 crpr29/30 Signed-off-by: James Cherry commit 2065acfbfbaa84307fde1c46ff51a1c619c45f50 Author: James Cherry Date: Sun Mar 23 12:33:55 2025 -0700 compile error Signed-off-by: James Cherry commit d3133015b90b59f7e8e934c20d1ed8449d543d7b Author: James Cherry Date: Mon Mar 17 15:20:55 2025 -0700 rebase falout Signed-off-by: James Cherry commit 8a4b81755765db823e18ffb497f1fb3f0c64ec7b Author: James Cherry Date: Mon Mar 17 09:22:01 2025 -0700 rebase fallout Signed-off-by: James Cherry commit 7ef00dcaa4ed0b6db3f4205da47013e4f2ef1049 Author: James Cherry Date: Sat Mar 15 17:00:51 2025 -0700 deleteEdge clear to path prev_paths Signed-off-by: James Cherry commit 912dacbca8f5c286f623f13659c831be6ed4d93e Author: James Cherry Date: Sat Mar 15 12:05:06 2025 -0700 undo 7f8c7adb Signed-off-by: James Cherry commit 9944c2ec907e9f07ab46f71af55ec947f3815de0 Author: James Cherry Date: Fri Mar 14 21:25:10 2025 -0700 rm Path::path() Signed-off-by: James Cherry commit a42c28b8447466a445cd8f6fb022eb42e6dcc0f2 Author: James Cherry Date: Fri Mar 14 17:12:17 2025 -0700 const Signed-off-by: James Cherry commit 3f72adf1b5ad5581adc81afd3e00be7343ae4183 Author: James Cherry Date: Fri Mar 14 17:03:04 2025 -0700 PathExpanded rm prev_arcs_ Signed-off-by: James Cherry commit 25879e66eddf9f12db38705807e1270459661810 Author: James Cherry Date: Thu Mar 13 12:34:12 2025 -0700 worst path init path Signed-off-by: James Cherry commit 5c7a4fbdf3b8823a1944074a7eb663c6ea8e32df Author: James Cherry Date: Thu Mar 13 10:47:02 2025 -0700 delete edge -> xelete paths of to vertex Signed-off-by: James Cherry commit aa8d3035489de2cd25f27f7531177193be7a40ac Author: James Cherry Date: Thu Mar 13 09:17:27 2025 -0700 debug Signed-off-by: James Cherry commit 53741b6c624b1313b0464a31e3900472d0b7c8d2 Author: James Cherry Date: Thu Mar 13 08:50:01 2025 -0700 debug Signed-off-by: James Cherry commit cdebd8f3e476e5a2afab1a949449b75dcec9ed97 Author: James Cherry Date: Thu Mar 13 08:14:58 2025 -0700 dbg network_edit Signed-off-by: James Cherry commit 60cc960439e65cda8cd244723456b81242ced458 Author: James Cherry Date: Thu Mar 13 07:42:22 2025 -0700 dbg network edit Signed-off-by: James Cherry commit f4e4264ac1c11dafddbe18971ca35127a0ffc171 Author: James Cherry Date: Tue Mar 11 19:23:17 2025 -0700 rm PathVertex.hh Signed-off-by: James Cherry commit aeba9b293f095aecd01d0f5d16de51640f3d2381 Author: James Cherry Date: Tue Mar 11 13:33:21 2025 -0700 PathEnum rm divEdge Signed-off-by: James Cherry commit ad97706562da7ceb41b9fbf4c882083de36d578d Author: James Cherry Date: Tue Mar 11 13:18:38 2025 -0700 genclks use path vector Signed-off-by: James Cherry commit a9c2563199d0cee3dee3d420c70f8117cfd69221 Author: James Cherry Date: Tue Mar 11 12:42:12 2025 -0700 group_path_count, end_path_count use size_t Signed-off-by: James Cherry commit f16309a8e09e22964b998bf1b7e0922fbb9f02c1 Author: James Cherry Date: Tue Mar 11 12:30:08 2025 -0700 Path rm uused Signed-off-by: James Cherry commit 51295613c4ab6a6a4170080252397e2846a61bf1 Author: James Cherry Date: Tue Mar 11 12:22:23 2025 -0700 network_edit3 Signed-off-by: James Cherry commit 5de6da2190460183cf07d0d4ffc1d1c6ebbe3e10 Author: James Cherry Date: Tue Mar 11 10:33:09 2025 -0700 leak Signed-off-by: James Cherry commit f52dbc18ce08bd2b14d7107b61a57e614b1e3a07 Author: James Cherry Date: Tue Mar 11 08:06:56 2025 -0700 valgrind 3 leaks left Signed-off-by: James Cherry commit de1a3727d908c4494f3039ff714ddb939d3390b5 Author: James Cherry Date: Mon Mar 10 18:21:50 2025 -0700 Path::prevPath Signed-off-by: James Cherry commit c40aadcac8d2cd6d6dd8ba18f2e9db607358a01f Author: James Cherry Date: Mon Mar 10 18:21:31 2025 -0700 clk_skew init Signed-off-by: James Cherry commit 041c97194553e7f7a4746f506be251ee42eb83ee Author: James Cherry Date: Mon Mar 10 07:38:49 2025 -0700 delete path groups before paths Signed-off-by: James Cherry commit fb4aed589f9f67ddb39f4260cb2901764cf49a98 Author: James Cherry Date: Sun Mar 9 17:23:27 2025 -0700 leak Signed-off-by: James Cherry commit 70b3062872cefdcf1358847025bc7bb1a85f4a5b Author: James Cherry Date: Sun Mar 9 17:09:45 2025 -0700 1 failure Signed-off-by: James Cherry commit 92cd7c33c1eb22e4f574a767a645c5db1c9efe4d Author: James Cherry Date: Sun Mar 9 11:19:59 2025 -0700 7 failures Signed-off-by: James Cherry commit 537ec153a5f8ab30d800cd36130e7668047b67af Author: James Cherry Date: Sun Mar 9 09:05:31 2025 -0700 11 failures Signed-off-by: James Cherry commit df514124c4daaf90175a89138ed954e20573e02f Author: James Cherry Date: Sun Mar 9 08:37:00 2025 -0700 25 failures Signed-off-by: James Cherry commit 0096e8ee5a83194aee84da2cba95f410931f5c0e Author: James Cherry Date: Sat Mar 8 16:05:04 2025 -0700 33 failures Signed-off-by: James Cherry commit 02ba7ffdf38b538cd1659df25837d37e8317e741 Author: James Cherry Date: Fri Mar 7 21:39:53 2025 -0700 delete path groups before pahts Signed-Off-by: James Cherry commit 270dbad6bc9303f9255256b5b85cac84deb27a94 Author: James Cherry Date: Fri Mar 7 18:27:52 2025 -0700 no seg faults, 42 failures Signed-off-by: James Cherry commit 3ceca5981fd6032294523cd23dc1334b9619f6a0 Author: James Cherry Date: Thu Mar 6 15:43:28 2025 -0700 multiclk1,2 seg fault Signed-off-by: James Cherry commit 0441c00dc172817cc1a39bbb740d6369cf163869 Author: James Cherry Date: Thu Mar 6 15:29:47 2025 -0700 gated_clocks15 Signed-off-by: James Cherry commit 7a1f87737e9c8247acd2c78138ee482d46123952 Author: James Cherry Date: Thu Mar 6 09:05:09 2025 -0700 nworst, crpr Signed-off-by: James Cherry commit 74b52e5ac0ed9dac5b7c31835393c4e2dd30ca95 Author: James Cherry Date: Wed Mar 5 17:18:47 2025 -0700 check_timiing6 Signed-off-by: James Cherry commit 93bddf0d940e9b833d5bc47d5af8b3bdefac67a5 Author: James Cherry Date: Wed Mar 5 17:13:24 2025 -0700 nworst10 Signed-off-by: James Cherry commit f1edddbffb2e0d23bc3f4a10733203b9756f2e2e Author: James Cherry Date: Wed Mar 5 16:22:25 2025 -0700 path enum Signed-off-by: James Cherry commit c57d241b668d305f0492e55e273b3411320692b4 Author: James Cherry Date: Wed Mar 5 16:09:11 2025 -0700 most nwost pass Signed-off-by: James Cherry commit c6fca38e28571e5f2d63236aa67233d572c3a1d6 Author: James Cherry Date: Wed Mar 5 09:15:47 2025 -0700 most genclks Signed-off-by: James Cherry commit 82f5e6e9252987433f9699919c5716b3a4321a5d Author: James Cherry Date: Tue Mar 4 17:51:29 2025 -0700 genclks Signed-off-by: James Cherry commit 19f4035496e004c543110b063482928e55bddbc9 Author: James Cherry Date: Tue Mar 4 17:33:28 2025 -0700 nworst1 Signed-off-by: James Cherry commit edafefa4e4f98291a3edebe5c7b3e2630988723f Author: James Cherry Date: Tue Mar 4 15:02:38 2025 -0700 path enum Signed-off-by: James Cherry commit 3e4684fd67eacdb474574eee9e51741e75bba907 Author: James Cherry Date: Mon Mar 3 21:07:18 2025 -0700 rm unused Path* files Signed-off-by: James Cherry commit 3f04819c01002f8b5eec0f4b8f0caf6798f3a20f Author: James Cherry Date: Mon Mar 3 19:43:35 2025 -0700 more regressions pass Signed-off-by: James Cherry commit 276d70283cda14dfd6c48d1e2e4f45d326bf286c Author: James Cherry Date: Mon Mar 3 10:43:30 2025 -0700 arrival1 Signed-off-by: James Cherry commit 383a480450833741144b57383bb40a33310fad44 Author: James Cherry Date: Sun Mar 2 19:23:40 2025 -0700 arrival1 no segfault Signed-off-by: James Cherry commit 36e3a6b8d8b19f185a5a71fb4547e17586ea2c44 Author: James Cherry Date: Sun Mar 2 18:40:23 2025 -0700 VertexPathIterator Signed-off-by: James Cherry commit 083c76201e1a5482726e5856f124b15a523453d6 Author: James Cherry Date: Sun Mar 2 18:18:15 2025 -0700 report_checks3 passes Signed-off-by: James Cherry commit 834c076b7e2cb733655d917881463c76ce6196f6 Author: James Cherry Date: Sun Mar 2 14:10:34 2025 -0800 links Signed-off-by: James Cherry commit 371792b1e6dd44ad0c72399b999d86cd2557cbe1 Author: James Cherry Date: Sun Mar 2 13:37:33 2025 -0800 link errors Signed-off-by: James Cherry commit 158e9dafa6d11e0a4fd4e7ef253b0b6cb7595bf6 Author: James Cherry Date: Sun Mar 2 12:30:29 2025 -0800 compiles Signed-off-by: James Cherry commit 8df515dab15c0744abe04eae7e4a7d7688455f03 Author: James Cherry Date: Sun Mar 2 09:41:51 2025 -0800 PathEnd compiles Signed-off-by: James Cherry commit d94f241d0803376b1526f32e4f5111d081c604af Author: James Cherry Date: Sun Mar 2 07:42:51 2025 -0800 compile progress Signed-off-by: James Cherry commit 591997e3bb496c4cc2fd6963c3798a8e17b8f587 Author: James Cherry Date: Sat Mar 1 10:42:11 2025 -0800 path unification Signed-off-by: James Cherry Signed-off-by: James Cherry --- CMakeLists.txt | 6 +- doc/ApiChanges.txt | 13 + graph/Graph.cc | 102 +---- include/sta/Graph.hh | 31 +- include/sta/Path.hh | 188 ++++++--- include/sta/PathEnd.hh | 89 +++-- include/sta/PathExpanded.hh | 26 +- include/sta/PathGroup.hh | 10 +- include/sta/PathPrev.hh | 75 ---- include/sta/PathRef.hh | 94 ----- include/sta/PathVertex.hh | 158 -------- include/sta/PathVertexPtr.hh | 63 ---- include/sta/Property.hh | 10 +- include/sta/Search.hh | 66 +++- include/sta/SearchClass.hh | 14 +- include/sta/Sta.hh | 35 +- include/sta/VisitPathEnds.hh | 2 +- power/Power.cc | 4 +- search/CheckMaxSkews.cc | 24 +- search/CheckMaxSkews.hh | 16 +- search/CheckMinPulseWidths.cc | 64 ++-- search/CheckMinPulseWidths.hh | 12 +- search/CheckSlewLimits.cc | 2 +- search/CheckTiming.cc | 4 +- search/ClkDelays.hh | 16 +- search/ClkInfo.cc | 35 +- search/ClkInfo.hh | 14 +- search/ClkLatency.cc | 22 +- search/ClkLatency.hh | 2 +- search/ClkSkew.cc | 58 +-- search/ClkSkew.hh | 2 +- search/Crpr.cc | 189 ++++------ search/Crpr.hh | 39 +- search/Genclks.cc | 138 ++++--- search/Genclks.hh | 26 +- search/Latches.cc | 68 ++-- search/Latches.hh | 30 +- search/MakeTimingModel.cc | 12 +- search/Path.cc | 591 ++++++++++++++++++++++++++--- search/PathEnd.cc | 303 +++++++-------- search/PathEnum.cc | 198 +++++----- search/PathEnum.hh | 24 +- search/PathEnumed.cc | 192 ---------- search/PathEnumed.hh | 80 ---- search/PathExpanded.cc | 110 +++--- search/PathGroup.cc | 14 +- search/PathPrev.cc | 246 ------------ search/PathRef.cc | 284 -------------- search/PathVertex.cc | 628 ------------------------------- search/PathVertexPtr.cc | 201 ---------- search/Property.cc | 42 +-- search/ReportPath.cc | 129 +++---- search/ReportPath.hh | 15 +- search/Search.cc | 467 +++++++++-------------- search/Search.i | 79 ++-- search/Search.tcl | 2 - search/Sta.cc | 90 ++--- search/Tag.cc | 19 +- search/Tag.hh | 5 +- search/TagGroup.cc | 292 +++++++------- search/TagGroup.hh | 81 ++-- search/VisitPathEnds.cc | 16 +- search/VisitPathGroupVertices.cc | 56 ++- spice/WritePathSpice.cc | 73 ++-- spice/WriteSpice.cc | 6 +- spice/WriteSpice.hh | 4 +- spice/WriteSpice.i | 2 +- tcl/Property.tcl | 2 +- tcl/StaTclTypes.i | 21 +- 69 files changed, 2148 insertions(+), 3883 deletions(-) delete mode 100644 include/sta/PathPrev.hh delete mode 100644 include/sta/PathRef.hh delete mode 100644 include/sta/PathVertex.hh delete mode 100644 include/sta/PathVertexPtr.hh delete mode 100644 search/PathEnumed.cc delete mode 100644 search/PathEnumed.hh delete mode 100644 search/PathPrev.cc delete mode 100644 search/PathRef.cc delete mode 100644 search/PathVertex.cc delete mode 100644 search/PathVertexPtr.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 530b3b0e..7b332285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,15 +184,11 @@ set(STA_SOURCE search/MakeTimingModel.cc search/Path.cc search/PathAnalysisPt.cc + search/Path.cc search/PathEnd.cc search/PathEnum.cc - search/PathEnumed.cc search/PathExpanded.cc search/PathGroup.cc - search/PathPrev.cc - search/PathRef.cc - search/PathVertex.cc - search/PathVertexPtr.cc search/Property.cc search/ReportPath.cc search/Search.cc diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt index 9dd06296..47ee5d57 100644 --- a/doc/ApiChanges.txt +++ b/doc/ApiChanges.txt @@ -24,6 +24,19 @@ This file summarizes STA API changes for each release. +Release 2.4.0 2025/03/?? +------------------------- + +The following classes have been replaced by the class Path. + PathEnumed + PathPrev + PathRef + PathVertex + PathVertexPtr + PathVertexRep + +The PathExpanded::prevArc function has been removed. Use Path::prevArc instead. + Release 2.4.0 2023/01/19 ------------------------- diff --git a/graph/Graph.cc b/graph/Graph.cc index c0961f05..65cdbf70 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -571,75 +571,25 @@ Graph::gateEdgeArc(const Pin *in_pin, //////////////////////////////////////////////////////////////// -Arrival * -Graph::makeArrivals(Vertex *vertex, - uint32_t count) +Path * +Graph::makePaths(Vertex *vertex, + uint32_t count) { - Arrival *arrivals = new Arrival[count]; - vertex->setArrivals(arrivals); - return arrivals; + Path *paths = new Path[count]; + vertex->setPaths(paths); + return paths; } -Arrival * -Graph::arrivals(const Vertex *vertex) const +Path * +Graph::paths(const Vertex *vertex) const { - return vertex->arrivals(); -} - -void -Graph::deleteArrivals(Vertex *vertex) -{ - vertex->setArrivals(nullptr); -} - -Required * -Graph::requireds(const Vertex *vertex) const -{ - return vertex->requireds(); -} - -Required * -Graph::makeRequireds(Vertex *vertex, - uint32_t count) -{ - Required *requireds = new Arrival[count]; - vertex->setRequireds(requireds); - return requireds; -} - -void -Graph::deleteRequireds(Vertex *vertex) -{ - vertex->setRequireds(nullptr); -} - -PathPrev * -Graph::prevPaths(const Vertex *vertex) const -{ - return vertex->prevPaths(); -} - -PathPrev * -Graph::makePrevPaths(Vertex *vertex, - uint32_t count) -{ - PathPrev *prev_paths = new PathPrev[count]; - vertex->setPrevPaths(prev_paths); - return prev_paths; -} - -void -Graph::deletePrevPaths(Vertex *vertex) -{ - vertex->setPrevPaths(nullptr); + return vertex->paths(); } void Graph::deletePaths(Vertex *vertex) { - deleteArrivals(vertex); - deleteRequireds(vertex); - deletePrevPaths(vertex); + vertex->setPaths(nullptr); vertex->tag_group_index_ = tag_group_index_max; vertex->crpr_path_pruning_disabled_ = false; } @@ -1007,9 +957,7 @@ Vertex::init(Pin *pin, in_edges_ = edge_id_null; out_edges_ = edge_id_null; slews_ = nullptr; - arrivals_ = nullptr; - requireds_ = nullptr; - prev_paths_ = nullptr; + paths_ = nullptr; tag_group_index_ = tag_group_index_max; slew_annotated_ = false; sim_value_ = unsigned(LogicValue::unknown); @@ -1035,12 +983,8 @@ Vertex::clear() { delete [] slews_; slews_ = nullptr; - delete [] arrivals_; - arrivals_ = nullptr; - delete [] requireds_; - requireds_ = nullptr; - delete [] prev_paths_; - prev_paths_ = nullptr; + delete [] paths_; + paths_ = nullptr; } void @@ -1153,24 +1097,10 @@ Vertex::setTagGroupIndex(TagGroupIndex tag_index) } void -Vertex::setArrivals(Arrival *arrivals) +Vertex::setPaths(Path *paths) { - delete [] arrivals_; - arrivals_ = arrivals; -} - -void -Vertex::setRequireds(Required *requireds) -{ - delete [] requireds_; - requireds_ = requireds; -} - -void -Vertex::setPrevPaths(PathPrev *prev_paths) -{ - delete [] prev_paths_; - prev_paths_ = prev_paths; + delete [] paths_; + paths_ = paths; } LogicValue diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index 4aa2313a..74058fa1 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -36,7 +36,7 @@ #include "Delay.hh" #include "GraphClass.hh" #include "VertexId.hh" -#include "PathPrev.hh" +#include "Path.hh" #include "StaState.hh" namespace sta { @@ -96,19 +96,9 @@ public: void deleteVertex(Vertex *vertex); bool hasFaninOne(Vertex *vertex) const; VertexId vertexCount() { return vertices_->size(); } - Arrival *makeArrivals(Vertex *vertex, - uint32_t count); - Arrival *arrivals(const Vertex *vertex) const; - void deleteArrivals(Vertex *vertex); - Required *makeRequireds(Vertex *vertex, - uint32_t count); - Required *requireds(const Vertex *vertex) const; - void deleteRequireds(Vertex *vertex); - PathPrev *makePrevPaths(Vertex *vertex, - uint32_t count); - PathPrev *prevPaths(const Vertex *vertex) const; - void deletePrevPaths(Vertex *vertex); - // Private to Search::deletePaths(Vertex). + Path *makePaths(Vertex *vertex, + uint32_t count); + Path *paths(const Vertex *vertex) const; void deletePaths(Vertex *vertex); // Reported slew are the same as those in the liberty tables. @@ -269,10 +259,8 @@ public: void setColor(LevelColor color); Slew *slews() { return slews_; } const Slew *slews() const { return slews_; } - Arrival *arrivals() const { return arrivals_; } - Arrival *requireds() const { return requireds_; } - PathPrev *prevPaths() const { return prev_paths_; } - void setPrevPaths(PathPrev *prev_paths); + Path *paths() const { return paths_; } + void setPaths(Path *paths); TagGroupIndex tagGroupIndex() const; void setTagGroupIndex(TagGroupIndex tag_index); // Slew is annotated by sdc set_annotated_transition cmd. @@ -311,7 +299,6 @@ public: bool isRegClk() const { return is_reg_clk_; } bool crprPathPruningDisabled() const { return crpr_path_pruning_disabled_;} void setCrprPathPruningDisabled(bool disabled); - bool hasRequireds() const { return requireds_ != nullptr; } // ObjectTable interface. ObjectIdx objectIdx() const { return object_idx_; } @@ -324,8 +311,6 @@ protected: bool is_bidirect_drvr, bool is_reg_clk); void clear(); - void setArrivals(Arrival *arrivals); - void setRequireds(Required *requireds); void setSlews(Slew *slews); Pin *pin_; @@ -335,9 +320,7 @@ protected: // Delay calc Slew *slews_; // Search - Arrival *arrivals_; - Arrival *requireds_; - PathPrev *prev_paths_; + Path *paths_; // These fields are written by multiple threads, so they // cannot share the same word as the following bit fields. diff --git a/include/sta/Path.hh b/include/sta/Path.hh index 1be09c28..7656d432 100644 --- a/include/sta/Path.hh +++ b/include/sta/Path.hh @@ -37,57 +37,96 @@ namespace sta { class DcalcAnalysisPt; -// Abstract base class for Path API. class Path { public: - Path() {} - virtual ~Path() {} - virtual const char *name(const StaState *sta) const; - virtual bool isNull() const = 0; - virtual Path *path() { return isNull() ? nullptr : this; } - virtual const Path *path() const { return isNull() ? nullptr : this; } - virtual void setRef(PathRef *ref) const = 0; - virtual void setRef(PathRef &ref) const { setRef(&ref); } - virtual Vertex *vertex(const StaState *sta) const = 0; - virtual VertexId vertexId(const StaState *sta) const = 0; - virtual Pin *pin(const StaState *sta) const; - virtual Tag *tag(const StaState *sta) const = 0; - virtual TagIndex tagIndex(const StaState *sta) const; - virtual ClkInfo *clkInfo(const StaState *sta) const; - virtual const ClockEdge *clkEdge(const StaState *sta) const; - virtual const Clock *clock(const StaState *sta) const; - virtual bool isClock(const StaState *sta) const; - virtual const RiseFall *transition(const StaState *sta) const = 0; - virtual int rfIndex(const StaState *sta) const; - virtual const MinMax *minMax(const StaState *sta) const; - virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const = 0; - virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const; - virtual DcalcAnalysisPt *dcalcAnalysisPt(const StaState *sta) const; - virtual Arrival arrival(const StaState *sta) const = 0; - virtual void setArrival(Arrival arrival, - const StaState *sta) = 0; - virtual void initArrival(const StaState *sta); - virtual bool arrivalIsInitValue(const StaState *sta) const; - virtual const Required &required(const StaState *sta) const = 0; - virtual void setRequired(const Required &required, - const StaState *sta) = 0; - virtual void initRequired(const StaState *sta); - virtual bool requiredIsInitValue(const StaState *sta) const; - virtual Slack slack(const StaState *sta) const; - virtual Slew slew(const StaState *sta) const; + Path(); + Path(Path *path); + Path(Vertex *vertex, + Tag *tag, + const StaState *sta); + Path(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta); + Path(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + bool is_enum, + const StaState *sta); + ~Path(); + const char *name(const StaState *sta) const; + bool isNull() const; + // prev_path null + void init(Vertex *vertex, + Arrival arrival, + const StaState *sta); + void init(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta); + void init(Vertex *vertex, + Tag *tag, + const StaState *sta); + void init(Vertex *vertex, + Tag *tag, + Arrival arrival, + const StaState *sta); + + Vertex *vertex(const StaState *sta) const; + VertexId vertexId(const StaState *sta) const; + Pin *pin(const StaState *sta) const; + Tag *tag(const StaState *sta) const; + TagIndex tagIndex(const StaState *sta) const; + void setTag(Tag *tag); + size_t pathIndex(const StaState *sta) const; + ClkInfo *clkInfo(const StaState *sta) const; + const ClockEdge *clkEdge(const StaState *sta) const; + const Clock *clock(const StaState *sta) const; + bool isClock(const StaState *sta) const; + const RiseFall *transition(const StaState *sta) const; + int rfIndex(const StaState *sta) const; + const MinMax *minMax(const StaState *sta) const; + PathAnalysisPt *pathAnalysisPt(const StaState *sta) const; + PathAPIndex pathAnalysisPtIndex(const StaState *sta) const; + DcalcAnalysisPt *dcalcAnalysisPt(const StaState *sta) const; + Arrival &arrival() { return arrival_; } + const Arrival &arrival() const { return arrival_; } + void setArrival(Arrival arrival); + Required &required() { return required_; } + const Required &required() const {return required_; } + void setRequired(const Required &required); + Slack slack(const StaState *sta) const; + Slew slew(const StaState *sta) const; // This takes the same time as prevPath and prevArc combined. - virtual void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const = 0; - virtual void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path) const; - virtual TimingArc *prevArc(const StaState *sta) const; - // Find the previous edge given the previous arc found above. - Edge *prevEdge(const TimingArc *prev_arc, - const StaState *sta) const; + Path *prevPath() const; + void setPrevPath(Path *prev_path); + void clearPrevPath(const StaState *sta); + TimingArc *prevArc(const StaState *sta) const; + Edge *prevEdge(const StaState *sta) const; + Vertex *prevVertex(const StaState *sta) const; + void setPrevEdgeArc(Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta); + 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); + static Path *vertexPath(const Vertex *vertex, + Tag *tag, + const StaState *sta); static bool less(const Path *path1, const Path *path2, @@ -118,6 +157,18 @@ public: static bool lessAll(const Path *path1, const Path *path2, const StaState *sta); + +protected: + Path *prev_path_; + Arrival arrival_; + Required required_; + union { + VertexId vertex_id_; + EdgeId prev_edge_id_; + }; + TagIndex tag_index_:tag_index_bit_count; + bool is_enum_:1; + unsigned prev_arc_idx_:2; }; // Compare all path attributes (vertex, transition, tag, analysis point). @@ -132,4 +183,47 @@ protected: const StaState *sta_; }; +// Iterator for paths on a vertex. +class VertexPathIterator : public Iterator +{ +public: + // Iterate over all vertex paths. + VertexPathIterator(Vertex *vertex, + const StaState *sta); + // Iterate over vertex paths with the same transition and + // analysis pt but different tags. + VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const PathAnalysisPt *path_ap, + const StaState *sta); + // Iterate over vertex paths with the same transition and + // analysis pt min/max but different tags. + VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const MinMax *min_max, + const StaState *sta); + VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const PathAnalysisPt *path_ap, + const MinMax *min_max, + const StaState *sta); + virtual ~VertexPathIterator(); + virtual bool hasNext(); + virtual Path *next(); + +private: + void findNext(); + + const Search *search_; + //bool filtered_; + const RiseFall *rf_; + const PathAnalysisPt *path_ap_; + const MinMax *min_max_; + Path *paths_; + size_t path_count_; + //size_t path_index_; + Path *next_; + PathIndexMap::Iterator path_iter_; +}; + } // namespace diff --git a/include/sta/PathEnd.hh b/include/sta/PathEnd.hh index 5491aa21..7456bcf1 100644 --- a/include/sta/PathEnd.hh +++ b/include/sta/PathEnd.hh @@ -30,7 +30,7 @@ #include "GraphClass.hh" #include "SdcClass.hh" #include "SearchClass.hh" -#include "PathRef.hh" +#include "Path.hh" #include "StaState.hh" namespace sta { @@ -73,10 +73,9 @@ public: virtual PathEnd *copy() = 0; virtual ~PathEnd(); void deletePath(); - Path *path() { return &path_; } - const Path *path() const { return &path_; } - PathRef &pathRef() { return path_; } - virtual void setPath(const Path *path); + Path *path() { return path_; } + const Path *path() const { return path_; } + virtual void setPath(Path *path); Vertex *vertex(const StaState *sta) const; const MinMax *minMax(const StaState *sta) const; // Synonym for minMax(). @@ -118,8 +117,8 @@ public: virtual float sourceClkOffset(const StaState *sta) const = 0; virtual Delay sourceClkLatency(const StaState *sta) const; virtual Delay sourceClkInsertionDelay(const StaState *sta) const; - virtual PathVertex *targetClkPath(); - virtual const PathVertex *targetClkPath() const; + virtual Path *targetClkPath(); + virtual const Path *targetClkPath() const; virtual const Clock *targetClk(const StaState *sta) const; virtual const ClockEdge *targetClkEdge(const StaState *sta) const; const RiseFall *targetClkEndTrans(const StaState *sta) const; @@ -149,7 +148,7 @@ public: virtual MultiCyclePath *multiCyclePath() const; virtual TimingArc *checkArc() const { return nullptr; } // PathEndDataCheck data clock path. - virtual const PathVertex *dataClkPath() const { return nullptr; } + virtual const Path *dataClkPath() const { return nullptr; } virtual int setupDefaultCycles() const { return 1; } virtual Delay clkSkew(const StaState *sta); virtual bool ignoreClkLatency(const StaState * /* sta */) const { return false; } @@ -173,11 +172,11 @@ public: // Helper common to multiple PathEnd classes and used // externally. // Target clock insertion delay + latency. - static Delay checkTgtClkDelay(const PathVertex *tgt_clk_path, + static Delay checkTgtClkDelay(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta); - static void checkTgtClkDelay(const PathVertex *tgt_clk_path, + static void checkTgtClkDelay(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta, @@ -186,11 +185,11 @@ public: Delay &latency); static float checkClkUncertainty(const ClockEdge *src_clk_edge, const ClockEdge *tgt_clk_edge, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, const TimingRole *check_role, const StaState *sta); // Non inter-clock uncertainty. - static float checkTgtClkUncertainty(const PathVertex *tgt_clk_path, + static float checkTgtClkUncertainty(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta); @@ -211,14 +210,14 @@ protected: static float outputDelayMargin(OutputDelay *output_delay, const Path *path, const StaState *sta); - static float pathDelaySrcClkOffset(const PathRef &path, + static float pathDelaySrcClkOffset(const Path *path, PathDelay *path_delay, Arrival src_clk_arrival, const StaState *sta); - static bool ignoreClkLatency(const PathRef &path, + static bool ignoreClkLatency(const Path *path, PathDelay *path_delay, const StaState *sta); - PathRef path_; + Path *path_; }; class PathEndUnconstrained : public PathEnd @@ -247,8 +246,8 @@ public: virtual Delay sourceClkInsertionDelay(const StaState *sta) const; virtual const Clock *targetClk(const StaState *sta) const; virtual const ClockEdge *targetClkEdge(const StaState *sta) const; - virtual PathVertex *targetClkPath(); - virtual const PathVertex *targetClkPath() const; + virtual Path *targetClkPath(); + virtual const Path *targetClkPath() const; virtual float targetClkTime(const StaState *sta) const; virtual float targetClkOffset(const StaState *sta) const; virtual Arrival targetClkArrival(const StaState *sta) const; @@ -263,13 +262,13 @@ public: virtual Slack slackNoCrpr(const StaState *sta) const; virtual int exceptPathCmp(const PathEnd *path_end, const StaState *sta) const; - virtual void setPath(const Path *path); + virtual void setPath(Path *path); protected: PathEndClkConstrained(Path *path, - PathVertex *clk_path); + Path *clk_path); PathEndClkConstrained(Path *path, - PathVertex *clk_path, + Path *clk_path, Crpr crpr, bool crpr_valid); @@ -281,7 +280,7 @@ protected: virtual Arrival targetClkArrivalNoCrpr(const StaState *sta) const; virtual Required requiredTimeNoCrpr(const StaState *sta) const; - PathVertex clk_path_; + Path *clk_path_; mutable Crpr crpr_; mutable bool crpr_valid_; }; @@ -296,10 +295,10 @@ public: protected: PathEndClkConstrainedMcp(Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp); PathEndClkConstrainedMcp(Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid); @@ -321,7 +320,7 @@ public: PathEndCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); @@ -342,7 +341,7 @@ protected: PathEndCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid); @@ -360,7 +359,7 @@ public: PathEndLatchCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *disable_path, + Path *disable_path, MultiCyclePath *mcp, PathDelay *path_delay, const StaState *sta); @@ -371,8 +370,8 @@ public: virtual bool isLatchCheck() const { return true; } virtual PathDelay *pathDelay() const { return path_delay_; } virtual PathEnd *copy(); - PathVertex *latchDisable(); - const PathVertex *latchDisable() const; + Path *latchDisable(); + const Path *latchDisable() const; virtual void reportShort(const ReportPath *report) const; virtual void reportFull(const ReportPath *report) const; virtual TimingRole *checkRole(const StaState *sta) const; @@ -403,8 +402,8 @@ protected: PathEndLatchCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, - PathVertex *disable, + Path *clk_path, + Path *disable, MultiCyclePath *mcp, PathDelay *path_delay, Delay src_clk_arrival, @@ -412,7 +411,7 @@ protected: bool crpr_valid); private: - PathVertex disable_path_; + Path *disable_path_; PathDelay *path_delay_; // Source clk arrival for set_max_delay -ignore_clk_latency. Arrival src_clk_arrival_; @@ -426,7 +425,7 @@ class PathEndOutputDelay : public PathEndClkConstrainedMcp public: PathEndOutputDelay(OutputDelay *output_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); @@ -448,7 +447,7 @@ public: protected: PathEndOutputDelay(OutputDelay *output_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid); @@ -470,7 +469,7 @@ class PathEndGatedClock : public PathEndClkConstrainedMcp { public: PathEndGatedClock(Path *gating_ref, - PathVertex *clk_path, + Path *clk_path, TimingRole *check_role, MultiCyclePath *mcp, ArcDelay margin, @@ -488,7 +487,7 @@ public: protected: PathEndGatedClock(Path *gating_ref, - PathVertex *clk_path, + Path *clk_path, TimingRole *check_role, MultiCyclePath *mcp, ArcDelay margin, @@ -504,7 +503,7 @@ class PathEndDataCheck : public PathEndClkConstrainedMcp public: PathEndDataCheck(DataCheck *check, Path *data_path, - PathVertex *data_clk_path, + Path *data_clk_path, MultiCyclePath *mcp, const StaState *sta); virtual PathEnd *copy(); @@ -518,26 +517,24 @@ public: virtual ArcDelay margin(const StaState *sta) const; virtual int exceptPathCmp(const PathEnd *path_end, const StaState *sta) const; - virtual const PathVertex *dataClkPath() const { return &data_clk_path_; } + virtual const Path *dataClkPath() const { return data_clk_path_; } protected: PathEndDataCheck(DataCheck *check, Path *data_path, - PathVertex *data_clk_path, - PathVertex *clk_path, + Path *data_clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid); - void clkPath(PathVertex *path, - const StaState *sta, - // Return value. - PathVertex &clk_path); + Path *clkPath(Path *path, + const StaState *sta); Arrival requiredTimeNoCrpr(const StaState *sta) const; // setup uses zero cycle default virtual int setupDefaultCycles() const { return 0; } private: - PathVertex data_clk_path_; + Path *data_clk_path_; DataCheck *check_; }; @@ -554,7 +551,7 @@ public: // Path delay to timing check. PathEndPathDelay(PathDelay *path_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, TimingArc *check_arc, Edge *check_edge, const StaState *sta); @@ -588,7 +585,7 @@ public: protected: PathEndPathDelay(PathDelay *path_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, TimingArc *check_arc, Edge *check_edge, OutputDelay *output_delay, diff --git a/include/sta/PathExpanded.hh b/include/sta/PathExpanded.hh index 1abf7ae4..784409bf 100644 --- a/include/sta/PathExpanded.hh +++ b/include/sta/PathExpanded.hh @@ -27,7 +27,7 @@ #include "TimingArc.hh" #include "GraphClass.hh" #include "SearchClass.hh" -#include "PathRef.hh" +#include "Path.hh" #include "StaState.hh" namespace sta { @@ -48,33 +48,31 @@ public: size_t size() const { return paths_.size(); } // path(0) is the startpoint. // path(size()-1) is the endpoint. - const PathRef *path(size_t index) const; - TimingArc *prevArc(size_t index) const; + const Path *path(size_t index) const; // Returns the path start point. // Register/Latch Q pin // Input pin - const PathRef *startPath() const; - const PathRef *startPrevPath() const; - const PathRef *endPath() const; - TimingArc *startPrevArc() const; + const Path *startPath() const; + const Path *startPrevPath() const; + const Path *endPath() const; + const TimingArc *startPrevArc() const; size_t startIndex() const; - void clkPath(PathRef &clk_path) const; + const Path *clkPath() const; void latchPaths(// Return values. - const PathRef *&d_path, - const PathRef *&q_path, + const Path *&d_path, + const Path *&q_path, Edge *&d_q_edge) const; protected: - void expandGenclk(PathRef *clk_path); + void expandGenclk(const Path *clk_path); // Convert external index that starts at the path root // and increases to an index for paths_ (reversed). size_t pathsIndex(size_t index) const; - // The PathRefs in paths_ are in reverse order. + // The Paths in paths_ are in reverse order. // paths_[0] is the endpoint. // paths_[size-1] is the beginning of the path. - PathRefSeq paths_; - TimingArcSeq prev_arcs_; + ConstPathSeq paths_; // Index of the startpoint. size_t start_index_; const StaState *sta_; diff --git a/include/sta/PathGroup.hh b/include/sta/PathGroup.hh index f60bfea7..bb26b89e 100644 --- a/include/sta/PathGroup.hh +++ b/include/sta/PathGroup.hh @@ -74,12 +74,12 @@ public: PathGroupIterator *iterator(); // This does NOT delete the path ends. void clear(); - static int group_path_count_max; + static size_t group_path_count_max; protected: PathGroup(const char *name, - int group_path_count, - int endpoint_path_count, + size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, float min_slack, float max_slack, @@ -91,8 +91,8 @@ protected: void sort(); const char *name_; - int group_path_count_; - int endpoint_path_count_; + size_t group_path_count_; + size_t endpoint_path_count_; bool unique_pins_; float slack_min_; float slack_max_; diff --git a/include/sta/PathPrev.hh b/include/sta/PathPrev.hh deleted file mode 100644 index 3643bef1..00000000 --- a/include/sta/PathPrev.hh +++ /dev/null @@ -1,75 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include "SdcClass.hh" -#include "SearchClass.hh" - -namespace sta { - -// "Pointer" to a previous path on a vertex (PathVertex) thru an edge/arc. -class PathPrev -{ -public: - PathPrev(); - PathPrev(const PathVertex *path, - const Edge *prev_edge, - const TimingArc *prev_arc, - const StaState *sta); - void init(); - void init(const PathPrev *path); - void init(const PathPrev &path); - void init(const PathVertex *path, - const Edge *prev_edge, - const TimingArc *prev_arc, - const StaState *sta); - bool isNull() const; - const char *name(const StaState *sta) const; - Vertex *vertex(const StaState *sta) const; - VertexId vertexId(const StaState *sta) const; - Edge *prevEdge(const StaState *sta) const; - TimingArc *prevArc(const StaState *sta) const; - Tag *tag(const StaState *sta) const; - TagIndex tagIndex() const { return prev_tag_index_; } - Arrival arrival(const StaState *sta) const; - void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const; - - static bool equal(const PathPrev *path1, - const PathPrev *path2); - static bool equal(const PathPrev &path1, - const PathPrev &path2); - static int cmp(const PathPrev &path1, - const PathPrev &path2); - -protected: - EdgeId prev_edge_id_; - TagIndex prev_tag_index_:tag_index_bit_count; - unsigned prev_arc_idx_:2; -}; - -} // namespace diff --git a/include/sta/PathRef.hh b/include/sta/PathRef.hh deleted file mode 100644 index 50288e28..00000000 --- a/include/sta/PathRef.hh +++ /dev/null @@ -1,94 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include "Vector.hh" -#include "SearchClass.hh" -#include "Path.hh" -#include "PathVertex.hh" - -namespace sta { - -// Path reference to either a PathVertex or PathEnum. -// This "could" be made smaller by using a union for -// path_vertex_.vertex_ and path_enumed_ and a non-legal -// value for path_vertex_.arrival_index_ (because a nullptr tag -// in PathVertex is valid). -class PathRef : public Path -{ -public: - PathRef(); - PathRef(const Path *path); - PathRef(const PathRef &path); - PathRef(const PathRef *path); - PathRef(const PathVertex &path); - void init(); - void init(const PathRef &path); - void init(const PathRef *path); - void init(const PathVertex &path); - void init(const PathVertex *path); - void init(const PathPrev &path, - const StaState *sta); - void init(Vertex *vertex, - Tag *tag, - int arrival_index); - void init(PathEnumed *path); - virtual void setRef(PathRef *ref) const; - virtual bool isNull() const; - virtual Vertex *vertex(const StaState *sta) const; - virtual VertexId vertexId(const StaState *sta) const; - virtual Tag *tag(const StaState *sta) const; - virtual TagIndex tagIndex(const StaState *sta) const; - virtual const RiseFall *transition(const StaState *sta) const; - virtual int rfIndex(const StaState *sta) const; - virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const; - virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const; - void arrivalIndex(int &arrival_index, - bool &arrival_exists) const; - virtual Arrival arrival(const StaState *sta) const; - virtual void setArrival(Arrival arrival, - const StaState *sta); - virtual const Required &required(const StaState *sta) const; - virtual void setRequired(const Required &required, - const StaState *sta); - virtual void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const; - void deleteRep(); - - using Path::setRef; - using Path::prevPath; - -protected: - PathVertex path_vertex_; - PathEnumed *path_enumed_; - -private: - friend class PathVertex; - friend class PathEnumed; -}; - -} // namespace diff --git a/include/sta/PathVertex.hh b/include/sta/PathVertex.hh deleted file mode 100644 index 9d21140f..00000000 --- a/include/sta/PathVertex.hh +++ /dev/null @@ -1,158 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include "SearchClass.hh" -#include "Path.hh" - -namespace sta { - -class PathPrev; -class PathVertexPtr; - -// Implements Path API for a vertex. -class PathVertex : public Path -{ -public: - PathVertex(); - PathVertex(const PathVertex &path); - PathVertex(const PathVertex *path); - PathVertex(const PathPrev *path, - const StaState *sta); - PathVertex(const PathPrev &path, - const StaState *sta); - PathVertex(const PathVertexPtr &path, - const StaState *sta); - // If tag is not in the vertex tag group isNull() is true. - PathVertex(Vertex *vertex, - Tag *tag, - const StaState *sta); - PathVertex(Vertex *vertex, - Tag *tag, - int arrival_index); - void init(); - void init(const PathPrev *path, - const StaState *sta); - void init(const PathPrev &path, - const StaState *sta); - void init(const PathVertexPtr &path, - const StaState *sta); - void init(Vertex *vertex, - Tag *tag, - const StaState *sta); - void init(Vertex *vertex, - Tag *tag, - int arrival_index); - void operator=(const PathVertex &path); - virtual bool isNull() const; - virtual void setRef(PathRef *ref) const; - virtual Vertex *vertex(const StaState *) const { return vertex_; } - virtual VertexId vertexId(const StaState *sta) const; - virtual Tag *tag(const StaState *) const { return tag_; } - virtual TagIndex tagIndex(const StaState *sta) const; - virtual const RiseFall *transition(const StaState *) const; - virtual int rfIndex(const StaState *sta) const; - virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const; - virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const; - void arrivalIndex(int &arrival_index, - bool &arrival_exists) const; - void setArrivalIndex(int arrival_index); - virtual Arrival arrival(const StaState *sta) const; - virtual void setArrival(Arrival arrival, - const StaState *sta); - virtual const Required &required(const StaState *sta) const; - virtual void setRequired(const Required &required, - const StaState *sta); - virtual void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const; - void prevPath(const StaState *sta, - // Return values. - PathVertex &prev_path) const; - void prevPath(const StaState *sta, - // Return values. - PathVertex &prev_path, - TimingArc *&prev_arc) const; - static bool equal(const PathVertex *path1, - const PathVertex *path2); - - using Path::setRef; - using Path::prevPath; - -protected: - Vertex *vertex_; - Tag *tag_; - int arrival_index_; - -private: - friend class PathRef; - friend class VertexPathIterator; - friend bool pathVertexEqual(const PathVertex *path1, - const PathVertex *path2); -}; - -// Iterator for vertex paths. -class VertexPathIterator : public Iterator -{ -public: - // Iterate over all vertex paths. - VertexPathIterator(Vertex *vertex, - const StaState *sta); - // Iterate over vertex paths with the same transition and - // analysis pt but different tags. - VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const PathAnalysisPt *path_ap, - const StaState *sta); - // Iterate over vertex paths with the same transition and - // analysis pt min/max but different tags. - VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max, - const StaState *sta); - VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const PathAnalysisPt *path_ap, - const MinMax *min_max, - const StaState *sta); - virtual ~VertexPathIterator(); - virtual bool hasNext(); - virtual PathVertex *next(); - -private: - void findNext(); - - const Search *search_; - Vertex *vertex_; - const RiseFall *rf_; - const PathAnalysisPt *path_ap_; - const MinMax *min_max_; - ArrivalMap::Iterator arrival_iter_; - PathVertex path_; - PathVertex next_; -}; - -} // namespace diff --git a/include/sta/PathVertexPtr.hh b/include/sta/PathVertexPtr.hh deleted file mode 100644 index 80c89649..00000000 --- a/include/sta/PathVertexPtr.hh +++ /dev/null @@ -1,63 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include "SearchClass.hh" - -namespace sta { - -// "Pointer" to a vertex path because there is no real path object to point to. -class PathVertexPtr -{ -public: - PathVertexPtr(); - PathVertexPtr(const PathVertex *path, - const StaState *sta); - void init(); - void init(const PathVertexPtr *path); - void init(const PathVertexPtr &path); - void init(const PathVertex *path, - const StaState *sta); - bool isNull() const; - const char *name(const StaState *sta) const; - Vertex *vertex(const StaState *sta) const; - VertexId vertexId() const { return vertex_id_; } - Tag *tag(const StaState *sta) const; - TagIndex tagIndex() const { return tag_index_; } - Arrival arrival(const StaState *sta) const; - - static bool equal(const PathVertexPtr *path1, - const PathVertexPtr *path2); - static bool equal(const PathVertexPtr &path1, - const PathVertexPtr &path2); - static int cmp(const PathVertexPtr &path1, - const PathVertexPtr &path2); - -protected: - VertexId vertex_id_; - TagIndex tag_index_; -}; - -} // namespace diff --git a/include/sta/Property.hh b/include/sta/Property.hh index c795ed80..3b175c72 100644 --- a/include/sta/Property.hh +++ b/include/sta/Property.hh @@ -55,7 +55,7 @@ public: type_library, type_cell, type_port, type_liberty_library, type_liberty_cell, type_liberty_port, type_instance, type_pin, type_pins, type_net, - type_clk, type_clks, type_path_refs, type_pwr_activity }; + type_clk, type_clks, type_paths, type_pwr_activity }; PropertyValue(); PropertyValue(const char *value); PropertyValue(string &value); @@ -77,7 +77,7 @@ public: PropertyValue(const Clock *value); PropertyValue(ClockSeq *value); PropertyValue(ClockSet *value); - PropertyValue(PathRefSeq *value); + PropertyValue(ConstPathSeq *value); PropertyValue(PwrActivity *value); // Copy constructor. PropertyValue(const PropertyValue &props); @@ -103,7 +103,7 @@ public: const Net *net() const { return net_; } const Clock *clock() const { return clk_; } ClockSeq *clocks() const { return clks_; } - PathRefSeq *pathRefs() const { return path_refs_; } + ConstPathSeq *paths() const { return paths_; } PwrActivity pwrActivity() const { return pwr_activity_; } // Copy assignment. @@ -129,7 +129,7 @@ private: const Net *net_; const Clock *clk_; ClockSeq *clks_; - PathRefSeq *path_refs_; + ConstPathSeq *paths_; PwrActivity pwr_activity_; }; const Unit *unit_; @@ -196,7 +196,7 @@ getProperty(PathEnd *end, Sta *sta); PropertyValue -getProperty(PathRef *end, +getProperty(Path *end, const char *property, Sta *sta); diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 312c6514..8129ae4f 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -1,4 +1,4 @@ -// OpenSTA, Static Timing Analyzer +// opensta, Static Timing Analyzer // Copyright (c) 2025, Parallax Software, Inc. // // This program is free software: you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include "SearchClass.hh" #include "SearchPred.hh" #include "VertexVisitor.hh" +#include "Path.hh" namespace sta { @@ -99,8 +100,8 @@ public: bool unconstrained, const Corner *corner, const MinMaxAll *min_max, - int group_path_count, - int endpoint_path_count, + size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, float slack_min, float slack_max, @@ -126,6 +127,7 @@ public: void requiredInvalid(const Pin *pin); // Vertex will be deleted. void deleteVertexBefore(Vertex *vertex); + void deleteEdgeBefore(Edge *edge); // Find all arrival times (propatating thru latches). void findAllArrivals(); // Find all arrivals (without latch propagation). @@ -226,7 +228,7 @@ public: TagIndex tagCount() const; TagGroupIndex tagGroupCount() const; void reportTagGroups() const; - void reportArrivalCountHistogram() const; + void reportPathCountHistogram() const; virtual int clkInfoCount() const; virtual bool isEndpoint(Vertex *vertex) const; virtual bool isEndpoint(Vertex *vertex, @@ -252,7 +254,7 @@ public: const RiseFall *to_rf, const MinMax *min_max, const PathAnalysisPt *path_ap); - Tag *thruClkTag(PathVertex *from_path, + Tag *thruClkTag(Path *from_path, Vertex *from_vertex, Tag *from_tag, bool to_propagates_clk, @@ -261,7 +263,7 @@ public: bool arc_delay_min_max_eq, const MinMax *min_max, const PathAnalysisPt *path_ap); - ClkInfo *thruClkInfo(PathVertex *from_path, + ClkInfo *thruClkInfo(Path *from_path, Vertex *from_vertex, ClkInfo *from_clk_info, bool from_is_clk, @@ -273,7 +275,7 @@ public: const MinMax *min_max, const PathAnalysisPt *path_ap); ClkInfo *clkInfoWithCrprClkPath(ClkInfo *from_clk_info, - PathVertex *from_path, + Path *from_path, const PathAnalysisPt *path_ap); void seedClkArrivals(const Pin *pin, Vertex *vertex, @@ -339,7 +341,7 @@ public: float latency, ClockUncertainties *uncertainties, const PathAnalysisPt *path_ap, - PathVertex *crpr_clk_path); + Path *crpr_clk_path); ClkInfo *findClkInfo(const ClockEdge *clk_edge, const Pin *clk_src, bool is_propagated, @@ -378,7 +380,33 @@ public: bool unconstrained, bool thru_latches); VertexSeq filteredEndpoints(); - bool alwaysSavePrevPaths() const { return always_save_prev_paths_; } + + Arrival *arrivals(const Vertex *vertex) const; + Arrival *makeArrivals(const Vertex *vertex, + uint32_t count); + void deleteArrivals(const Vertex *vertex); + Required *requireds(const Vertex *vertex) const; + bool hasRequireds(const Vertex *vertex) const; + Required *makeRequireds(const Vertex *vertex, + uint32_t count); + void deleteRequireds(const Vertex *vertex); + size_t arrivalCount() const; + size_t requiredCount() const; + Path *prevPaths(const Vertex *vertex) const; + Path *makePrevPaths(const Vertex *vertex, + uint32_t count); + void deletePrevPaths(Vertex *vertex); + bool crprPathPruningDisabled(const Vertex *vertex) const; + void setCrprPathPruningDisabled(const Vertex *vertex, + bool disabled); + bool bfsInQueue(const Vertex *vertex, + BfsIndex index) const; + void setBfsInQueue(const Vertex *vertex, + BfsIndex index, + bool value); + TagGroupIndex tagGroupIndex(const Vertex *vertex) const; + void setTagGroupIndex(const Vertex *vertex, + TagGroupIndex tag_index); protected: void init(StaState *sta); @@ -544,7 +572,8 @@ protected: void tnsNotifyBefore(Vertex *vertex); bool matchesFilterTo(Path *path, const ClockEdge *to_clk_edge) const; - PathRef pathClkPathArrival1(const Path *path) const; + const Path *pathClkPathArrival1(const Path *path) const; + void deletePathsState(const Vertex *vertex) const; void clocks(const Vertex *vertex, // Return value. ClockSet &clks) const; @@ -619,7 +648,6 @@ protected: std::mutex pending_latch_outputs_lock_; VertexSet *endpoints_; VertexSet *invalid_endpoints_; - bool always_save_prev_paths_; // Filter exception to tag arrivals for // report_timing -from pin|inst -through. // -to is always nullptr. @@ -682,7 +710,7 @@ protected: bool visitArc(const Pin *from_pin, Vertex *from_vertex, const RiseFall *from_rf, - PathVertex *from_path, + Path *from_path, Edge *edge, TimingArc *arc, const Pin *to_pin, @@ -694,7 +722,7 @@ protected: virtual bool visitFromPath(const Pin *from_pin, Vertex *from_vertex, const RiseFall *from_rf, - PathVertex *from_path, + Path *from_path, Edge *edge, TimingArc *arc, const Pin *to_pin, @@ -707,7 +735,7 @@ protected: Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, @@ -740,7 +768,7 @@ public: Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, @@ -781,14 +809,14 @@ public: RequiredCmp(); void requiredsInit(Vertex *vertex, const StaState *sta); - void requiredSet(int arrival_index, - Required required, + void requiredSet(size_t path_index, + Required &required, const MinMax *min_max, const StaState *sta); // Return true if the requireds changed. bool requiredsSave(Vertex *vertex, const StaState *sta); - Required required(int arrival_index); + Required required(size_t path_index); protected: ArrivalSeq requireds_; @@ -811,7 +839,7 @@ protected: Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, diff --git a/include/sta/SearchClass.hh b/include/sta/SearchClass.hh index ac558426..39c516f3 100644 --- a/include/sta/SearchClass.hh +++ b/include/sta/SearchClass.hh @@ -41,12 +41,6 @@ namespace sta { class Search; class Corner; class Path; -class PathRep; -class PathVertex; -class PathPrev; -class PathVertexPtr; -class PathRef; -class PathEnumed; class PathEnd; class PathGroup; class Tag; @@ -120,12 +114,12 @@ typedef Vector MaxSkewCheckSeq; typedef StringSet PathGroupNameSet; typedef Vector PathEndSeq; typedef Vector ArrivalSeq; -typedef Map VertexPathCountMap; -typedef UnorderedMap ArrivalMap; -typedef Vector PathVertexSeq; +typedef Map VertexPathCountMap; +typedef UnorderedMap PathIndexMap; typedef Vector SlackSeq; typedef Delay Crpr; -typedef Vector PathRefSeq; +typedef Vector PathSeq; +typedef vector ConstPathSeq; enum class ReportPathFormat { full, full_clock, diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 48df74b8..61b0b66e 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1000,21 +1000,21 @@ public: VertexPathIterator *vertexPathIterator(Vertex *vertex, const RiseFall *rf, const MinMax *min_max); - PathRef vertexWorstArrivalPath(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max); - PathRef vertexWorstArrivalPath(Vertex *vertex, - const MinMax *min_max); - PathRef vertexWorstRequiredPath(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max); - PathRef vertexWorstRequiredPath(Vertex *vertex, - const MinMax *min_max); - PathRef vertexWorstSlackPath(Vertex *vertex, - const MinMax *min_max); - PathRef vertexWorstSlackPath(Vertex *vertex, + Path *vertexWorstArrivalPath(Vertex *vertex, const RiseFall *rf, const MinMax *min_max); + Path *vertexWorstArrivalPath(Vertex *vertex, + const MinMax *min_max); + Path *vertexWorstRequiredPath(Vertex *vertex, + const RiseFall *rf, + const MinMax *min_max); + Path *vertexWorstRequiredPath(Vertex *vertex, + const MinMax *min_max); + Path *vertexWorstSlackPath(Vertex *vertex, + const MinMax *min_max); + Path *vertexWorstSlackPath(Vertex *vertex, + const RiseFall *rf, + const MinMax *min_max); // Find the min clock period for rise/rise and fall/fall paths of a clock // using the slack. This does NOT correctly predict min period when there @@ -1112,10 +1112,9 @@ public: TagIndex tagCount() const; TagGroupIndex tagGroupCount() const; int clkInfoCount() const; - int arrivalCount() const; - int requiredCount() const; - int vertexArrivalCount(Vertex *vertex) const; - Vertex *maxArrivalCountVertex() const; + int pathCount() const; + int vertexPathCount(Vertex *vertex) const; + Vertex *maxPathCountVertex() const; LogicValue simLogicValue(const Pin *pin); // Propagate liberty constant functions and pins tied high/low through @@ -1314,7 +1313,7 @@ public: LibertyLibrarySeq *map_libs); LibertyCellSeq *equivCells(LibertyCell *cell); - void writePathSpice(PathRef *path, + void writePathSpice(Path *path, const char *spice_filename, const char *subckt_filename, const char *lib_subckt_filename, diff --git a/include/sta/VisitPathEnds.hh b/include/sta/VisitPathEnds.hh index c91b117d..1661c140 100644 --- a/include/sta/VisitPathEnds.hh +++ b/include/sta/VisitPathEnds.hh @@ -85,7 +85,7 @@ protected: Path *path, const RiseFall *end_rf, const ClockEdge *tgt_clk_edge, - PathVertex *ref_path, + Path *ref_path, const MinMax *min_max, PathEndVisitor *visitor, bool &is_constrained); diff --git a/power/Power.cc b/power/Power.cc index cd564c3f..602942fd 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -50,7 +50,7 @@ #include "DcalcAnalysisPt.hh" #include "GraphDelayCalc.hh" #include "Corner.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "search/Levelize.hh" #include "search/Sim.hh" #include "Search.hh" @@ -1339,7 +1339,7 @@ Power::findClk(const Pin *to_pin) if (to_vertex) { VertexPathIterator path_iter(to_vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const Clock *path_clk = path->clock(this); if (path_clk && (clk == nullptr diff --git a/search/CheckMaxSkews.cc b/search/CheckMaxSkews.cc index e2da8420..51816c25 100644 --- a/search/CheckMaxSkews.cc +++ b/search/CheckMaxSkews.cc @@ -30,7 +30,7 @@ #include "Network.hh" #include "Graph.hh" #include "Clock.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "PathAnalysisPt.hh" #include "Search.hh" @@ -199,13 +199,13 @@ CheckMaxSkews:: visitMaxSkewChecks(Vertex *vertex, RiseFall *ref_rf = arc->toEdge()->asRiseFall(); VertexPathIterator clk_path_iter(vertex, clk_rf, clk_min_max, search); while (clk_path_iter.hasNext()) { - PathVertex *clk_path = clk_path_iter.next(); + Path *clk_path = clk_path_iter.next(); if (clk_path->isClock(search)) { const PathAnalysisPt *clk_ap = clk_path->pathAnalysisPt(sta_); PathAnalysisPt *ref_ap = clk_ap->tgtClkAnalysisPt(); VertexPathIterator ref_path_iter(ref_vertex, ref_rf, ref_ap, sta_); while (ref_path_iter.hasNext()) { - PathVertex *ref_path = ref_path_iter.next(); + Path *ref_path = ref_path_iter.next(); if (ref_path->isClock(search)) { MaxSkewCheck check(clk_path, ref_path, arc, edge); visitor->visit(check, sta_); @@ -220,8 +220,8 @@ CheckMaxSkews:: visitMaxSkewChecks(Vertex *vertex, //////////////////////////////////////////////////////////////// -MaxSkewCheck::MaxSkewCheck(PathVertex *clk_path, - PathVertex *ref_path, +MaxSkewCheck::MaxSkewCheck(Path *clk_path, + Path *ref_path, TimingArc *check_arc, Edge *check_edge) : clk_path_(clk_path), @@ -234,34 +234,34 @@ MaxSkewCheck::MaxSkewCheck(PathVertex *clk_path, Pin * MaxSkewCheck::clkPin(const StaState *sta) const { - return clk_path_.pin(sta); + return clk_path_->pin(sta); } Pin * MaxSkewCheck::refPin(const StaState *sta) const { - return ref_path_.pin(sta); + return ref_path_->pin(sta); } ArcDelay MaxSkewCheck::maxSkew(const StaState *sta) const { Search *search = sta->search(); - return search->deratedDelay(ref_path_.vertex(sta), + return search->deratedDelay(ref_path_->vertex(sta), check_arc_, check_edge_, false, - clk_path_.pathAnalysisPt(sta)); + clk_path_->pathAnalysisPt(sta)); } Delay -MaxSkewCheck::skew(const StaState *sta) const +MaxSkewCheck::skew() const { - return Delay(clk_path_.arrival(sta) - ref_path_.arrival(sta)); + return Delay(clk_path_->arrival() - ref_path_->arrival()); } Slack MaxSkewCheck::slack(const StaState *sta) const { - return maxSkew(sta) - skew(sta); + return maxSkew(sta) - skew(); } //////////////////////////////////////////////////////////////// diff --git a/search/CheckMaxSkews.hh b/search/CheckMaxSkews.hh index 3fd937f5..4f40ffbb 100644 --- a/search/CheckMaxSkews.hh +++ b/search/CheckMaxSkews.hh @@ -28,7 +28,7 @@ #include "Delay.hh" #include "StaState.hh" #include "SearchClass.hh" -#include "PathRef.hh" +#include "Path.hh" namespace sta { @@ -57,22 +57,22 @@ protected: class MaxSkewCheck { public: - MaxSkewCheck(PathVertex *clk_path, - PathVertex *ref_path, + MaxSkewCheck(Path *clk_path, + Path *ref_path, TimingArc *check_arc, Edge *check_edge); - const PathVertex *clkPath() const { return &clk_path_; } + const Path *clkPath() const { return clk_path_; } Pin *clkPin(const StaState *sta) const; - const PathVertex *refPath() const { return &ref_path_; } + const Path *refPath() const { return ref_path_; } Pin *refPin(const StaState *sta) const; - Delay skew(const StaState *sta) const; + Delay skew() const; ArcDelay maxSkew(const StaState *sta) const; Slack slack(const StaState *sta) const; TimingArc *checkArc() const { return check_arc_; } private: - PathVertex clk_path_; - PathVertex ref_path_; + Path *clk_path_; + Path *ref_path_; TimingArc *check_arc_; Edge *check_edge_; }; diff --git a/search/CheckMinPulseWidths.cc b/search/CheckMinPulseWidths.cc index eb4821a4..f5f2d23c 100644 --- a/search/CheckMinPulseWidths.cc +++ b/search/CheckMinPulseWidths.cc @@ -35,8 +35,7 @@ #include "GraphDelayCalc.hh" #include "ClkInfo.hh" #include "Tag.hh" -#include "PathVertex.hh" -#include "PathRef.hh" +#include "Path.hh" #include "Corner.hh" #include "PathAnalysisPt.hh" #include "SearchPred.hh" @@ -275,10 +274,9 @@ visitMinPulseWidthChecks(Vertex *vertex, minPulseWidth(path, sta_, min_width, exists); if (exists) { MinPulseWidthCheck check(path); - PathVertex close_path; - check.closePath(sta_, close_path); + Path *close_path = check.closePath(sta_); // Don't bother visiting if nobody is home. - if (!close_path.isNull()) + if (close_path) visitor->visit(check, sta_); } } @@ -289,7 +287,7 @@ visitMinPulseWidthChecks(Vertex *vertex, //////////////////////////////////////////////////////////////// MinPulseWidthCheck::MinPulseWidthCheck() : - open_path_() + open_path_(nullptr) { } @@ -301,31 +299,29 @@ MinPulseWidthCheck::MinPulseWidthCheck(Path *open_path) : MinPulseWidthCheck * MinPulseWidthCheck::copy() { - return new MinPulseWidthCheck(&open_path_); + return new MinPulseWidthCheck(open_path_); } Pin * MinPulseWidthCheck::pin(const StaState *sta) const { - return open_path_.pin(sta); + return open_path_->pin(sta); } const RiseFall * MinPulseWidthCheck::openTransition(const StaState *sta) const { - return open_path_.transition(sta); + return open_path_->transition(sta); } -void -MinPulseWidthCheck::closePath(const StaState *sta, - // Return value. - PathVertex &close) const +Path * +MinPulseWidthCheck::closePath(const StaState *sta) const { - PathAnalysisPt *open_ap = open_path_.pathAnalysisPt(sta); + PathAnalysisPt *open_ap = open_path_->pathAnalysisPt(sta); PathAnalysisPt *close_ap = open_ap->tgtClkAnalysisPt(); - const RiseFall *open_rf = open_path_.transition(sta); + const RiseFall *open_rf = open_path_->transition(sta); const RiseFall *close_rf = open_rf->opposite(); - Tag *open_tag = open_path_.tag(sta); + Tag *open_tag = open_path_->tag(sta); ClkInfo *open_clk_info = open_tag->clkInfo(); ClkInfo close_clk_info(open_clk_info->clkEdge()->opposite(), open_clk_info->clkSrc(), @@ -335,7 +331,7 @@ MinPulseWidthCheck::closePath(const StaState *sta, open_clk_info->pulseClkSense(), delay_zero, 0.0, nullptr, open_clk_info->pathAPIndex(), - open_clk_info->crprClkPath(), + open_clk_info->crprClkPath(sta), sta); Tag close_tag(0, close_rf->index(), @@ -350,31 +346,30 @@ MinPulseWidthCheck::closePath(const StaState *sta, open_tag->asString(sta)); debugPrint(sta->debug(), "mpw", 3, " close %s", close_tag.asString(sta)); - VertexPathIterator close_iter(open_path_.vertex(sta), close_rf, + VertexPathIterator close_iter(open_path_->vertex(sta), close_rf, close_ap, sta); while (close_iter.hasNext()) { - PathVertex *close_path = close_iter.next(); + Path *close_path = close_iter.next(); if (tagMatchNoPathAp(close_path->tag(sta), &close_tag)) { debugPrint(sta->debug(), "mpw", 3, " match %s", close_path->tag(sta)->asString(sta)); - close = close_path; - break; + return close_path; } } + return nullptr; } Arrival -MinPulseWidthCheck::openArrival(const StaState *sta) const +MinPulseWidthCheck::openArrival(const StaState *) const { - return open_path_.arrival(sta); + return open_path_->arrival(); } Arrival MinPulseWidthCheck::closeArrival(const StaState *sta) const { - PathVertex close; - closePath(sta, close); - return close.arrival(sta); + Path *close = closePath(sta); + return close->arrival(); } Arrival @@ -392,13 +387,13 @@ MinPulseWidthCheck::closeDelay(const StaState *sta) const const ClockEdge * MinPulseWidthCheck::openClkEdge(const StaState *sta) const { - return open_path_.clkEdge(sta->search()); + return open_path_->clkEdge(sta->search()); } const ClockEdge * MinPulseWidthCheck::closeClkEdge(const StaState *sta) const { - Tag *open_tag = open_path_.tag(sta); + Tag *open_tag = open_path_->tag(sta); ClkInfo *open_clk_info = open_tag->clkInfo(); return open_clk_info->clkEdge()->opposite(); } @@ -418,7 +413,7 @@ Arrival MinPulseWidthCheck::width(const StaState *sta) const { return closeArrival(sta) + closeOffset(sta) - - open_path_.arrival(sta) + - open_path_->arrival() + checkCrpr(sta); } @@ -427,7 +422,7 @@ MinPulseWidthCheck::minWidth(const StaState *sta) const { float min_width; bool exists; - minPulseWidth(&open_path_, sta, min_width, exists); + minPulseWidth(open_path_, sta, min_width, exists); return min_width; } @@ -469,10 +464,9 @@ Crpr MinPulseWidthCheck::checkCrpr(const StaState *sta) const { CheckCrpr *check_crpr = sta->search()->checkCrpr(); - PathVertex close; - closePath(sta, close); - if (!close.isNull()) - return check_crpr->checkCrpr(openPath(), &close); + Path *close = closePath(sta); + if (close) + return check_crpr->checkCrpr(openPath(), close); else return 0.0; } @@ -486,7 +480,7 @@ MinPulseWidthCheck::slack(const StaState *sta) const Corner * MinPulseWidthCheck::corner(const StaState *sta) const { - return open_path_.pathAnalysisPt(sta)->corner(); + return open_path_->pathAnalysisPt(sta)->corner(); } //////////////////////////////////////////////////////////////// diff --git a/search/CheckMinPulseWidths.hh b/search/CheckMinPulseWidths.hh index 21773cd5..8c6abeac 100644 --- a/search/CheckMinPulseWidths.hh +++ b/search/CheckMinPulseWidths.hh @@ -27,7 +27,7 @@ #include "SdcClass.hh" #include "SearchClass.hh" #include "StaState.hh" -#include "PathRef.hh" +#include "Path.hh" namespace sta { @@ -75,13 +75,11 @@ public: Arrival width(const StaState *sta) const; float minWidth(const StaState *sta) const; Slack slack(const StaState *sta) const; - Path *openPath() { return &open_path_; } + Path *openPath() { return open_path_; } Corner *corner(const StaState *sta) const; - const Path *openPath() const { return &open_path_; } + const Path *openPath() const { return open_path_; } Arrival openArrival(const StaState *sta) const; - void closePath(const StaState *sta, - // Return value. - PathVertex &close) const; + Path *closePath(const StaState *sta) const; Arrival closeArrival(const StaState *sta) const; Arrival openDelay(const StaState *sta) const; Arrival closeDelay(const StaState *sta) const; @@ -92,7 +90,7 @@ public: protected: // Open path of the pulse. - PathRef open_path_; + Path *open_path_; }; class MinPulseWidthSlackLess diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index 1bb36662..2cc392ca 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -34,7 +34,7 @@ #include "GraphDelayCalc.hh" #include "StaState.hh" #include "Corner.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "PortDirection.hh" #include "Search.hh" #include "ClkNetwork.hh" diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index dafa6a18..f6496356 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -38,7 +38,7 @@ #include "Bfs.hh" #include "Search.hh" #include "Genclks.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "Sim.hh" namespace sta { @@ -316,7 +316,7 @@ CheckTiming::hasClkedArrival(Vertex *vertex) { VertexPathIterator path_iter(vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); if (path->clock(this)) return true; } diff --git a/search/ClkDelays.hh b/search/ClkDelays.hh index 1eba8bf5..1b394914 100644 --- a/search/ClkDelays.hh +++ b/search/ClkDelays.hh @@ -27,7 +27,7 @@ #include "MinMax.hh" #include "StaState.hh" #include "Transition.hh" -#include "PathVertex.hh" +#include "Path.hh" namespace sta { @@ -43,7 +43,7 @@ public: Delay &delay, float &internal_latency, Delay &latency, - PathVertex &path, + Path &path, bool &exists) const; void latency(const RiseFall *src_rf, const RiseFall *end_rf, @@ -51,28 +51,28 @@ public: // Return values. Delay &delay, bool &exists) const; - static Delay latency(PathVertex *clk_path, + static Delay latency(Path *clk_path, StaState *sta); void setLatency(const RiseFall *src_rf, const RiseFall *end_rf, const MinMax *min_max, - PathVertex *path, + Path *path, bool include_internal_latency, StaState *sta); private: - static float insertionDelay(PathVertex *clk_path, + static float insertionDelay(Path *clk_path, StaState *sta); - static float delay(PathVertex *clk_path, + static float delay(Path *clk_path, StaState *sta); - static float clkTreeDelay(PathVertex *clk_path, + static float clkTreeDelay(Path *clk_path, StaState *sta); Delay insertion_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; Delay delay_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; float internal_latency_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; Delay latency_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; - PathVertex path_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; + Path path_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; bool exists_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count]; }; diff --git a/search/ClkInfo.cc b/search/ClkInfo.cc index dda8357d..f16a3818 100644 --- a/search/ClkInfo.cc +++ b/search/ClkInfo.cc @@ -53,12 +53,12 @@ ClkInfo::ClkInfo(const ClockEdge *clk_edge, float latency, ClockUncertainties *uncertainties, PathAPIndex path_ap_index, - PathVertexPtr &crpr_clk_path, + Path *crpr_clk_path, const StaState *sta) : clk_edge_(clk_edge), clk_src_(clk_src), gen_clk_src_(gen_clk_src), - crpr_clk_path_(is_propagated ? crpr_clk_path : PathVertexPtr()), + crpr_clk_path_(is_propagated ? crpr_clk_path : nullptr), uncertainties_(uncertainties), insertion_(insertion), latency_(latency), @@ -87,7 +87,7 @@ ClkInfo::findHash(const StaState *sta) hashIncr(hash_, network->vertexId(clk_src_)); if (gen_clk_src_) hashIncr(hash_, network->vertexId(gen_clk_src_)); - hashIncr(hash_, crprClkVertexId()); + hashIncr(hash_, crprClkVertexId(sta)); if (uncertainties_) { float uncertainty; bool exists; @@ -108,12 +108,24 @@ ClkInfo::findHash(const StaState *sta) } VertexId -ClkInfo::crprClkVertexId() const +ClkInfo::crprClkVertexId(const StaState *sta) const { if (crpr_clk_path_.isNull()) - return 0; + return vertex_id_null; else - return crpr_clk_path_.vertexId(); + return crpr_clk_path_.vertexId(sta); +} + +Path * +ClkInfo::crprClkPath(const StaState *sta) +{ + return Path::vertexPath(crpr_clk_path_, sta); +} + +const Path * +ClkInfo::crprClkPath(const StaState *sta) const +{ + return Path::vertexPath(crpr_clk_path_, sta); } const char * @@ -213,8 +225,9 @@ clkInfoEqual(const ClkInfo *clk_info1, && clk_info1->clkSrc() == clk_info2->clkSrc() && clk_info1->genClkSrc() == clk_info2->genClkSrc() && (!crpr_on - || (PathVertexPtr::equal(clk_info1->crprClkPath(), - clk_info2->crprClkPath()))) + || Path::equal(clk_info1->crprClkPath(sta), + clk_info2->crprClkPath(sta), + sta)) && ((uncertainties1 == nullptr && uncertainties2 == nullptr) || (uncertainties1 && uncertainties2 @@ -279,9 +292,9 @@ clkInfoCmp(const ClkInfo *clk_info1, bool crpr_on = sta->sdc()->crprActive(); if (crpr_on) { - const PathVertexPtr &crpr_path1 = clk_info1->crprClkPath(); - const PathVertexPtr &crpr_path2 = clk_info2->crprClkPath(); - int path_cmp = PathVertexPtr::cmp(crpr_path1, crpr_path2); + const Path *crpr_path1 = clk_info1->crprClkPath(sta); + const Path *crpr_path2 = clk_info2->crprClkPath(sta); + int path_cmp = Path::cmp(crpr_path1, crpr_path2, sta); if (path_cmp != 0) return path_cmp; } diff --git a/search/ClkInfo.hh b/search/ClkInfo.hh index e7a548fd..70832677 100644 --- a/search/ClkInfo.hh +++ b/search/ClkInfo.hh @@ -26,12 +26,12 @@ #include "Transition.hh" #include "SearchClass.hh" -#include "PathVertexPtr.hh" #include "Sdc.hh" +#include "Path.hh" namespace sta { -class PathVertex; +class Path; class ClkInfo { @@ -46,7 +46,7 @@ public: float latency, ClockUncertainties *uncertainties, PathAPIndex path_ap_index, - PathVertexPtr &crpr_clk_path, + Path *crpr_clk_path, const StaState *sta); ~ClkInfo(); const char *asString(const StaState *sta) const; @@ -65,9 +65,9 @@ public: PathAPIndex pathAPIndex() const { return path_ap_index_; } // Clock path used for crpr resolution. // Null for clocks because the path cannot point to itself. - PathVertexPtr &crprClkPath() { return crpr_clk_path_; } - const PathVertexPtr &crprClkPath() const { return crpr_clk_path_; } - VertexId crprClkVertexId() const; + Path *crprClkPath(const StaState *sta); + const Path *crprClkPath(const StaState *sta) const; + VertexId crprClkVertexId(const StaState *sta) const; bool hasCrprClkPin() const { return !crpr_clk_path_.isNull(); } bool refsFilter(const StaState *sta) const; // This clk_info/tag is used for a generated clock source path. @@ -81,7 +81,7 @@ private: const ClockEdge *clk_edge_; const Pin *clk_src_; const Pin *gen_clk_src_; - PathVertexPtr crpr_clk_path_; + Path crpr_clk_path_; ClockUncertainties *uncertainties_; Arrival insertion_; float latency_; diff --git a/search/ClkLatency.cc b/search/ClkLatency.cc index 334d3e56..52edbe42 100644 --- a/search/ClkLatency.cc +++ b/search/ClkLatency.cc @@ -33,7 +33,7 @@ #include "Network.hh" #include "Clock.hh" #include "Graph.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "StaState.hh" #include "Search.hh" #include "PathAnalysisPt.hh" @@ -88,7 +88,7 @@ ClkLatency::reportClkLatency(const Clock *clk, report_->reportLine("Clock %s", clk->name()); for (const RiseFall *src_rf : RiseFall::range()) { for (const RiseFall *end_rf : RiseFall::range()) { - PathVertex path_min; + Path path_min; Delay insertion_min; Delay delay_min; float internal_latency_min; @@ -97,7 +97,7 @@ ClkLatency::reportClkLatency(const Clock *clk, clk_delays.delay(src_rf, end_rf, MinMax::min(), insertion_min, delay_min, internal_latency_min, latency_min, path_min, exists_min); - PathVertex path_max; + Path path_max; Delay insertion_max; Delay delay_max; float internal_latency_max; @@ -153,7 +153,7 @@ ClkLatency::findClkDelays(ConstClockSeq &clks, for (Vertex *clk_vertex : *graph_->regClkVertices()) { VertexPathIterator path_iter(clk_vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const ClockEdge *path_clk_edge = path->clkEdge(this); const PathAnalysisPt *path_ap = path->pathAnalysisPt(this); if (path_clk_edge @@ -206,7 +206,7 @@ ClkDelays::delay(const RiseFall *src_rf, Delay &delay, float &lib_clk_delay, Delay &latency, - PathVertex &path, + Path &path, bool &exists) const { int src_rf_index = src_rf->index(); @@ -239,7 +239,7 @@ void ClkDelays::setLatency(const RiseFall *src_rf, const RiseFall *end_rf, const MinMax *min_max, - PathVertex *path, + Path *path, bool include_internal_latency, StaState *sta) { @@ -267,7 +267,7 @@ ClkDelays::setLatency(const RiseFall *src_rf, } Delay -ClkDelays::latency(PathVertex *clk_path, +ClkDelays::latency(Path *clk_path, StaState *sta) { @@ -278,16 +278,16 @@ ClkDelays::latency(PathVertex *clk_path, } float -ClkDelays::delay(PathVertex *clk_path, +ClkDelays::delay(Path *clk_path, StaState *sta) { - Arrival arrival = clk_path->arrival(sta); + Arrival arrival = clk_path->arrival(); const ClockEdge *path_clk_edge = clk_path->clkEdge(sta); return delayAsFloat(arrival) - path_clk_edge->time(); } float -ClkDelays::insertionDelay(PathVertex *clk_path, +ClkDelays::insertionDelay(Path *clk_path, StaState *sta) { const ClockEdge *clk_edge = clk_path->clkEdge(sta); @@ -302,7 +302,7 @@ ClkDelays::insertionDelay(PathVertex *clk_path, } float -ClkDelays::clkTreeDelay(PathVertex *clk_path, +ClkDelays::clkTreeDelay(Path *clk_path, StaState *sta) { const Vertex *vertex = clk_path->vertex(sta); diff --git a/search/ClkLatency.hh b/search/ClkLatency.hh index 8f4e0933..3a7d0385 100644 --- a/search/ClkLatency.hh +++ b/search/ClkLatency.hh @@ -30,7 +30,7 @@ #include "StaState.hh" #include "Transition.hh" #include "SearchClass.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "ClkDelays.hh" namespace sta { diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 7b9ae64b..e195c51b 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -38,7 +38,7 @@ #include "Graph.hh" #include "Sdc.hh" #include "Bfs.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "StaState.hh" #include "PathAnalysisPt.hh" #include "SearchPred.hh" @@ -55,14 +55,14 @@ class ClkSkew { public: ClkSkew(); - ClkSkew(PathVertex *src_path, - PathVertex *tgt_path, + ClkSkew(Path *src_path, + Path *tgt_path, bool include_internal_latency, StaState *sta); ClkSkew(const ClkSkew &clk_skew); void operator=(const ClkSkew &clk_skew); - PathVertex *srcPath() { return &src_path_; } - PathVertex *tgtPath() { return &tgt_path_; } + Path *srcPath() { return src_path_; } + Path *tgtPath() { return tgt_path_; } float srcLatency(const StaState *sta); float tgtLatency(const StaState *sta); float srcInternalClkLatency(const StaState *sta); @@ -75,23 +75,25 @@ public: const StaState *sta); private: - float clkTreeDelay(PathVertex &clk_path, + float clkTreeDelay(Path *clk_path, const StaState *sta); - PathVertex src_path_; - PathVertex tgt_path_; + Path *src_path_; + Path *tgt_path_; bool include_internal_latency_; float skew_; }; ClkSkew::ClkSkew() : + src_path_(nullptr), + tgt_path_(nullptr), include_internal_latency_(false), skew_(0.0) { } -ClkSkew::ClkSkew(PathVertex *src_path, - PathVertex *tgt_path, +ClkSkew::ClkSkew(Path *src_path, + Path *tgt_path, bool include_internal_latency, StaState *sta) : src_path_(src_path), @@ -124,8 +126,8 @@ ClkSkew::operator=(const ClkSkew &clk_skew) float ClkSkew::srcLatency(const StaState *sta) { - Arrival src_arrival = src_path_.arrival(sta); - return delayAsFloat(src_arrival) - src_path_.clkEdge(sta)->time() + Arrival src_arrival = src_path_->arrival(); + return delayAsFloat(src_arrival) - src_path_->clkEdge(sta)->time() + clkTreeDelay(src_path_, sta); } @@ -138,8 +140,8 @@ ClkSkew::srcInternalClkLatency(const StaState *sta) float ClkSkew::tgtLatency(const StaState *sta) { - Arrival tgt_arrival = tgt_path_.arrival(sta); - return delayAsFloat(tgt_arrival) - tgt_path_.clkEdge(sta)->time() + Arrival tgt_arrival = tgt_path_->arrival(); + return delayAsFloat(tgt_arrival) - tgt_path_->clkEdge(sta)->time() + clkTreeDelay(tgt_path_, sta); } @@ -150,16 +152,16 @@ ClkSkew::tgtInternalClkLatency(const StaState *sta) } float -ClkSkew::clkTreeDelay(PathVertex &clk_path, +ClkSkew::clkTreeDelay(Path *clk_path, const StaState *sta) { if (include_internal_latency_) { - const Vertex *vertex = clk_path.vertex(sta); + const Vertex *vertex = clk_path->vertex(sta); const Pin *pin = vertex->pin(); const LibertyPort *port = sta->network()->libertyPort(pin); - const MinMax *min_max = clk_path.minMax(sta); - const RiseFall *rf = clk_path.transition(sta); - float slew = delayAsFloat(clk_path.slew(sta)); + const MinMax *min_max = clk_path->minMax(sta); + const RiseFall *rf = clk_path->transition(sta); + float slew = delayAsFloat(clk_path->slew(sta)); return port->clkTreeDelay(slew, rf, min_max); } else @@ -170,17 +172,17 @@ Crpr ClkSkew::crpr(const StaState *sta) { CheckCrpr *check_crpr = sta->search()->checkCrpr(); - return check_crpr->checkCrpr(&src_path_, &tgt_path_); + return check_crpr->checkCrpr(src_path_, tgt_path_); } float ClkSkew::uncertainty(const StaState *sta) { - TimingRole *check_role = (src_path_.minMax(sta) == SetupHold::max()) + TimingRole *check_role = (src_path_->minMax(sta) == SetupHold::max()) ? TimingRole::setup() : TimingRole::hold(); // Uncertainty decreases slack, but increases skew. - return -PathEnd::checkTgtClkUncertainty(&tgt_path_, tgt_path_.clkEdge(sta), + return -PathEnd::checkTgtClkUncertainty(tgt_path_, tgt_path_->clkEdge(sta), check_role, sta); } @@ -240,8 +242,8 @@ ClkSkews::reportClkSkew(ClkSkew &clk_skew, int digits) { Unit *time_unit = units_->timeUnit(); - PathVertex *src_path = clk_skew.srcPath(); - PathVertex *tgt_path = clk_skew.tgtPath(); + Path *src_path = clk_skew.srcPath(); + Path *tgt_path = clk_skew.tgtPath(); float src_latency = clk_skew.srcLatency(this); float tgt_latency = clk_skew.tgtLatency(this); float src_internal_clk_latency = clk_skew.srcInternalClkLatency(this); @@ -352,7 +354,7 @@ ClkSkews::hasClkPaths(Vertex *vertex) { VertexPathIterator path_iter(vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const Clock *path_clk = path->clock(this); if (clk_set_.find(path_clk) != clk_set_.end()) return true; @@ -417,7 +419,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, const SetupHold *tgt_min_max = setup_hold_->opposite(); VertexPathIterator src_iter(src_vertex, this); while (src_iter.hasNext()) { - PathVertex *src_path = src_iter.next(); + Path *src_path = src_iter.next(); const Clock *src_clk = src_path->clock(this); if (src_rf->matches(src_path->transition(this)) && src_path->minMax(this) == setup_hold_ @@ -427,7 +429,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, || src_corner == corner_) { VertexPathIterator tgt_iter(tgt_vertex, this); while (tgt_iter.hasNext()) { - PathVertex *tgt_path = tgt_iter.next(); + Path *tgt_path = tgt_iter.next(); const Clock *tgt_clk = tgt_path->clock(this); if (tgt_clk == src_clk && tgt_path->isClock(this) @@ -446,7 +448,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex, time_unit->asString(probe.tgtLatency(this)), delayAsString(probe.crpr(this), this), time_unit->asString(probe.skew())); - if (clk_skew.srcPath()->isNull() + if (clk_skew.srcPath() == nullptr || abs(probe.skew()) > abs(clk_skew.skew())) clk_skew = probe; } diff --git a/search/ClkSkew.hh b/search/ClkSkew.hh index f9b89fd6..712e7b8b 100644 --- a/search/ClkSkew.hh +++ b/search/ClkSkew.hh @@ -32,7 +32,7 @@ #include "Transition.hh" #include "SearchClass.hh" #include "SearchPred.hh" -#include "PathVertex.hh" +#include "Path.hh" namespace sta { diff --git a/search/Crpr.cc b/search/Crpr.cc index 0fd5f473..ea819248 100644 --- a/search/Crpr.cc +++ b/search/Crpr.cc @@ -32,8 +32,6 @@ #include "Network.hh" #include "Graph.hh" #include "Sdc.hh" -#include "PathVertex.hh" -#include "PathPrev.hh" #include "Path.hh" #include "PathAnalysisPt.hh" #include "ClkInfo.hh" @@ -54,60 +52,26 @@ CheckCrpr::CheckCrpr(StaState *sta) : { } -void -CheckCrpr::clkPathPrev(const PathVertex *path, - PathVertex &prev) - -{ - Vertex *vertex = path->vertex(this); - int arrival_index; - bool exists; - path->arrivalIndex(arrival_index, exists); - PathPrev *prevs = graph_->prevPaths(vertex); - if (prevs) - prev.init(prevs[arrival_index], this); - else - criticalError(2200, "missing prev paths"); -} - -PathVertex -CheckCrpr::clkPathPrev(Vertex *vertex, - int arrival_index) -{ - PathPrev *prevs = graph_->prevPaths(vertex); - if (prevs) - return PathVertex(prevs[arrival_index], this); - else { - criticalError(2201, "missing prev paths"); - return PathVertex(); - } -} - -//////////////////////////////////////////////////////////////// - // Find the maximum possible crpr (clock min/max delta delay) for a // path from it's ClkInfo. Arrival CheckCrpr::maxCrpr(ClkInfo *clk_info) { - const PathVertexPtr &crpr_clk_path = clk_info->crprClkPath(); - if (!crpr_clk_path.isNull()) { - PathVertex crpr_clk_vpath(crpr_clk_path, this); - if (!crpr_clk_vpath.isNull()) { - Arrival other_arrival = otherMinMaxArrival(&crpr_clk_vpath); - float crpr_diff = abs(delayAsFloat(crpr_clk_vpath.arrival(this), - EarlyLate::late(), - this) - - delayAsFloat(other_arrival, EarlyLate::early(), - this)); - return crpr_diff; - } + const Path *crpr_clk_path = clk_info->crprClkPath(this); + if (crpr_clk_path) { + Arrival other_arrival = otherMinMaxArrival(crpr_clk_path); + float crpr_diff = abs(delayAsFloat(crpr_clk_path->arrival(), + EarlyLate::late(), + this) + - delayAsFloat(other_arrival, EarlyLate::early(), + this)); + return crpr_diff; } return 0.0F; } Arrival -CheckCrpr::otherMinMaxArrival(const PathVertex *path) +CheckCrpr::otherMinMaxArrival(const Path *path) { PathAnalysisPt *other_ap = path->pathAnalysisPt(this)->tgtClkAnalysisPt(); Tag *tag = path->tag(this); @@ -115,18 +79,18 @@ CheckCrpr::otherMinMaxArrival(const PathVertex *path) path->transition(this), other_ap, this); while (other_iter.hasNext()) { - PathVertex *other = other_iter.next(); + Path *other = other_iter.next(); if (tagMatchCrpr(other->tag(this), tag)) - return other->arrival(this); + return other->arrival(); } // No corresponding path found. // Match the arrival so the difference is zero. - return path->arrival(this); + return path->arrival(); } Crpr CheckCrpr::checkCrpr(const Path *src_path, - const PathVertex *tgt_clk_path) + const Path *tgt_clk_path) { Crpr crpr; Pin *crpr_pin; @@ -136,7 +100,7 @@ CheckCrpr::checkCrpr(const Path *src_path, void CheckCrpr::checkCrpr(const Path *src_path, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, // Return values. Crpr &crpr, Pin *&crpr_pin) @@ -152,7 +116,7 @@ CheckCrpr::checkCrpr(const Path *src_path, void CheckCrpr::checkCrpr1(const Path *src_path, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, bool same_pin, // Return values. Crpr &crpr, @@ -165,17 +129,11 @@ CheckCrpr::checkCrpr1(const Path *src_path, ClkInfo *tgt_clk_info = tgt_clk_path->tag(this)->clkInfo(); const Clock *src_clk = src_clk_info->clock(); const Clock *tgt_clk = tgt_clk_info->clock(); - PathVertex src_clk_path1; - const PathVertexPtr &src_crpr_clk_path = src_clk_info->crprClkPath(); - const PathVertex *src_clk_path = nullptr; - if (src_tag->isClock()) { - src_clk_path1.init(src_path->vertex(this), src_path->tag(this), this); - src_clk_path = &src_clk_path1; - } - else if (!src_crpr_clk_path.isNull()) { - src_clk_path1.init(src_crpr_clk_path, this); - src_clk_path = &src_clk_path1; - } + const Path *src_clk_path = nullptr; + if (src_tag->isClock()) + src_clk_path = src_path; + else + src_clk_path = src_clk_info->crprClkPath(this); const MinMax *src_clk_min_max = src_clk_path ? src_clk_path->minMax(this) : src_path->minMax(this); if (src_clk && tgt_clk @@ -189,42 +147,37 @@ CheckCrpr::checkCrpr1(const Path *src_path, && (src_clk_path || src_clk->isGenerated())) { // Src path from input port clk path can only be from generated clk path. - PathVertex port_clk_path; if (src_clk_path == nullptr) { - portClkPath(src_clk_info->clkEdge(), - src_clk_info->clkSrc(), - src_path->pathAnalysisPt(this), - port_clk_path); - src_clk_path = &port_clk_path; + src_clk_path = portClkPath(src_clk_info->clkEdge(), + src_clk_info->clkSrc(), + src_path->pathAnalysisPt(this)); } findCrpr(src_clk_path, tgt_clk_path, same_pin, crpr, crpr_pin); } } // Find the clk path for an input/output port. -void +Path * CheckCrpr::portClkPath(const ClockEdge *clk_edge, const Pin *clk_src_pin, - const PathAnalysisPt *path_ap, - // Return value. - PathVertex &genclk_path) + const PathAnalysisPt *path_ap) { Vertex *clk_vertex = graph_->pinDrvrVertex(clk_src_pin); VertexPathIterator path_iter(clk_vertex, clk_edge->transition(), path_ap, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); if (path->clkEdge(this) == clk_edge && path->isClock(this)) { - genclk_path = path; - break; + return path; } } + return nullptr; } void -CheckCrpr::findCrpr(const PathVertex *src_clk_path, - const PathVertex *tgt_clk_path, +CheckCrpr::findCrpr(const Path *src_clk_path, + const Path *tgt_clk_path, bool same_pin, // Return values. Crpr &crpr, @@ -232,35 +185,33 @@ CheckCrpr::findCrpr(const PathVertex *src_clk_path, { crpr = 0.0; crpr_pin = nullptr; - const PathVertex *src_clk_path1 = src_clk_path; - const PathVertex *tgt_clk_path1 = tgt_clk_path; - PathVertexSeq src_gclk_paths, tgt_gclk_paths; + const Path *src_clk_path1 = src_clk_path; + const Path *tgt_clk_path1 = tgt_clk_path; if (src_clk_path1->clkInfo(this)->clkSrc() != tgt_clk_path1->clkInfo(this)->clkSrc()) { // Push src/tgt genclk src paths into a vector, // The last genclk src path is at index 0. - genClkSrcPaths(src_clk_path1, src_gclk_paths); - genClkSrcPaths(tgt_clk_path1, tgt_gclk_paths); + ConstPathSeq src_gclk_paths = genClkSrcPaths(src_clk_path1); + ConstPathSeq tgt_gclk_paths = genClkSrcPaths(tgt_clk_path1); // Search from the first gen clk toward the end // of the path to find a common root pin. int i = src_gclk_paths.size() - 1; int j = tgt_gclk_paths.size() - 1; for (; i >= 0 && j >= 0; i--, j--) { - PathVertex &src_path = src_gclk_paths[i]; - PathVertex &tgt_path = tgt_gclk_paths[j]; - if (src_path.clkInfo(this)->clkSrc() - == tgt_path.clkInfo(this)->clkSrc()) { - src_clk_path1 = &src_gclk_paths[i]; - tgt_clk_path1 = &tgt_gclk_paths[j]; + const Path *src_path = src_gclk_paths[i]; + const Path *tgt_path = tgt_gclk_paths[j]; + if (src_path->clkInfo(this)->clkSrc() + == tgt_path->clkInfo(this)->clkSrc()) { + src_clk_path1 = src_gclk_paths[i]; + tgt_clk_path1 = tgt_gclk_paths[j]; } else break; } } - const PathVertex *src_clk_path2 = src_clk_path1; - const PathVertex *tgt_clk_path2 = tgt_clk_path1; - PathVertex src_prev, tgt_prev; - // src_clk_path and tgt_clk_path are now in the same (gen)clk src path. + const Path *src_clk_path2 = src_clk_path1; + const Path *tgt_clk_path2 = tgt_clk_path1; + // src_clk_path2 and tgt_clk_path2 are now in the same (gen)clk src path. // Use the vertex levels to back up the deeper path to see if they // overlap. int src_level = src_clk_path2->vertex(this)->level(); @@ -268,21 +219,19 @@ CheckCrpr::findCrpr(const PathVertex *src_clk_path, while (src_clk_path2->pin(this) != tgt_clk_path2->pin(this)) { int level_diff = src_level - tgt_level; if (level_diff >= 0) { - clkPathPrev(src_clk_path2, src_prev); - if (src_prev.isNull()) + src_clk_path2 = src_clk_path2->prevPath(); + if (src_clk_path2 == nullptr) break; - src_clk_path2 = &src_prev; src_level = src_clk_path2->vertex(this)->level(); } if (level_diff <= 0) { - clkPathPrev(tgt_clk_path2, tgt_prev); - if (tgt_prev.isNull()) + tgt_clk_path2 = tgt_clk_path2->prevPath(); + if (tgt_clk_path2 == nullptr) break; - tgt_clk_path2 = &tgt_prev; tgt_level = tgt_clk_path2->vertex(this)->level(); } } - if (!src_clk_path2->isNull() && !tgt_clk_path2->isNull() + if (src_clk_path2 && tgt_clk_path2 && (src_clk_path2->transition(this) == tgt_clk_path2->transition(this) || same_pin)) { debugPrint(debug_, "crpr", 2, "crpr pin %s", @@ -292,30 +241,31 @@ CheckCrpr::findCrpr(const PathVertex *src_clk_path, } } -void -CheckCrpr::genClkSrcPaths(const PathVertex *path, - PathVertexSeq &gclk_paths) +ConstPathSeq +CheckCrpr::genClkSrcPaths(const Path *path) { + ConstPathSeq gclk_paths; ClkInfo *clk_info = path->clkInfo(this); const ClockEdge *clk_edge = clk_info->clkEdge(); const Pin *clk_src = clk_info->clkSrc(); PathAnalysisPt *path_ap = path->pathAnalysisPt(this); gclk_paths.push_back(path); + Genclks *genclks = search_->genclks(); while (clk_edge->clock()->isGenerated()) { - PathVertex genclk_path = - search_->genclks()->srcPath(clk_edge, clk_src, path_ap); - if (genclk_path.isNull()) + Path *genclk_path = genclks->srcPath(clk_edge, clk_src, path_ap); + if (genclk_path == nullptr) break; - clk_info = genclk_path.clkInfo(this); + clk_info = genclk_path->clkInfo(this); clk_src = clk_info->clkSrc(); clk_edge = clk_info->clkEdge(); gclk_paths.push_back(genclk_path); } + return gclk_paths; } Crpr -CheckCrpr::findCrpr1(const PathVertex *src_clk_path, - const PathVertex *tgt_clk_path) +CheckCrpr::findCrpr1(const Path *src_clk_path, + const Path *tgt_clk_path) { if (pocv_enabled_) { // Remove variation on the common path. @@ -323,8 +273,8 @@ CheckCrpr::findCrpr1(const PathVertex *src_clk_path, // sigma of the common clock path. const EarlyLate *src_el = src_clk_path->minMax(this); const EarlyLate *tgt_el = tgt_clk_path->minMax(this); - Arrival src_arrival = src_clk_path->arrival(this); - Arrival tgt_arrival = tgt_clk_path->arrival(this); + Arrival src_arrival = src_clk_path->arrival(); + Arrival tgt_arrival = tgt_clk_path->arrival(); float src_clk_time = src_clk_path->clkEdge(this)->time(); float tgt_clk_time = tgt_clk_path->clkEdge(this)->time(); float crpr_mean = abs(delayAsFloat(src_arrival) - src_clk_time @@ -352,10 +302,10 @@ CheckCrpr::findCrpr1(const PathVertex *src_clk_path, } float -CheckCrpr::crprArrivalDiff(const PathVertex *path) +CheckCrpr::crprArrivalDiff(const Path *path) { Arrival other_arrival = otherMinMaxArrival(path); - float crpr_diff = abs(delayAsFloat(path->arrival(this)) + float crpr_diff = abs(delayAsFloat(path->arrival()) - delayAsFloat(other_arrival)); return crpr_diff; } @@ -407,13 +357,12 @@ CheckCrpr::outputDelayCrpr1(const Path *src_path, && tgt_clk->isGenerated() && tgt_clk->isPropagated() && crprPossible(src_clk, tgt_clk)) { - PathVertex tgt_genclk_path; - portClkPath(tgt_clk_edge, tgt_clk_edge->clock()->defaultPin(), tgt_path_ap, - tgt_genclk_path); - PathVertex src_clk_path(src_path->clkInfo(this)->crprClkPath(), this); - if (!src_clk_path.isNull()) { - findCrpr(&src_clk_path, &tgt_genclk_path, same_pin, crpr, crpr_pin); - } + Path *tgt_genclk_path = portClkPath(tgt_clk_edge, + tgt_clk_edge->clock()->defaultPin(), + tgt_path_ap); + Path *src_clk_path = src_path->clkInfo(this)->crprClkPath(this); + if (src_clk_path) + findCrpr(src_clk_path, tgt_genclk_path, same_pin, crpr, crpr_pin); } } diff --git a/search/Crpr.hh b/search/Crpr.hh index 26bcc4c4..bed17295 100644 --- a/search/Crpr.hh +++ b/search/Crpr.hh @@ -42,9 +42,9 @@ public: Arrival maxCrpr(ClkInfo *clk_info); // Timing check CRPR. Crpr checkCrpr(const Path *src_clk_path, - const PathVertex *tgt_clk_path); + const Path *tgt_clk_path); void checkCrpr(const Path *src_path, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, // Return values. Crpr &crpr, Pin *&crpr_pin); @@ -57,18 +57,12 @@ public: Crpr &crpr, Pin *&crpr_pin); - // Previous clk path when crpr is enabled. - PathVertex clkPathPrev(const PathVertex *path); - // For Search::reportArrivals. - PathVertex clkPathPrev(Vertex *vertex, - int arrival_index); - private: - void clkPathPrev(const PathVertex *path, - PathVertex &prev); - Arrival otherMinMaxArrival(const PathVertex *path); + void clkPathPrev(const Path *path, + Path &prev); + Arrival otherMinMaxArrival(const Path *path); void checkCrpr1(const Path *src_path, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, bool same_pin, // Return values. Crpr &crpr, @@ -82,22 +76,19 @@ private: Pin *&crpr_pin); bool crprPossible(const Clock *clk1, const Clock *clk2); - void genClkSrcPaths(const PathVertex *path, - PathVertexSeq &gclk_paths); - void findCrpr(const PathVertex *src_clk_path, - const PathVertex *tgt_clk_path, + ConstPathSeq genClkSrcPaths(const Path *path); + void findCrpr(const Path *src_clk_path, + const Path *tgt_clk_path, bool same_pin, // Return values. Crpr &crpr, Pin *&common_pin); - void portClkPath(const ClockEdge *clk_edge, - const Pin *clk_src_pin, - const PathAnalysisPt *path_ap, - // Return value. - PathVertex &port_clk_path); - Crpr findCrpr1(const PathVertex *src_clk_path, - const PathVertex *tgt_clk_path); - float crprArrivalDiff(const PathVertex *path); + Path *portClkPath(const ClockEdge *clk_edge, + const Pin *clk_src_pin, + const PathAnalysisPt *path_ap); + Crpr findCrpr1(const Path *src_clk_path, + const Path *tgt_clk_path); + float crprArrivalDiff(const Path *path); }; } // namespace diff --git a/search/Genclks.cc b/search/Genclks.cc index 573dcf0f..7a7cb4ef 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -40,7 +40,7 @@ #include "Corner.hh" #include "PathAnalysisPt.hh" #include "Levelize.hh" -#include "PathVertexPtr.hh" +#include "Path.hh" #include "Search.hh" namespace sta { @@ -137,7 +137,7 @@ Genclks::fanins(const Clock *clk) } Vertex * -Genclks::srcPathVertex(const Pin *pin) const +Genclks::srcPath(const Pin *pin) const { bool is_bidirect = network_->direction(pin)->isBidirect(); // Insertion delay is to the driver vertex for clks defined on @@ -155,7 +155,7 @@ Genclks::clkPinMaxLevel(const Clock *clk) const { Level max_level = 0; for (const Pin *pin : clk->leafPins()) { - Vertex *vertex = srcPathVertex(pin); + Vertex *vertex = srcPath(pin); max_level = max(max_level, vertex->level()); } return max_level; @@ -209,9 +209,7 @@ Genclks::ensureInsertionDelays() // insertion delay, so sort the clocks by source pin level. sort(gclks, ClockPinMaxLevelLess(this)); - ClockSeq::Iterator gclk_iter(gclks); - while (gclk_iter.hasNext()) { - Clock *gclk = gclk_iter.next(); + for (Clock *gclk : gclks) { if (gclk->masterClk()) { findInsertionDelays(gclk); recordSrcPaths(gclk); @@ -546,7 +544,7 @@ Genclks::makeGenclkInfo(Clock *gclk) VertexSet *fanins = new VertexSet(graph_); findFanin(gclk, fanins); GenclkInfo *genclk_info = new GenclkInfo(gclk, gclk_level, fanins, - src_filter); + src_filter); genclk_info_map_.insert(gclk, genclk_info); return genclk_info; } @@ -684,12 +682,12 @@ Genclks::seedSrcPins(Clock *gclk, for (auto path_ap : corners_->pathAnalysisPts()) { const MinMax *min_max = path_ap->pathMinMax(); const EarlyLate *early_late = min_max; - for (auto rf : RiseFall::range()) { - Tag *tag = makeTag(gclk, master_clk, master_pin, rf, src_filter, - path_ap); + 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_bldr.setArrival(tag, insert, nullptr); + tag_bldr.setArrival(tag, insert); } } search_->setVertexArrivals(vertex, &tag_bldr); @@ -854,22 +852,14 @@ void Genclks::copyGenClkSrcPaths(Vertex *vertex, TagGroupBldr *tag_bldr) { - Arrival *arrivals = graph_->arrivals(vertex); - if (arrivals) { - PathPrev *prev_paths = graph_->prevPaths(vertex); + Path *paths = graph_->paths(vertex); + if (paths) { TagGroup *tag_group = search_->tagGroup(vertex); if (tag_group) { - ArrivalMap::Iterator arrival_iter(tag_group->arrivalMap()); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); + for (auto const [tag, path_index] : *tag_group->pathIndexMap()) { if (tag->isGenClkSrcPath()) { - Arrival arrival = arrivals[arrival_index]; - PathPrev *prev_path = prev_paths - ? &prev_paths[arrival_index] - : nullptr; - tag_bldr->setArrival(tag, arrival, prev_path); + Path &path = paths[path_index]; + tag_bldr->insertPath(path); } } } @@ -881,11 +871,14 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, void Genclks::clearSrcPaths() { - genclk_src_paths_.deleteArrayContents(); + for (auto const & [clk_pin, src_paths] : genclk_src_paths_) { + for (const Path &src_path : src_paths) + delete src_path.prevPath(); + } genclk_src_paths_.clear(); } -int +size_t Genclks::srcPathIndex(const RiseFall *clk_rf, const PathAnalysisPt *path_ap) const { @@ -903,14 +896,13 @@ Genclks::recordSrcPaths(Clock *gclk) bool has_edges = gclk->edges() != nullptr; for (const Pin *gclk_pin : gclk->leafPins()) { - PathVertexPtr *src_paths = new PathVertexPtr[path_count]; - genclk_src_paths_.insert(ClockPinPair(gclk, gclk_pin), src_paths); - - Vertex *gclk_vertex = srcPathVertex(gclk_pin); + vector &src_paths = genclk_src_paths_[ClockPinPair(gclk, gclk_pin)]; + src_paths.resize(path_count); + Vertex *gclk_vertex = srcPath(gclk_pin); bool found_src_paths = false; VertexPathIterator path_iter(gclk_vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const ClockEdge *src_clk_edge = path->clkEdge(this); if (src_clk_edge && matchesSrcFilter(path, gclk)) { @@ -919,24 +911,34 @@ Genclks::recordSrcPaths(Clock *gclk) const RiseFall *rf = path->transition(this); bool inverting_path = (rf != src_clk_rf); const PathAnalysisPt *path_ap = path->pathAnalysisPt(this); - int path_index = srcPathIndex(rf, path_ap); - PathVertexPtr &src_path = src_paths[path_index]; + size_t path_index = srcPathIndex(rf, path_ap); + Path &src_path = src_paths[path_index]; if ((!divide_by_1 || (inverting_path == invert)) && (!has_edges || src_clk_rf == gclk->masterClkEdgeTr(rf)) && (src_path.isNull() - || delayGreater(path->arrival(this), - src_path.arrival(this), + || delayGreater(path->arrival(), + src_path.arrival(), early_late, this))) { debugPrint(debug_, "genclk", 2, " %s insertion %s %s %s", network_->pathName(gclk_pin), early_late->asString(), rf->asString(), - delayAsString(path->arrival(this), this)); - src_path.init(path, this); - found_src_paths = true; + delayAsString(path->arrival(), this)); + delete src_path.prevPath(); + src_path = *path; + Path *prev_copy = &src_path; + Path *p = path->prevPath(); + while (p) { + Path *copy = new Path(p); + copy->setIsEnum(true); + prev_copy->setPrevPath(copy); + prev_copy = copy; + p = p->prevPath(); + } + found_src_paths = true; } } } @@ -973,8 +975,8 @@ Genclks::matchesSrcFilter(Path *path, return false; } -PathVertex -Genclks::srcPath(Path *clk_path) const +Path * +Genclks::srcPath(const Path *clk_path) const { const Pin *src_pin = clk_path->pin(this); const ClockEdge *clk_edge = clk_path->clkEdge(this); @@ -985,7 +987,7 @@ Genclks::srcPath(Path *clk_path) const insert_ap); } -PathVertex +Path * Genclks::srcPath(const ClockEdge *clk_edge, const Pin *src_pin, const PathAnalysisPt *path_ap) const @@ -993,20 +995,52 @@ Genclks::srcPath(const ClockEdge *clk_edge, return srcPath(clk_edge->clock(), src_pin, clk_edge->transition(), path_ap); } -PathVertex +Path * Genclks::srcPath(const Clock *gclk, const Pin *src_pin, const RiseFall *rf, const PathAnalysisPt *path_ap) const { - PathVertexPtr *src_paths = - genclk_src_paths_.findKey(ClockPinPair(gclk, src_pin)); - if (src_paths) { - int path_index = srcPathIndex(rf, path_ap); - return PathVertex(src_paths[path_index], this); + auto itr = genclk_src_paths_.find(ClockPinPair(gclk, src_pin)); + if (itr != genclk_src_paths_.end()) { + 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; + } + } + } + return nullptr; +} + +void +Genclks::updateSrcPathPrevs() +{ + for (auto const & [clk_pin, src_paths] : genclk_src_paths_) { + for (const Path &src_path : src_paths) { + if (!src_path.isNull()) { + const Path *p = &src_path; + while (p) { + Path *src_vpath = Path::vertexPath(p->vertex(this), + p->tag(this), this); + Path *prev_path = p->prevPath(); + if (prev_path) { + Path *prev_vpath = Path::vertexPath(prev_path->vertex(this), + prev_path->tag(this), this); + src_vpath->setPrevPath(prev_vpath); + src_vpath->setPrevEdgeArc(p->prevEdge(this), + p->prevArc(this), this); + } + p = p->prevPath(); + } + debugPrint(debug_, "genclk", 3, "repaired src path prev %s", + src_path.name(this)); + } + } } - else - return PathVertex(); } Arrival @@ -1017,9 +1051,9 @@ Genclks::insertionDelay(const Clock *clk, const PathAnalysisPt *path_ap) const { PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late); - PathVertex src_path = srcPath(clk, pin, rf, insert_ap); - if (!src_path.isNull()) - return src_path.arrival(this); + Path *src_path = srcPath(clk, pin, rf, insert_ap); + if (src_path) + return src_path->arrival(); else return 0.0; } diff --git a/search/Genclks.hh b/search/Genclks.hh index 7d662e1b..c063d31b 100644 --- a/search/Genclks.hh +++ b/search/Genclks.hh @@ -50,7 +50,7 @@ public: }; typedef Map GenclkInfoMap; -typedef Map GenclkSrcPathMap; +typedef Map, ClockPinPairLess> GenclkSrcPathMap; class Genclks : public StaState { @@ -71,19 +71,20 @@ public: const EarlyLate *early_late, const PathAnalysisPt *path_ap) const; // Generated clock source path for a clock path root. - PathVertex srcPath(Path *clk_path) const; + Path *srcPath(const Path *clk_path) const; // Generated clock source path. - PathVertex srcPath(const ClockEdge *clk_edge, - const Pin *src_pin, - const PathAnalysisPt *path_ap) const; - PathVertex srcPath(const Clock *clk, - const Pin *src_pin, - const RiseFall *rf, - const PathAnalysisPt *path_ap) const; - Vertex *srcPathVertex(const Pin *pin) const; + 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; + Vertex *srcPath(const Pin *pin) const; Level clkPinMaxLevel(const Clock *clk) const; void copyGenClkSrcPaths(Vertex *vertex, TagGroupBldr *tag_bldr); + void updateSrcPathPrevs(); private: void findInsertionDelays(); @@ -94,8 +95,8 @@ private: void seedClkVertices(Clock *clk, BfsBkwdIterator &iter, VertexSet *fanins); - int srcPathIndex(const RiseFall *clk_rf, - const PathAnalysisPt *path_ap) const; + size_t srcPathIndex(const RiseFall *clk_rf, + const PathAnalysisPt *path_ap) const; bool matchesSrcFilter(Path *path, const Clock *gclk) const; void seedSrcPins(Clock *gclk, @@ -129,7 +130,6 @@ private: VertexSet &visited_vertices, EdgeSet *&fdbk_edges); - bool found_insertion_delays_; GenclkSrcPathMap genclk_src_paths_; GenclkInfoMap genclk_info_map_; diff --git a/search/Latches.cc b/search/Latches.cc index 947243ac..d04bdfc1 100644 --- a/search/Latches.cc +++ b/search/Latches.cc @@ -49,8 +49,8 @@ Latches::Latches(StaState *sta) : void Latches::latchRequired(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const MultiCyclePath *mcp, const PathDelay *path_delay, Arrival src_clk_latency, @@ -61,7 +61,7 @@ Latches::latchRequired(const Path *data_path, Arrival &adjusted_data_arrival, Delay &time_given_to_startpoint) const { - const Arrival data_arrival = data_path->arrival(this); + const Arrival data_arrival = data_path->arrival(); float max_delay = 0.0; bool ignore_clk_latency = false; if (path_delay) { @@ -149,8 +149,8 @@ Latches::latchRequired(const Path *data_path, void Latches::latchBorrowInfo(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const ArcDelay &margin, bool ignore_clk_latency, // Return values. @@ -213,8 +213,8 @@ Latches::latchBorrowInfo(const Path *data_path, void Latches::latchRequired(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const PathAnalysisPt *path_ap, // Return values. Required &required, @@ -243,11 +243,9 @@ Latches::latchRequired(const Path *data_path, } // Find the latch enable open/close path from the close/open path. -void +Path * Latches::latchEnableOtherPath(const Path *path, - const PathAnalysisPt *tgt_clk_path_ap, - // Return value. - PathVertex &other_path) const + const PathAnalysisPt *tgt_clk_path_ap) const { Vertex *vertex = path->vertex(this); const ClockEdge *clk_edge = path->clkEdge(this); @@ -256,20 +254,18 @@ Latches::latchEnableOtherPath(const Path *path, RiseFall *other_rf = path->transition(this)->opposite(); VertexPathIterator path_iter(vertex, other_rf, tgt_clk_path_ap, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); if (path->isClock(this) && path->clkEdge(this) == other_clk_edge) { - other_path = path; - break; + return path; } } + return nullptr; } -void +Path * Latches::latchEnablePath(const Path *q_path, - const Edge *d_q_edge, - // Return value. - PathVertex &enable_path) const + const Edge *d_q_edge) const { const ClockEdge *en_clk_edge = q_path->clkEdge(this); @@ -283,15 +279,15 @@ Latches::latchEnablePath(const Path *q_path, if (state == LatchEnableState::enabled) { VertexPathIterator path_iter(en_vertex, en_rf, tgt_clk_path_ap, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const ClockEdge *clk_edge = path->clkEdge(this); if (path->isClock(this) && clk_edge == en_clk_edge) { - enable_path = path; - break; + return path; } } } + return nullptr; } // The arrival time for a latch D->Q edge is clipped to the window of @@ -324,7 +320,7 @@ Latches::latchOutArrival(const Path *data_path, if (!(excpt && excpt->isFalse())) { arc_delay = search_->deratedDelay(data_vertex, d_q_arc, d_q_edge, false, path_ap); - q_arrival = data_path->arrival(this) + arc_delay; + q_arrival = data_path->arrival() + arc_delay; q_tag = data_path->tag(this); } } @@ -334,7 +330,7 @@ Latches::latchOutArrival(const Path *data_path, VertexPathIterator enable_iter(enable_vertex, enable_rf, tgt_clk_path_ap, this); while (enable_iter.hasNext()) { - PathVertex *enable_path = enable_iter.next(); + Path *enable_path = enable_iter.next(); ClkInfo *en_clk_info = enable_path->clkInfo(this); const ClockEdge *en_clk_edge = en_clk_info->clkEdge(); if (enable_path->isClock(this)) { @@ -342,12 +338,11 @@ Latches::latchOutArrival(const Path *data_path, // D->Q is disabled when if there is a path delay -to D or EN clk. if (!(excpt && (excpt->isFalse() || excpt->isPathDelay()))) { - PathVertex disable_path; - latchEnableOtherPath(enable_path, tgt_clk_path_ap, disable_path); + Path *disable_path = latchEnableOtherPath(enable_path, tgt_clk_path_ap); Delay borrow, time_given_to_startpoint; Arrival adjusted_data_arrival; Required required; - latchRequired(data_path, enable_path, &disable_path, path_ap, + latchRequired(data_path, enable_path, disable_path, path_ap, required, borrow, adjusted_data_arrival, time_given_to_startpoint); if (delayGreater(borrow, 0.0, this)) { @@ -357,7 +352,7 @@ Latches::latchOutArrival(const Path *data_path, q_arrival = adjusted_data_arrival + arc_delay; // Tag switcheroo - data passing thru gets latch enable tag. // States and path ap come from Q, everything else from enable. - PathVertex *crpr_clk_path = + Path *crpr_clk_path = sdc_->crprActive() ? enable_path : nullptr; ClkInfo *q_clk_info = search_->findClkInfo(en_clk_edge, @@ -448,24 +443,23 @@ Latches::latchTimeGivenToStartpoint(const Path *d_path, const Edge *d_q_edge, // Return values. Arrival &time_given, - PathVertex &enable_path) const + Path *&enable_path) const { - latchEnablePath(q_path, d_q_edge, enable_path); - if (!enable_path.isNull() - && enable_path.isClock(this)) { + enable_path = latchEnablePath(q_path, d_q_edge); + if (enable_path + && enable_path->isClock(this)) { const PathAnalysisPt *path_ap = q_path->pathAnalysisPt(this); const PathAnalysisPt *tgt_clk_path_ap = path_ap->tgtClkAnalysisPt(); - PathVertex disable_path; - latchEnableOtherPath(enable_path.path(), tgt_clk_path_ap, disable_path); + Path *disable_path = latchEnableOtherPath(enable_path, tgt_clk_path_ap); Delay borrow; Required required; Arrival adjusted_data_arrival; - latchRequired(d_path, &enable_path, &disable_path, path_ap, + latchRequired(d_path, enable_path, disable_path, path_ap, required, borrow, adjusted_data_arrival, time_given); } else { time_given = 0.0; - enable_path.init(); + enable_path = nullptr; } } @@ -517,7 +511,7 @@ Latches::latchDtoQEnable(const Edge *d_q_edge, } LatchEnableState -Latches::latchDtoQState(Edge *edge) const +Latches::latchDtoQState(const Edge *edge) const { const Vertex *from_vertex = edge->from(graph_); const Pin *from_pin = from_vertex->pin(); @@ -532,7 +526,7 @@ Latches::latchDtoQState(Edge *edge) const // Latch D->Q arc looks combinational when the enable pin is disabled // or constant. bool -Latches::isLatchDtoQ(Edge *edge) const +Latches::isLatchDtoQ(const Edge *edge) const { return edge->role() == TimingRole::latchDtoQ() && latchDtoQState(edge) == LatchEnableState::enabled; diff --git a/search/Latches.hh b/search/Latches.hh index 4f14fc2d..689e1685 100644 --- a/search/Latches.hh +++ b/search/Latches.hh @@ -43,10 +43,10 @@ public: const Edge *d_q_edge, // Return values. Arrival &time_given, - PathVertex &enable_path) const; + Path *&enable_path) const; void latchRequired(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const MultiCyclePath *mcp, const PathDelay *path_delay, Arrival src_clk_latency, @@ -57,8 +57,8 @@ public: Arrival &adjusted_data_arrival, Delay &time_given_to_startpoint) const; void latchRequired(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const PathAnalysisPt *path_ap, // Return values. Required &required, @@ -66,8 +66,8 @@ public: Arrival &adjusted_data_arrival, Delay &time_given_to_startpoint) const; void latchBorrowInfo(const Path *data_path, - const PathVertex *enable_path, - const PathVertex *disable_path, + const Path *enable_path, + const Path *disable_path, const ArcDelay &margin, bool ignore_clk_latency, // Return values. @@ -79,7 +79,7 @@ public: Crpr &crpr_diff, Delay &max_borrow, bool &borrow_limit_exists) const; - bool isLatchDtoQ(Edge *edge) const; + bool isLatchDtoQ(const Edge *edge) const; // Find the latch EN->Q edge for a D->Q edge. void latchDtoQEnable(const Edge *d_q_edge, const Instance *inst, @@ -87,15 +87,11 @@ public: Vertex *&enable_vertex, const RiseFall *&enable_rf, LatchEnableState &state) const; - LatchEnableState latchDtoQState(Edge *d_q_edge) const; - void latchEnableOtherPath(const Path *path, - const PathAnalysisPt *tgt_clk_path_ap, - // Return value. - PathVertex &other_path) const; - void latchEnablePath(const Path *q_path, - const Edge *d_q_edge, - // Return value. - PathVertex &enable_path) const; + LatchEnableState latchDtoQState(const Edge *d_q_edge) const; + Path *latchEnableOtherPath(const Path *path, + const PathAnalysisPt *tgt_clk_path_ap) const; + Path *latchEnablePath(const Path *q_path, + const Edge *d_q_edge) const; void latchOutArrival(const Path *data_path, const TimingArc *d_q_arc, const Edge *d_q_edge, diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 9de20759..b9010b9b 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -280,7 +280,7 @@ MakeEndTimingArcs::visit(PathEnd *path_end) Network *network = sta_->network(); Debug *debug = sta_->debug(); const MinMax *min_max = path_end->minMax(sta_); - Arrival data_delay = src_path->arrival(sta_); + Arrival data_delay = src_path->arrival(); Delay clk_latency = path_end->targetClkDelay(sta_); ArcDelay check_margin = path_end->margin(sta_); Delay margin = min_max == MinMax::max() @@ -377,11 +377,11 @@ MakeTimingModel::findOutputDelays(const RiseFall *input_rf, Vertex *output_vertex = graph_->pinLoadVertex(output_pin); VertexPathIterator path_iter(output_vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); if (search_->matchesFilter(path, nullptr)) { const RiseFall *output_rf = path->transition(sta_); const MinMax *min_max = path->minMax(sta_); - Arrival delay = path->arrival(sta_); + Arrival delay = path->arrival(); OutputDelays &delays = output_pin_delays[output_pin]; delays.delays.mergeValue(output_rf, min_max, delayAsFloat(delay, min_max, sta_)); @@ -486,12 +486,12 @@ MakeTimingModel::findClkedOutputPaths() Vertex *output_vertex = graph_->pinLoadVertex(output_pin); VertexPathIterator path_iter(output_vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); const ClockEdge *clk_edge = path->clkEdge(sta_); if (clk_edge) { const RiseFall *output_rf = path->transition(sta_); const MinMax *min_max = path->minMax(sta_); - Arrival delay = path->arrival(sta_); + Arrival delay = path->arrival(); RiseFallMinMax &delays = clk_delays[clk_edge]; delays.mergeValue(output_rf, min_max, delayAsFloat(delay, min_max, sta_)); @@ -567,7 +567,7 @@ MakeTimingModel::makeClkTreePaths(LibertyPort *lib_port, const RiseFall *end_rf = (sense == TimingSense::positive_unate) ? clk_rf : clk_rf->opposite(); - PathVertex clk_path; + Path clk_path; Delay insertion, delay, latency; float lib_clk_delay; bool exists; diff --git a/search/Path.cc b/search/Path.cc index c592a418..90f56b4d 100644 --- a/search/Path.cc +++ b/search/Path.cc @@ -33,17 +33,180 @@ #include "Corner.hh" #include "PathAnalysisPt.hh" #include "Tag.hh" -#include "PathRef.hh" +#include "TagGroup.hh" +#include "Search.hh" namespace sta { +Path::Path() : + prev_path_(nullptr), + arrival_(0.0), + required_(0.0), + vertex_id_(vertex_id_null), + tag_index_(tag_index_null), + is_enum_(false), + prev_arc_idx_(0) +{ +} + +Path::Path(Path *path) : + prev_path_(path ? path->prev_path_ : nullptr), + arrival_(path ? path->arrival_ : 0.0), + required_(path ? path->required_ : 0.0), + vertex_id_(path ? path->vertex_id_ : vertex_id_null), + tag_index_(path ? path->tag_index_ : tag_index_null), + is_enum_(path ? path->is_enum_ : false), + prev_arc_idx_(path ? path->prev_arc_idx_ : 0) +{ +} + +Path::Path(Vertex *vertex, + Tag *tag, + const StaState *sta) : + prev_path_(nullptr), + arrival_(0.0), + required_(0.0), + tag_index_(tag->index()), + is_enum_(false), + prev_arc_idx_(0) +{ + const Graph *graph = sta->graph(); + vertex_id_ = graph->id(vertex); +} + +Path::Path(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta) : + prev_path_(prev_path), + arrival_(arrival), + required_(0.0), + tag_index_(tag->index()), + is_enum_(false) +{ + const Graph *graph = sta->graph(); + if (prev_path) { + prev_edge_id_ = graph->id(prev_edge); + prev_arc_idx_ = prev_arc->index(); + } + else { + vertex_id_ = graph->id(vertex); + prev_arc_idx_ = 0; + } +} + +Path::Path(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + bool is_enum, + const StaState *sta) : + prev_path_(prev_path), + arrival_(arrival), + required_(0.0), + tag_index_(tag->index()), + is_enum_(is_enum) +{ + const Graph *graph = sta->graph(); + if (prev_path) { + prev_edge_id_ = graph->id(prev_edge); + prev_arc_idx_ = prev_arc->index(); + } + else { + vertex_id_ = graph->id(vertex); + prev_arc_idx_ = 0; + } +} + +Path:: ~Path() +{ + if (is_enum_ && prev_path_ && prev_path_->is_enum_) + delete prev_path_; +} + +void +Path::init(Vertex *vertex, + Arrival arrival, + const StaState *sta) +{ + const Graph *graph = sta->graph(); + vertex_id_ = graph->id(vertex); + tag_index_ = tag_index_null, + prev_path_ = nullptr; + prev_arc_idx_ = 0; + arrival_ = arrival; + required_ = 0.0; + is_enum_ = false; +} + +void +Path::init(Vertex *vertex, + Tag *tag, + const StaState *sta) +{ + const Graph *graph = sta->graph(); + vertex_id_ = graph->id(vertex); + tag_index_ = tag->index(), + prev_path_ = nullptr; + prev_arc_idx_ = 0; + arrival_ = 0.0; + required_ = 0.0; + is_enum_ = false; +} + +void +Path::init(Vertex *vertex, + Tag *tag, + Arrival arrival, + const StaState *sta) +{ + const Graph *graph = sta->graph(); + vertex_id_ = graph->id(vertex); + tag_index_ = tag->index(), + prev_path_ = nullptr; + prev_arc_idx_ = 0; + arrival_ = arrival; + required_ = 0.0; + is_enum_ = false; +} + +void +Path::init(Vertex *vertex, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta) +{ + const Graph *graph = sta->graph(); + tag_index_ = tag->index(), + prev_path_ = prev_path; + if (prev_path) { + prev_edge_id_ = graph->id(prev_edge); + prev_arc_idx_ = prev_arc->index(); + } + else { + vertex_id_ = graph->id(vertex); + prev_arc_idx_ = 0; + } + arrival_ = arrival; + required_ = 0.0; + is_enum_ = false; +} + const char * Path::name(const StaState *sta) const { const Network *network = sta->network(); - Vertex *vertex1 = vertex(sta); - if (vertex1) { - const char *vertex_name = vertex1->name(network); + Vertex *vertex = this->vertex(sta); + if (vertex) { + const char *vertex_name = vertex->name(network); const char *tr_str = transition(sta)->asString(); const PathAnalysisPt *path_ap = pathAnalysisPt(sta); int ap_index = path_ap->index(); @@ -57,16 +220,67 @@ Path::name(const StaState *sta) const return "NULL"; } +bool +Path::isNull() const +{ + return vertex_id_ == vertex_id_null; +} + +Vertex * +Path::vertex(const StaState *sta) const +{ + const Graph *graph = sta->graph(); + if (prev_path_) { + const Edge *edge = graph->edge(prev_edge_id_); + return edge->to(graph); + } + else + return graph->vertex(vertex_id_); +} + +VertexId +Path::vertexId(const StaState *sta) const +{ + const Graph *graph = sta->graph(); + if (prev_path_) { + const Edge *edge = graph->edge(prev_edge_id_); + return edge->to(); + } + else + return vertex_id_; +} + Pin * Path::pin(const StaState *sta) const { return vertex(sta)->pin(); } -TagIndex -Path::tagIndex(const StaState *sta) const +Tag * +Path::tag(const StaState *sta) const { - return tag(sta)->index(); + const Search *search = sta->search(); + return search->tag(tag_index_); +} + +void +Path::setTag(Tag *tag) +{ + tag_index_ = tag->index(); +} + +TagIndex +Path::tagIndex(const StaState *) const +{ + return tag_index_; +} + +size_t +Path::pathIndex(const StaState *sta) const +{ + Vertex *vertex = this->vertex(sta); + Path *paths = vertex->paths(); + return this - paths; } ClkInfo * @@ -118,80 +332,187 @@ Path::slew(const StaState *sta) const dcalcAnalysisPt(sta)->index()); } +const RiseFall * +Path::transition(const StaState *sta) const +{ + return tag(sta)->transition(); +} + int Path::rfIndex(const StaState *sta) const { return transition(sta)->index(); } -void -Path::initArrival(const StaState *sta) +PathAnalysisPt * +Path::pathAnalysisPt(const StaState *sta) const { - setArrival(delayInitValue(minMax(sta)), sta); -} - -bool -Path::arrivalIsInitValue(const StaState *sta) const -{ - return delayIsInitValue(arrival(sta), minMax(sta)); + return tag(sta)->pathAnalysisPt(sta); } void -Path::initRequired(const StaState *sta) +Path::setArrival(Arrival arrival) { - setRequired(delayInitValue(minMax(sta)->opposite()), sta); + arrival_ = arrival; } -bool -Path::requiredIsInitValue(const StaState *sta) const +void +Path::setRequired(const Required &required) { - return delayIsInitValue(required(sta), minMax(sta)->opposite()); + required_ = required; } Slack Path::slack(const StaState *sta) const { if (minMax(sta) == MinMax::max()) - return required(sta) - arrival(sta); + return required_ - arrival_; else - return arrival(sta) - required(sta); + return arrival_ - required_; +} + +Path * +Path::prevPath() const +{ + return prev_path_; } void -Path::prevPath(const StaState *sta, - // Return values. - PathRef &prev_path) const +Path::setPrevPath(Path *prev_path) { - TimingArc *prev_arc; - prevPath(sta, prev_path, prev_arc); + prev_path_ = prev_path; +} + +void +Path::clearPrevPath(const StaState *sta) +{ + // Preserve vertex ID for path when prev edge is no longer valid. + if (prev_path_) { + const Graph *graph = sta->graph(); + const Edge *prev_edge = graph->edge(prev_edge_id_); + vertex_id_ = prev_edge->to(); + prev_arc_idx_ = 0; + } + prev_path_ = nullptr; } TimingArc * Path::prevArc(const StaState *sta) const { - PathRef prev_path; - TimingArc *prev_arc; - prevPath(sta, prev_path, prev_arc); - return prev_arc; + if (prev_path_) { + const Graph *graph = sta->graph(); + const Edge *edge = graph->edge(prev_edge_id_); + TimingArcSet *arc_set = edge->timingArcSet(); + return arc_set->findTimingArc(prev_arc_idx_); + } + else + return nullptr; } Edge * -Path::prevEdge(const TimingArc *prev_arc, - const StaState *sta) const +Path::prevEdge(const StaState *sta) const { - if (prev_arc) { - TimingArcSet *arc_set = prev_arc->set(); - VertexInEdgeIterator edge_iter(vertex(sta), sta->graph()); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->timingArcSet() == arc_set) - return edge; + if (prev_path_) { + const Graph *graph = sta->graph(); + return graph->edge(prev_edge_id_); + } + else + return nullptr; +} + +Vertex * +Path::prevVertex(const StaState *sta) const +{ + if (prev_path_) { + const Graph *graph = sta->graph(); + return graph->edge(prev_edge_id_)->from(graph); + } + else + return nullptr; +} + +void +Path::setPrevEdgeArc(Edge *prev_edge, + TimingArc *prev_arc, + const StaState *sta) +{ + if (prev_edge) { + const Graph *graph = sta->graph(); + prev_edge_id_ = graph->id(prev_edge); + prev_arc_idx_ = prev_arc->index(); + } + else + 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()) { + Graph *graph = sta->graph(); + Edge *edge = prevEdge(sta); + Vertex *prev_vertex = prev_path_->vertex(sta); + Vertex *prev_edge_vertex = edge->from(graph); + if (prev_vertex != prev_edge_vertex) { + Network *network = sta->network(); + sta->report()->reportLine("path %s prev path corrupted %s vs %s.", + name(sta), + prev_vertex->name(network), + prev_edge_vertex->name(network)); } } +} + +void +Path::setIsEnum(bool is_enum) +{ + is_enum_ = is_enum; +} + +//////////////////////////////////////////////////////////////// + +Path * +Path::vertexPath(const Path &path, + const StaState *sta) +{ + if (!path.isNull()) { + Vertex *vertex = path.vertex(sta); + Tag *tag = path.tag(sta); + return vertexPath(vertex, tag, sta); + } return nullptr; } -//////////////////////////////////////////////////////////////// +Path * +Path::vertexPath(const Vertex *vertex, + Tag *tag, + const StaState *sta) +{ + const Search *search = sta->search(); + TagGroup *tag_group = search->tagGroup(vertex); + if (tag_group) { + size_t path_index; + bool exists; + tag_group->pathIndex(tag, path_index, exists); + if (exists) { + Path *paths = vertex->paths(); + Path &src_vpath = paths[path_index]; + if (!src_vpath.isNull()) + return &src_vpath; + } + } + return nullptr; +} int Path::cmpPinTrClk(const Path *path1, @@ -256,11 +577,9 @@ Path::equal(const Path *path1, const Path *path2, const StaState *sta) { - bool path1_null = (path1 == nullptr || path1->isNull()); - bool path2_null = (path2 == nullptr || path2->isNull()); - return (path1_null && path2_null) - || (!path1_null - && !path2_null + return (path1 == nullptr && path2 == nullptr) + || (path1 + && path2 && path1->vertexId(sta) == path2->vertexId(sta) // Tag equal implies transition and path ap equal. && path1->tagIndex(sta) == path2->tagIndex(sta)); @@ -340,27 +659,27 @@ Path::cmpAll(const Path *path1, const Path *path2, const StaState *sta) { - PathRef p1(path1); - PathRef p2(path2); - while (!p1.isNull() - && !p2.isNull()) { - int cmp = Path::cmp(&p1, &p2, sta); + const Path *p1 = path1; + const Path *p2 = path2; + while (p1 && p2) { + int cmp = Path::cmp(p1, p2, sta); if (cmp != 0) return cmp; - TimingArc *prev_arc1, *prev_arc2; - p1.prevPath(sta, p1, prev_arc1); - p2.prevPath(sta, p2, prev_arc2); - if (equal(&p1, path1, sta)) + TimingArc *prev_arc1 = p1->prevArc(sta); + TimingArc *prev_arc2 = p2->prevArc(sta); + p1 = p1->prevPath(); + p2 = p2->prevPath(); + if (equal(p1, path1, sta)) // Equivalent latch loops. return 0; if ((prev_arc1 && prev_arc1->role()->isLatchDtoQ()) || (prev_arc2 && prev_arc2->role()->isLatchDtoQ())) break; } - if (p1.isNull() && p2.isNull()) + if (p1 == nullptr && p2 == nullptr) return 0; - else if (p1.isNull() && !p2.isNull()) + else if (p1 == nullptr && p2 != nullptr) return -1; else return 1; @@ -374,4 +693,160 @@ Path::lessAll(const Path *path1, return cmpAll(path1, path2, sta) < 0; } +//////////////////////////////////////////////////////////////// + +VertexPathIterator::VertexPathIterator(Vertex *vertex, + const StaState *sta) : + search_(sta->search()), + //filtered_(false), + rf_(nullptr), + path_ap_(nullptr), + min_max_(nullptr), + paths_(vertex->paths()), + path_count_(0), + //path_index_(0), + next_(nullptr) +{ + TagGroup *tag_group = search_->tagGroup(vertex); + if (tag_group) { + path_count_ = tag_group->pathCount(); + path_iter_.init(tag_group->pathIndexMap()); + findNext(); + } +} + +// Iterate over vertex paths with the same transition and +// analysis pt but different but different tags. +VertexPathIterator::VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const PathAnalysisPt *path_ap, + const StaState *sta) : + search_(sta->search()), + //filtered_(true), + rf_(rf), + path_ap_(path_ap), + min_max_(nullptr), + paths_(vertex->paths()), + //path_count_(0), + //path_index_(0), + next_(nullptr) +{ + TagGroup *tag_group = search_->tagGroup(vertex); + if (tag_group) { + path_count_ = tag_group->pathCount(); + path_iter_.init(tag_group->pathIndexMap()); + findNext(); + } +} + +VertexPathIterator::VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const MinMax *min_max, + const StaState *sta) : + search_(sta->search()), + //filtered_(true), + rf_(rf), + path_ap_(nullptr), + min_max_(min_max), + paths_(vertex->paths()), + //path_count_(0), + //path_index_(0), + next_(nullptr) +{ + TagGroup *tag_group = search_->tagGroup(vertex); + if (tag_group) { + path_count_ = tag_group->pathCount(); + path_iter_.init(tag_group->pathIndexMap()); + findNext(); + } +} + +VertexPathIterator::VertexPathIterator(Vertex *vertex, + const RiseFall *rf, + const PathAnalysisPt *path_ap, + const MinMax *min_max, + const StaState *sta) : + search_(sta->search()), + //filtered_(true), + rf_(rf), + path_ap_(path_ap), + min_max_(min_max), + paths_(vertex->paths()), + //path_count_(0), + //path_index_(0), + next_(nullptr) +{ + TagGroup *tag_group = search_->tagGroup(vertex); + if (tag_group) { + path_count_ = tag_group->pathCount(); + path_iter_.init(tag_group->pathIndexMap()); + findNext(); + } +} + +VertexPathIterator::~VertexPathIterator() +{ +} + +bool +VertexPathIterator::hasNext() +{ + return next_ != nullptr; +} + +#if 0 +void +VertexPathIterator::findNext() +{ + while (path_index_ < path_count_) { + Path *path = &paths_[path_index_++]; + if (filtered_) { + const Tag *tag = path->tag(search_); + if ((rf_ == nullptr + || tag->rfIndex() == rf_->index()) + && (path_ap_ == nullptr + || tag->pathAPIndex() == path_ap_->index()) + && (min_max_ == nullptr + || tag->pathAnalysisPt(search_)->pathMinMax() == min_max_)) { + next_ = path; + return; + } + } + else { + next_ = path; + return; + } + } + next_ = nullptr; +} +#endif + +void +VertexPathIterator::findNext() +{ + while (path_iter_.hasNext()) { + Tag *tag; + size_t path_index; + path_iter_.next(tag, path_index); + if ((rf_ == nullptr + || tag->rfIndex() == rf_->index()) + && (path_ap_ == nullptr + || tag->pathAPIndex() == path_ap_->index()) + && (min_max_ == nullptr + || tag->pathAnalysisPt(search_)->pathMinMax() == min_max_)) { + next_ = &paths_[path_index]; + return; + } + } + next_ = nullptr; +} + +Path * +VertexPathIterator::next() +{ + Path *path = next_; + findNext(); + return path; +} + } // namespace diff --git a/search/PathEnd.cc b/search/PathEnd.cc index 9bca45d6..0ca44bc6 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -55,31 +55,32 @@ PathEnd::PathEnd(Path *path) : PathEnd::~PathEnd() { - path_.deleteRep(); + if (path_->isEnum()) + delete path_; } void -PathEnd::setPath(const Path *path) +PathEnd::setPath(Path *path) { - path_.init(path); + path_ = path; } Vertex * PathEnd::vertex(const StaState *sta) const { - return path_.vertex(sta); + return path_->vertex(sta); } const MinMax * PathEnd::minMax(const StaState *sta) const { - return path_.pathAnalysisPt(sta)->pathMinMax(); + return path_->pathAnalysisPt(sta)->pathMinMax(); } const EarlyLate * PathEnd::pathEarlyLate(const StaState *sta) const { - return path_.pathAnalysisPt(sta)->pathMinMax(); + return path_->pathAnalysisPt(sta)->pathMinMax(); } const EarlyLate * @@ -91,31 +92,31 @@ PathEnd::clkEarlyLate(const StaState *sta) const const RiseFall * PathEnd::transition(const StaState *sta) const { - return path_.transition(sta); + return path_->transition(sta); } PathAPIndex PathEnd::pathIndex(const StaState *sta) const { - return path_.pathAnalysisPtIndex(sta); + return path_->pathAnalysisPtIndex(sta); } PathAnalysisPt * PathEnd::pathAnalysisPt(const StaState *sta) const { - return path_.pathAnalysisPt(sta); + return path_->pathAnalysisPt(sta); } const ClockEdge * PathEnd::sourceClkEdge(const StaState *sta) const { - return path_.clkEdge(sta); + return path_->clkEdge(sta); } Arrival -PathEnd::dataArrivalTime(const StaState *sta) const +PathEnd::dataArrivalTime(const StaState *) const { - return path_.arrival(sta); + return path_->arrival(); } Arrival @@ -133,7 +134,7 @@ PathEnd::requiredTimeOffset(const StaState *sta) const const RiseFall * PathEnd::targetClkEndTrans(const StaState *sta) const { - const PathVertex *clk_path = targetClkPath(); + const Path *clk_path = targetClkPath(); if (clk_path) return clk_path->transition(sta); else { @@ -235,13 +236,13 @@ PathEnd::checkRole(const StaState *) const return nullptr; } -PathVertex * +Path * PathEnd::targetClkPath() { return nullptr; } -const PathVertex * +const Path * PathEnd::targetClkPath() const { return nullptr; @@ -303,7 +304,7 @@ PathEnd::exceptPathCmp(const PathEnd *path_end, //////////////////////////////////////////////////////////////// Delay -PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, +PathEnd::checkTgtClkDelay(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta) @@ -315,7 +316,7 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, } void -PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, +PathEnd::checkTgtClkDelay(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta, @@ -340,7 +341,7 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, || check_role->isDataCheck()) { // Propagated clock. Propagated arrival is seeded with // early_late==path_min_max insertion delay. - Arrival clk_arrival = tgt_clk_path->arrival(sta); + Arrival clk_arrival = tgt_clk_path->arrival(); Delay path_insertion = search->clockInsertion(tgt_clk, tgt_src_pin, tgt_clk_rf, min_max, min_max, tgt_path_ap); @@ -359,7 +360,7 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, float PathEnd::checkClkUncertainty(const ClockEdge *src_clk_edge, const ClockEdge *tgt_clk_edge, - const PathVertex *tgt_clk_path, + const Path *tgt_clk_path, const TimingRole *check_role, const StaState *sta) { @@ -375,7 +376,7 @@ PathEnd::checkClkUncertainty(const ClockEdge *src_clk_edge, } float -PathEnd::checkTgtClkUncertainty(const PathVertex *tgt_clk_path, +PathEnd::checkTgtClkUncertainty(const Path *tgt_clk_path, const ClockEdge *tgt_clk_edge, const TimingRole *check_role, const StaState *sta) @@ -455,7 +456,7 @@ PathEndUnconstrained::PathEndUnconstrained(Path *path) : PathEnd * PathEndUnconstrained::copy() { - return new PathEndUnconstrained(path_.path()); + return new PathEndUnconstrained(path_); } bool @@ -510,7 +511,7 @@ PathEndUnconstrained::typeName() const //////////////////////////////////////////////////////////////// PathEndClkConstrained::PathEndClkConstrained(Path *path, - PathVertex *clk_path) : + Path *clk_path) : PathEnd(path), clk_path_(clk_path), crpr_(0.0), @@ -519,7 +520,7 @@ PathEndClkConstrained::PathEndClkConstrained(Path *path, } PathEndClkConstrained::PathEndClkConstrained(Path *path, - PathVertex *clk_path, + Path *clk_path, Crpr crpr, bool crpr_valid) : PathEnd(path), @@ -530,9 +531,9 @@ PathEndClkConstrained::PathEndClkConstrained(Path *path, } void -PathEndClkConstrained::setPath(const Path *path) +PathEndClkConstrained::setPath(Path *path) { - path_.init(path); + path_ = path; crpr_valid_ = false; } @@ -559,33 +560,27 @@ PathEndClkConstrained::sourceClkOffset(const ClockEdge *src_clk_edge, Arrival PathEndClkConstrained::sourceClkLatency(const StaState *sta) const { - ClkInfo *clk_info = path_.clkInfo(sta); + ClkInfo *clk_info = path_->clkInfo(sta); return clk_info->latency(); } Arrival PathEndClkConstrained::sourceClkInsertionDelay(const StaState *sta) const { - ClkInfo *clk_info = path_.clkInfo(sta); + ClkInfo *clk_info = path_->clkInfo(sta); return clk_info->insertion(); } -PathVertex * +Path * PathEndClkConstrained::targetClkPath() { - if (clk_path_.isNull()) - return nullptr; - else - return &clk_path_; + return clk_path_; } -const PathVertex * +const Path * PathEndClkConstrained::targetClkPath() const { - if (clk_path_.isNull()) - return nullptr; - else - return &clk_path_; + return clk_path_; } float @@ -602,8 +597,8 @@ PathEndClkConstrained::targetClkOffset(const StaState *sta) const const ClockEdge * PathEndClkConstrained::targetClkEdge(const StaState *sta) const { - if (!clk_path_.isNull()) - return clk_path_.clkEdge(sta); + if (clk_path_) + return clk_path_->clkEdge(sta); else return nullptr; } @@ -708,7 +703,7 @@ PathEndClkConstrained::crpr(const StaState *sta) const { if (!crpr_valid_) { CheckCrpr *check_crpr = sta->search()->checkCrpr(); - crpr_ = check_crpr->checkCrpr(path_.path(), targetClkPath()); + crpr_ = check_crpr->checkCrpr(path_, targetClkPath()); crpr_valid_ = true; } return crpr_; @@ -751,7 +746,7 @@ PathEndClkConstrained::exceptPathCmp(const PathEnd *path_end, if (cmp == 0) { const PathEndClkConstrained *path_end2 = dynamic_cast(path_end); - const PathVertex *clk_path2 = path_end2->targetClkPath(); + const Path *clk_path2 = path_end2->targetClkPath(); return Path::cmp(targetClkPath(), clk_path2, sta); } else @@ -761,7 +756,7 @@ PathEndClkConstrained::exceptPathCmp(const PathEnd *path_end, //////////////////////////////////////////////////////////////// PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp) : PathEndClkConstrained(path, clk_path), mcp_(mcp) @@ -769,7 +764,7 @@ PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path, } PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid) : @@ -781,7 +776,7 @@ PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path, float PathEndClkConstrainedMcp::targetClkMcpAdjustment(const StaState *sta) const { - return checkMcpAdjustment(path_.path(), targetClkEdge(sta), sta); + return checkMcpAdjustment(path_, targetClkEdge(sta), sta); } float @@ -887,8 +882,8 @@ PathEndClkConstrainedMcp::findHoldMcps(const ClockEdge *tgt_clk_edge, const StaState *sta) const { - Pin *pin = path_.pin(sta); - const RiseFall *rf = path_.transition(sta); + Pin *pin = path_->pin(sta); + const RiseFall *rf = path_->transition(sta); // Mcp may be setup, hold or setup_hold, since all match min paths. const MinMaxAll *mcp_min_max = mcp_->minMax(); Search *search = sta->search(); @@ -896,7 +891,7 @@ PathEndClkConstrainedMcp::findHoldMcps(const ClockEdge *tgt_clk_edge, hold_mcp = mcp_; setup_mcp = dynamic_cast(search->exceptionTo(ExceptionPathType::multi_cycle, - path_.path(), pin, rf, + path_, pin, rf, tgt_clk_edge, MinMax::max(), true, false)); @@ -905,7 +900,7 @@ PathEndClkConstrainedMcp::findHoldMcps(const ClockEdge *tgt_clk_edge, setup_mcp = mcp_; hold_mcp = dynamic_cast(search->exceptionTo(ExceptionPathType::multi_cycle, - path_.path(), pin, rf, + path_, pin, rf, tgt_clk_edge, MinMax::min(), true, false)); @@ -937,7 +932,7 @@ PathEndClkConstrainedMcp::exceptPathCmp(const PathEnd *path_end, PathEndCheck::PathEndCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, const StaState *) : PathEndClkConstrainedMcp(path, clk_path, mcp), @@ -949,7 +944,7 @@ PathEndCheck::PathEndCheck(Path *path, PathEndCheck::PathEndCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid) : @@ -962,8 +957,8 @@ PathEndCheck::PathEndCheck(Path *path, PathEnd * PathEndCheck::copy() { - return new PathEndCheck(path_.path(), check_arc_, check_edge_, - &clk_path_, mcp_, crpr_, crpr_valid_); + return new PathEndCheck(path_, check_arc_, check_edge_, + clk_path_, mcp_, crpr_, crpr_valid_); } PathEnd::Type @@ -999,7 +994,7 @@ PathEndCheck::checkRole(const StaState *) const ArcDelay PathEndCheck::margin(const StaState *sta) const { - return sta->search()->deratedDelay(clk_path_.vertex(sta), + return sta->search()->deratedDelay(clk_path_->vertex(sta), check_arc_, check_edge_, false, pathAnalysisPt(sta)); } @@ -1028,20 +1023,20 @@ PathEndCheck::clkSkew(const StaState *sta) { return sourceClkDelay(sta) - targetClkDelay(sta) - crpr(sta) // Uncertainty decreases slack, but increases skew. - - checkTgtClkUncertainty(&clk_path_, clk_path_.clkEdge(sta), checkRole(sta), sta); + - checkTgtClkUncertainty(clk_path_, clk_path_->clkEdge(sta), + checkRole(sta), sta); } Delay PathEndCheck::sourceClkDelay(const StaState *sta) const { - PathExpanded expanded(&path_, sta); - PathRef src_clk_path; - expanded.clkPath(src_clk_path); - if (!src_clk_path.isNull()) { - ClkInfo *src_clk_info = path_.tag(sta)->clkInfo(); + PathExpanded expanded(path_, sta); + const Path *src_clk_path = expanded.clkPath(); + if (src_clk_path) { + ClkInfo *src_clk_info = path_->tag(sta)->clkInfo(); if (src_clk_info->isPropagated()) { // Propagated clock. Propagated arrival is seeded with insertion delay. - Arrival clk_arrival = src_clk_path.arrival(sta); + Arrival clk_arrival = src_clk_path->arrival(); const ClockEdge *src_clk_edge = src_clk_info->clkEdge(); Delay insertion = sourceClkInsertionDelay(sta); return delayRemove(clk_arrival - src_clk_edge->time(), insertion); @@ -1072,16 +1067,16 @@ PathEndCheck::macroClkTreeDelay(const StaState *sta) const const ClockEdge *tgt_clk_edge = targetClkEdge(sta); const Clock *tgt_clk = tgt_clk_edge->clock(); const Network *network = sta->network(); - const Pin *clk_pin = clk_path_.pin(sta); + const Pin *clk_pin = clk_path_->pin(sta); const Instance *inst = network->instance(clk_pin); const LibertyCell *inst_cell = network->libertyCell(inst); if (tgt_clk->isIdeal() && inst_cell && inst_cell->isMacro()) { LibertyPort *clk_port = network->libertyPort(clk_pin); if (clk_port) { - const MinMax *min_max = clk_path_.minMax(sta); - const RiseFall *rf = clk_path_.transition(sta); - float slew = delayAsFloat(clk_path_.slew(sta)); + const MinMax *min_max = clk_path_->minMax(sta); + const RiseFall *rf = clk_path_->transition(sta); + float slew = delayAsFloat(clk_path_->slew(sta)); return clk_port->clkTreeDelay(slew, rf, min_max); } } @@ -1093,7 +1088,7 @@ PathEndCheck::macroClkTreeDelay(const StaState *sta) const PathEndLatchCheck::PathEndLatchCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *disable_path, + Path *disable_path, MultiCyclePath *mcp, PathDelay *path_delay, const StaState *sta) : @@ -1102,23 +1097,22 @@ PathEndLatchCheck::PathEndLatchCheck(Path *path, path_delay_(path_delay), src_clk_arrival_(0.0) { - PathVertex enable_path; Latches *latches = sta->latches(); - latches->latchEnableOtherPath(disable_path, - disable_path->pathAnalysisPt(sta), - enable_path); + Path *enable_path = + latches->latchEnableOtherPath(disable_path, + disable_path->pathAnalysisPt(sta)); clk_path_ = enable_path; Search *search = sta->search(); // Same as PathEndPathDelay::findRequired. if (path_delay_ && ignoreClkLatency(sta)) - src_clk_arrival_ = search->pathClkPathArrival(&path_); + src_clk_arrival_ = search->pathClkPathArrival(path_); } PathEndLatchCheck::PathEndLatchCheck(Path *path, TimingArc *check_arc, Edge *check_edge, - PathVertex *clk_path, - PathVertex *disable_path, + Path *clk_path, + Path *disable_path, MultiCyclePath *mcp, PathDelay *path_delay, Delay src_clk_arrival, @@ -1134,8 +1128,8 @@ PathEndLatchCheck::PathEndLatchCheck(Path *path, PathEnd * PathEndLatchCheck::copy() { - return new PathEndLatchCheck(path_.path(), check_arc_, check_edge_, - &clk_path_, &disable_path_, mcp_, path_delay_, + return new PathEndLatchCheck(path_, check_arc_, check_edge_, + clk_path_, disable_path_, mcp_, path_delay_, src_clk_arrival_, crpr_, crpr_valid_); } @@ -1151,22 +1145,16 @@ PathEndLatchCheck::typeName() const return "latch_check"; } -PathVertex * +Path * PathEndLatchCheck::latchDisable() { - if (disable_path_.isNull()) - return nullptr; - else - return &disable_path_; + return disable_path_; } -const PathVertex * +const Path * PathEndLatchCheck::latchDisable() const { - if (disable_path_.isNull()) - return nullptr; - else - return &disable_path_; + return disable_path_; } void @@ -1188,7 +1176,7 @@ PathEndLatchCheck::sourceClkOffset(const StaState *sta) const return pathDelaySrcClkOffset(path_, path_delay_, src_clk_arrival_, sta); else return PathEndClkConstrained::sourceClkOffset(sourceClkEdge(sta), - disable_path_.clkEdge(sta), + disable_path_->clkEdge(sta), TimingRole::setup(), sta); } @@ -1196,7 +1184,7 @@ PathEndLatchCheck::sourceClkOffset(const StaState *sta) const TimingRole * PathEndLatchCheck::checkRole(const StaState *sta) const { - if (clk_path_.clkInfo(sta)->isPulseClk()) + if (clk_path_->clkInfo(sta)->isPulseClk()) // Pulse latches use register cycle accounting. return TimingRole::setup(); else @@ -1211,7 +1199,7 @@ PathEndLatchCheck::requiredTime(const StaState *sta) const Required required; Arrival borrow, adjusted_data_arrival, time_given_to_startpoint; Latches *latches = sta->latches(); - latches->latchRequired(path_.path(), targetClkPath(), latchDisable(), + latches->latchRequired(path_, targetClkPath(), latchDisable(), mcp_, path_delay_, src_clk_arrival_, margin(sta), required, borrow, adjusted_data_arrival, time_given_to_startpoint); @@ -1224,7 +1212,7 @@ PathEndLatchCheck::borrow(const StaState *sta) const Latches *latches = sta->latches(); Required required; Arrival borrow, adjusted_data_arrival, time_given_to_startpoint; - latches->latchRequired(path_.path(), targetClkPath(), latchDisable(), + latches->latchRequired(path_, targetClkPath(), latchDisable(), mcp_, path_delay_, src_clk_arrival_, margin(sta), required, borrow, adjusted_data_arrival, time_given_to_startpoint); @@ -1240,7 +1228,7 @@ PathEndLatchCheck::latchRequired(const StaState *sta, Delay &time_given_to_startpoint) const { Latches *latches = sta->latches(); - latches->latchRequired(path_.path(), targetClkPath(), latchDisable(), + latches->latchRequired(path_, targetClkPath(), latchDisable(), mcp_, path_delay_, src_clk_arrival_, margin(sta), required, borrow, adjusted_data_arrival, time_given_to_startpoint); @@ -1259,7 +1247,7 @@ PathEndLatchCheck::latchBorrowInfo(const StaState *sta, bool &borrow_limit_exists) const { Latches *latches = sta->latches(); - latches->latchBorrowInfo(path_.path(), targetClkPath(), latchDisable(), + latches->latchBorrowInfo(path_, targetClkPath(), latchDisable(), margin(sta), path_delay_ && ignoreClkLatency(sta), nom_pulse_width, open_latency, @@ -1272,9 +1260,9 @@ Arrival PathEndLatchCheck::targetClkWidth(const StaState *sta) const { const Search *search = sta->search(); - Arrival disable_arrival = search->clkPathArrival(&disable_path_); - Arrival enable_arrival = search->clkPathArrival(&clk_path_); - ClkInfo *enable_clk_info = clk_path_.clkInfo(sta); + Arrival disable_arrival = search->clkPathArrival(disable_path_); + Arrival enable_arrival = search->clkPathArrival(clk_path_); + ClkInfo *enable_clk_info = clk_path_->clkInfo(sta); if (enable_clk_info->isPulseClk()) return disable_arrival - enable_arrival; else { @@ -1297,8 +1285,8 @@ PathEndLatchCheck::exceptPathCmp(const PathEnd *path_end, dynamic_cast(path_end); const TimingArc *check_arc2 = path_end2->check_arc_; if (check_arc_ == check_arc2) { - const Path *disable_path2 = path_end2->disable_path_.path(); - return Path::cmp(disable_path_.path(), disable_path2, sta); + const Path *disable_path2 = path_end2->disable_path_; + return Path::cmp(disable_path_, disable_path2, sta); } else if (check_arc_ < check_arc2) return -1; @@ -1319,7 +1307,7 @@ PathEndLatchCheck::ignoreClkLatency(const StaState *sta) const PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, const StaState *) : // No target clk_path_ for output delays. @@ -1330,7 +1318,7 @@ PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay, PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid) : @@ -1342,7 +1330,7 @@ PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay, PathEnd * PathEndOutputDelay::copy() { - return new PathEndOutputDelay(output_delay_, path_.path(), &clk_path_, + return new PathEndOutputDelay(output_delay_, path_, clk_path_, mcp_, crpr_, crpr_valid_); } @@ -1373,7 +1361,7 @@ PathEndOutputDelay::reportShort(const ReportPath *report) const ArcDelay PathEndOutputDelay::margin(const StaState *sta) const { - return outputDelayMargin(output_delay_, path_.path(), sta); + return outputDelayMargin(output_delay_, path_, sta); } float @@ -1393,7 +1381,7 @@ PathEnd::outputDelayMargin(OutputDelay *output_delay, TimingRole * PathEndOutputDelay::checkRole(const StaState *sta) const { - if (path_.minMax(sta) == MinMax::max()) + if (path_->minMax(sta) == MinMax::max()) return TimingRole::outputSetup(); else return TimingRole::outputHold(); @@ -1402,8 +1390,8 @@ PathEndOutputDelay::checkRole(const StaState *sta) const const ClockEdge * PathEndOutputDelay::targetClkEdge(const StaState *sta) const { - if (!clk_path_.isNull()) - return clk_path_.clkEdge(sta); + if (clk_path_) + return clk_path_->clkEdge(sta); else return output_delay_->clkEdge(); } @@ -1411,7 +1399,7 @@ PathEndOutputDelay::targetClkEdge(const StaState *sta) const Arrival PathEndOutputDelay::targetClkArrivalNoCrpr(const StaState *sta) const { - if (!clk_path_.isNull()) + if (clk_path_) return PathEndClkConstrained::targetClkArrivalNoCrpr(sta); else { const ClockEdge *tgt_clk_edge = targetClkEdge(sta); @@ -1419,7 +1407,7 @@ PathEndOutputDelay::targetClkArrivalNoCrpr(const StaState *sta) const return targetClkTime(sta) + tgtClkDelay(tgt_clk_edge, check_role, sta) + targetClkUncertainty(sta) - + checkMcpAdjustment(path_.path(), tgt_clk_edge, sta); + + checkMcpAdjustment(path_, tgt_clk_edge, sta); } } @@ -1428,7 +1416,7 @@ PathEndOutputDelay::crpr(const StaState *sta) const { if (!crpr_valid_) { CheckCrpr *check_crpr = sta->search()->checkCrpr(); - crpr_ = check_crpr->outputDelayCrpr(path_.path(), targetClkEdge(sta)); + crpr_ = check_crpr->outputDelayCrpr(path_, targetClkEdge(sta)); crpr_valid_ = true; } return crpr_; @@ -1437,7 +1425,7 @@ PathEndOutputDelay::crpr(const StaState *sta) const Delay PathEndOutputDelay::targetClkDelay(const StaState *sta) const { - if (!clk_path_.isNull()) + if (clk_path_) return PathEndClkConstrained::targetClkDelay(sta); else return tgtClkDelay(targetClkEdge(sta), checkRole(sta), sta); @@ -1465,7 +1453,7 @@ PathEndOutputDelay::tgtClkDelay(const ClockEdge *tgt_clk_edge, // Early late: setup early, hold late. const EarlyLate *early_late = check_role->tgtClkEarlyLate(); // Latency min_max depends on bc_wc or ocv. - const PathAnalysisPt *path_ap = path_.pathAnalysisPt(sta); + const PathAnalysisPt *path_ap = path_->pathAnalysisPt(sta); const MinMax *latency_min_max = path_ap->tgtClkAnalysisPt()->pathMinMax(); Clock *tgt_clk = tgt_clk_edge->clock(); RiseFall *tgt_clk_rf = tgt_clk_edge->transition(); @@ -1488,7 +1476,7 @@ PathEndOutputDelay::tgtClkDelay(const ClockEdge *tgt_clk_edge, Delay PathEndOutputDelay::targetClkInsertionDelay(const StaState *sta) const { - if (!clk_path_.isNull()) + if (clk_path_) return PathEndClkConstrained::targetClkInsertionDelay(sta); else { Arrival insertion, latency; @@ -1521,7 +1509,7 @@ PathEndOutputDelay::exceptPathCmp(const PathEnd *path_end, //////////////////////////////////////////////////////////////// PathEndGatedClock::PathEndGatedClock(Path *gating_ref, - PathVertex *clk_path, + Path *clk_path, TimingRole *check_role, MultiCyclePath *mcp, ArcDelay margin, @@ -1533,7 +1521,7 @@ PathEndGatedClock::PathEndGatedClock(Path *gating_ref, } PathEndGatedClock::PathEndGatedClock(Path *gating_ref, - PathVertex *clk_path, + Path *clk_path, TimingRole *check_role, MultiCyclePath *mcp, ArcDelay margin, @@ -1548,7 +1536,7 @@ PathEndGatedClock::PathEndGatedClock(Path *gating_ref, PathEnd * PathEndGatedClock::copy() { - return new PathEndGatedClock(path_.path(), &clk_path_, check_role_, + return new PathEndGatedClock(path_, clk_path_, check_role_, mcp_, margin_, crpr_, crpr_valid_); } @@ -1606,59 +1594,52 @@ PathEndGatedClock::exceptPathCmp(const PathEnd *path_end, PathEndDataCheck::PathEndDataCheck(DataCheck *check, Path *data_path, - PathVertex *data_clk_path, + Path *data_clk_path, MultiCyclePath *mcp, const StaState *sta) : PathEndClkConstrainedMcp(data_path, nullptr, mcp), data_clk_path_(data_clk_path), check_(check) { - clkPath(data_clk_path, sta, clk_path_); + clk_path_ = clkPath(data_clk_path, sta); } // PathExpanded::expand() and PathExpanded::clkPath(). -void -PathEndDataCheck::clkPath(PathVertex *path, - const StaState *sta, - // Return value. - PathVertex &clk_path) +Path * +PathEndDataCheck::clkPath(Path *path, + const StaState *sta) { - PathVertex p(path); - while (!p.isNull()) { - PathVertex prev_path; - TimingArc *prev_arc; - p.prevPath(sta, prev_path, prev_arc); + Path *p = path; + while (p) { + Path *prev_path = p->prevPath(); + TimingArc *prev_arc = p->prevArc(sta); - if (p.isClock(sta)) { - clk_path = p; - return; - } + if (p->isClock(sta)) + return p; if (prev_arc) { TimingRole *prev_role = prev_arc->role(); if (prev_role == TimingRole::regClkToQ() || prev_role == TimingRole::latchEnToQ()) { - p.prevPath(sta, prev_path, prev_arc); - clk_path = prev_path; - return; + prev_path = p->prevPath(); + return prev_path; } else if (prev_role == TimingRole::latchDtoQ()) { const Latches *latches = sta->latches(); - Edge *prev_edge = p.prevEdge(prev_arc, sta); - PathVertex enable_path; - latches->latchEnablePath(&p, prev_edge, enable_path); - clk_path = enable_path; - return; + Edge *prev_edge = p->prevEdge(sta); + Path *enable_path = latches->latchEnablePath(p, prev_edge); + return enable_path; } } p = prev_path; } + return nullptr; } PathEndDataCheck::PathEndDataCheck(DataCheck *check, Path *data_path, - PathVertex *data_clk_path, - PathVertex *clk_path, + Path *data_clk_path, + Path *clk_path, MultiCyclePath *mcp, Crpr crpr, bool crpr_valid) : @@ -1671,8 +1652,8 @@ PathEndDataCheck::PathEndDataCheck(DataCheck *check, PathEnd * PathEndDataCheck::copy() { - return new PathEndDataCheck(check_, path_.path(), &data_clk_path_, - &clk_path_, mcp_, crpr_, crpr_valid_); + return new PathEndDataCheck(check_, path_, data_clk_path_, + clk_path_, mcp_, crpr_, crpr_valid_); } PathEnd::Type @@ -1691,14 +1672,14 @@ const ClockEdge * PathEndDataCheck::targetClkEdge(const StaState *sta) const { // clk_path_ can be null if data_clk_path is from an input port. - return data_clk_path_.clkEdge(sta); + return data_clk_path_->clkEdge(sta); } Arrival PathEndDataCheck::requiredTimeNoCrpr(const StaState *sta) const { - Arrival data_clk_arrival = data_clk_path_.arrival(sta); - float data_clk_time = data_clk_path_.clkEdge(sta)->time(); + Arrival data_clk_arrival = data_clk_path_->arrival(); + float data_clk_time = data_clk_path_->clkEdge(sta)->time(); Arrival data_clk_delay = data_clk_arrival - data_clk_time; Arrival tgt_clk_arrival = targetClkTime(sta) + data_clk_delay @@ -1717,9 +1698,9 @@ PathEndDataCheck::margin(const StaState *sta) const { float margin; bool margin_exists; - check_->margin(data_clk_path_.transition(sta), - path_.transition(sta), - path_.minMax(sta), + check_->margin(data_clk_path_->transition(sta), + path_->transition(sta), + path_->minMax(sta), margin, margin_exists); return margin; } @@ -1727,7 +1708,7 @@ PathEndDataCheck::margin(const StaState *sta) const TimingRole * PathEndDataCheck::checkRole(const StaState *sta) const { - if (path_.minMax(sta) == MinMax::max()) + if (path_->minMax(sta) == MinMax::max()) return TimingRole::dataCheckSetup(); else return TimingRole::dataCheckHold(); @@ -1794,7 +1775,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, TimingArc *check_arc, Edge *check_edge, const StaState *sta) : @@ -1809,7 +1790,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, Path *path, - PathVertex *clk_path, + Path *clk_path, TimingArc *check_arc, Edge *check_edge, OutputDelay *output_delay, @@ -1828,7 +1809,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay, PathEnd * PathEndPathDelay::copy() { - return new PathEndPathDelay(path_delay_, path_.path(), &clk_path_, + return new PathEndPathDelay(path_delay_, path_, clk_path_, check_arc_, check_edge_, output_delay_, src_clk_arrival_, crpr_, crpr_valid_); } @@ -1850,7 +1831,7 @@ PathEndPathDelay::findSrcClkArrival(const StaState *sta) { if (ignoreClkLatency(sta)) { Search *search = sta->search(); - src_clk_arrival_ = search->pathClkPathArrival(&path_); + src_clk_arrival_ = search->pathClkPathArrival(path_); } else src_clk_arrival_ = 0.0; @@ -1895,7 +1876,7 @@ PathEndPathDelay::margin(const StaState *sta) const pathAnalysisPt(sta)); } else if (output_delay_) - return outputDelayMargin(output_delay_, path_.path(), sta); + return outputDelayMargin(output_delay_, path_, sta); else return delay_zero; } @@ -1914,13 +1895,13 @@ PathEnd::clkSkew(const StaState *) // Helper shared by PathEndLatchCheck. float -PathEnd::pathDelaySrcClkOffset(const PathRef &path, +PathEnd::pathDelaySrcClkOffset(const Path *path, PathDelay *path_delay, Arrival src_clk_arrival, const StaState *sta) { float offset = 0.0; - const ClockEdge *clk_edge = path.clkEdge(sta); + const ClockEdge *clk_edge = path->clkEdge(sta); if (clk_edge) { if (ignoreClkLatency(path, path_delay, sta)) offset = -delayAsFloat(src_clk_arrival); @@ -1933,18 +1914,18 @@ PathEnd::pathDelaySrcClkOffset(const PathRef &path, } bool -PathEnd::ignoreClkLatency(const PathRef &path, +PathEnd::ignoreClkLatency(const Path *path, PathDelay *path_delay, const StaState *sta) { - return path_delay->ignoreClkLatency() && !path.isClock(sta); + return path_delay->ignoreClkLatency() && !path->isClock(sta); } const ClockEdge * PathEndPathDelay::targetClkEdge(const StaState *sta) const { - if (!clk_path_.isNull()) - return clk_path_.clkEdge(sta); + if (clk_path_) + return clk_path_->clkEdge(sta); else if (output_delay_) return output_delay_->clkEdge(); else @@ -1968,8 +1949,8 @@ PathEndPathDelay::targetClkArrivalNoCrpr(const StaState *sta) const if (tgt_clk_edge) return targetClkDelay(sta) + targetClkUncertainty(sta); - else if (!clk_path_.isNull()) - return clk_path_.arrival(sta); + else if (clk_path_) + return clk_path_->arrival(); else return 0.0; } @@ -1985,8 +1966,8 @@ PathEndPathDelay::requiredTime(const StaState *sta) const { float delay = path_delay_->delay(); if (path_delay_->ignoreClkLatency()) { - Required src_offset = path_.isClock(sta) - ? path_.clkEdge(sta)->time() + Required src_offset = path_->isClock(sta) + ? path_->clkEdge(sta)->time() : src_clk_arrival_; return src_offset + delay + ((minMax(sta) == MinMax::max()) ? -margin(sta) : margin(sta)); diff --git a/search/PathEnum.cc b/search/PathEnum.cc index a8dd572c..dd4c4a1f 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -36,8 +36,7 @@ #include "Tag.hh" #include "Search.hh" #include "PathEnd.hh" -#include "PathRef.hh" -#include "PathEnumed.hh" +#include "Path.hh" namespace sta { @@ -104,8 +103,8 @@ deleteDiversionPathEnd(Diversion *div) //////////////////////////////////////////////////////////////// -PathEnum::PathEnum(int group_path_count, - int endpoint_path_count, +PathEnum::PathEnum(size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, bool cmp_slack, const StaState *sta) : @@ -214,17 +213,16 @@ PathEnum::reportDiversionPath(Diversion *div) { PathEnd *path_end = div->pathEnd(); Path *path = path_end->path(); - PathRef p; - path->prevPath(this, p); + Path *p = path->prevPath(); Path *after_div = div->divPath(); - while (!p.isNull()) { + while (p) { report_->reportLine("path_enum: %s %s%s", - p.name(this), - delayAsString(p.arrival(this), this), - Path::equal(&p, after_div, this) ? " <-diversion" : ""); - if (network_->isLatchData(p.pin(this))) + p->name(this), + delayAsString(p->arrival(), this), + Path::equal(p, after_div, this) ? " <-diversion" : ""); + if (network_->isLatchData(p->pin(this))) break; - p.prevPath(this, p); + p = p->prevPath(); } } @@ -234,19 +232,19 @@ class PathEnumFaninVisitor : public PathVisitor { public: PathEnumFaninVisitor(PathEnd *path_end, - PathRef &before_div, + Path *before_div, bool unique_pins, PathEnum *path_enum); virtual VertexVisitor *copy() const; virtual void visit(Vertex *) {} // Not used. - void visitFaninPathsThru(Vertex *vertex, + void visitFaninPathsThru(Path *before_div, Vertex *prev_vertex, TimingArc *prev_arc); virtual bool visitFromToPath(const Pin *from_pin, Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, @@ -260,16 +258,18 @@ public: private: void makeDivertedPathEnd(Path *after_div, + Edge *div_edge, TimingArc *div_arc, // Return values. PathEnd *&div_end, - PathEnumed *&after_div_copy); - void reportDiversion(TimingArc *div_arc, + Path *&after_div_copy); + void reportDiversion(const Edge *edge, + const TimingArc *div_arc, Path *after_div); PathEnd *path_end_; Slack path_end_slack_; - PathRef &before_div_; + Path *before_div_; bool unique_pins_; int before_div_rf_index_; Tag *before_div_tag_; @@ -282,7 +282,7 @@ private: }; PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end, - PathRef &before_div, + Path *before_div, bool unique_pins, PathEnum *path_enum) : PathVisitor(path_enum), @@ -290,27 +290,28 @@ PathEnumFaninVisitor::PathEnumFaninVisitor(PathEnd *path_end, path_end_slack_(path_end->slack(this)), before_div_(before_div), unique_pins_(unique_pins), - before_div_rf_index_(before_div_.rfIndex(this)), - before_div_tag_(before_div_.tag(this)), - before_div_ap_index_(before_div_.pathAnalysisPtIndex(this)), - before_div_arrival_(before_div_.arrival(this)), + before_div_rf_index_(before_div_->rfIndex(this)), + before_div_tag_(before_div_->tag(this)), + before_div_ap_index_(before_div_->pathAnalysisPtIndex(this)), + before_div_arrival_(before_div_->arrival()), path_enum_(path_enum), crpr_active_(sdc_->crprActive()) { } void -PathEnumFaninVisitor::visitFaninPathsThru(Vertex *vertex, +PathEnumFaninVisitor::visitFaninPathsThru(Path *before_div, Vertex *prev_vertex, TimingArc *prev_arc) { - before_div_rf_index_ = before_div_.rfIndex(this); - before_div_tag_ = before_div_.tag(this); - before_div_ap_index_ = before_div_.pathAnalysisPtIndex(this); - before_div_arrival_ = before_div_.arrival(this); + before_div_ = before_div; + before_div_rf_index_ = before_div_->rfIndex(this); + before_div_tag_ = before_div_->tag(this); + before_div_ap_index_ = before_div_->pathAnalysisPtIndex(this); + before_div_arrival_ = before_div_->arrival(); prev_arc_ = prev_arc; prev_vertex_ = prev_vertex; - visitFaninPaths(vertex); + visitFaninPaths(before_div_->vertex(this)); } VertexVisitor * @@ -325,7 +326,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, Vertex *from_vertex, const RiseFall *, Tag *, - PathVertex *from_path, + Path *from_path, const Arrival &, Edge *edge, TimingArc *arc, @@ -351,13 +352,13 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, && tagMatchNoCrpr(to_tag, before_div_tag_)) { if (crpr_active_) { PathEnd *div_end; - PathEnumed *after_div_copy; + Path *after_div_copy; // Make the diverted path end to check slack with from_path crpr. - makeDivertedPathEnd(from_path, arc, div_end, after_div_copy); + makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy); if (div_end) { // Only enumerate paths with greater slack. if (delayGreaterEqual(div_end->slack(this), path_end_slack_, this)) { - reportDiversion(arc, from_path); + reportDiversion(edge, arc, from_path); path_enum_->makeDiversion(div_end, after_div_copy); } else @@ -367,9 +368,9 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, // Only enumerate slower/faster paths. else if (delayLessEqual(to_arrival, before_div_arrival_, min_max, this)) { PathEnd *div_end; - PathEnumed *after_div_copy; - makeDivertedPathEnd(from_path, arc, div_end, after_div_copy); - reportDiversion(arc, from_path); + Path *after_div_copy; + makeDivertedPathEnd(from_path, edge, arc, div_end, after_div_copy); + reportDiversion(edge, arc, from_path); path_enum_->makeDiversion(div_end, after_div_copy); } } @@ -378,14 +379,15 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *, void PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div, + Edge *div_edge, TimingArc *div_arc, // Return values. PathEnd *&div_end, - PathEnumed *&after_div_copy) + Path *&after_div_copy) { - PathEnumed *div_path; - path_enum_->makeDivertedPath(path_end_->path(), &before_div_, after_div, - div_arc, div_path, after_div_copy); + Path *div_path; + path_enum_->makeDivertedPath(path_end_->path(), before_div_, after_div, + div_edge, div_arc, div_path, after_div_copy); if (after_div_copy) { div_end = path_end_->copy(); div_end->setPath(div_path); @@ -395,7 +397,8 @@ PathEnumFaninVisitor::makeDivertedPathEnd(Path *after_div, } void -PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc, +PathEnumFaninVisitor::reportDiversion(const Edge *div_edge, + const TimingArc *div_arc, Path *after_div) { if (debug_->check("path_enum", 3)) { @@ -404,19 +407,18 @@ PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc, Arrival path_delay = path_enum_->cmp_slack_ ? path_end_->slack(this) : path_end_->dataArrivalTime(this); - Arrival div_delay = path_delay - path_enum_->divSlack(&before_div_, - after_div, - div_arc, path_ap); - PathRef div_prev; - before_div_.prevPath(this, div_prev); + Arrival div_delay = path_delay - path_enum_->divSlack(before_div_, + after_div, div_edge, + div_arc, path_ap); + Path *div_prev = before_div_->prevPath(); report_->reportLine("path_enum: diversion %s %s %s -> %s", path->name(this), path_enum_->cmp_slack_ ? "slack" : "delay", delayAsString(path_delay, this), delayAsString(div_delay, this)); report_->reportLine("path_enum: from %s -> %s", - div_prev.name(this), - before_div_.name(this)); + div_prev->name(this), + before_div_->name(this)); report_->reportLine("path_enum: to %s", after_div->name(this)); } @@ -431,13 +433,13 @@ PathEnumFaninVisitor::reportDiversion(TimingArc *div_arc, // <--...--before_div<--...--path<---path_end void PathEnum::makeDiversion(PathEnd *div_end, - PathEnumed *after_div_copy) + Path *after_div_copy) { Diversion *div = new Diversion(div_end, after_div_copy); div_queue_.push(div); div_count_++; - if (static_cast(div_queue_.size()) > group_path_count_ * 2) + if (div_queue_.size() > group_path_count_ * 2) // We have more potenial paths than we will need. pruneDiversionQueue(); } @@ -447,7 +449,7 @@ PathEnum::pruneDiversionQueue() { debugPrint(debug_, "path_enum", 2, "prune queue"); VertexPathCountMap path_counts; - int end_count = 0; + size_t end_count = 0; // Collect endpoint_path_count diversions per vertex. DiversionSeq divs; while (!div_queue_.empty()) { @@ -476,11 +478,11 @@ PathEnum::pruneDiversionQueue() Arrival PathEnum::divSlack(Path *before_div, Path *after_div, - TimingArc *div_arc, + const Edge *div_edge, + const TimingArc *div_arc, const PathAnalysisPt *path_ap) { - Arrival arc_arrival = before_div->arrival(this); - Edge *div_edge = divEdge(before_div, div_arc); + Arrival arc_arrival = before_div->arrival(); if (div_edge) { ArcDelay div_delay = search_->deratedDelay(div_edge->from(graph_), div_arc, div_edge, @@ -494,45 +496,30 @@ PathEnum::divSlack(Path *before_div, } } -Edge * -PathEnum::divEdge(Path *before_div, - TimingArc *div_arc) -{ - TimingArcSet *arc_set = div_arc->set(); - VertexInEdgeIterator edge_iter(before_div->vertex(this), graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->timingArcSet() == arc_set) - return edge; - } - return nullptr; -} - // Make diversions for all arcs that merge into path for paths // starting at "before" to the beginning of the path. void PathEnum::makeDiversions(PathEnd *path_end, Path *before) { - PathRef path(before); - PathRef prev_path; - TimingArc *prev_arc; - path.prevPath(this, prev_path, prev_arc); + Path *path = before; + Path *prev_path = path->prevPath(); + TimingArc *prev_arc = path->prevArc(this); PathEnumFaninVisitor fanin_visitor(path_end, path, unique_pins_, this); - while (prev_arc + while (prev_path // Do not enumerate paths in the clk network. - && !path.isClock(this)) { + && !path->isClock(this)) { // Fanin visitor does all the work. // While visiting the fanins the fanin_visitor finds the // previous path and arc as well as diversions. - fanin_visitor.visitFaninPathsThru(path.vertex(this), - prev_path.vertex(this), prev_arc); + fanin_visitor.visitFaninPathsThru(path, prev_path->vertex(this), prev_arc); // Do not enumerate beyond latch D to Q edges. // This breaks latch loop paths. if (prev_arc->role() == TimingRole::latchDtoQ()) break; - path.init(prev_path); - path.prevPath(this, prev_path, prev_arc); + path = prev_path; + prev_path = path->prevPath(); + prev_arc = path->prevArc(this); } } @@ -540,47 +527,52 @@ void PathEnum::makeDivertedPath(Path *path, Path *before_div, Path *after_div, + Edge *div_edge, TimingArc *div_arc, // Returned values. - PathEnumed *&div_path, - PathEnumed *&after_div_copy) + Path *&div_path, + Path *&after_div_copy) { div_path = nullptr; after_div_copy = nullptr; // Copy the diversion path. bool found_div = false; - PathEnumedSeq copies; - PathRef p(path); + PathSeq copies; + Path *p = path; bool first = true; - PathEnumed *prev_copy = nullptr; - while (!p.isNull()) { - PathRef prev; - TimingArc *prev_arc; - p.prevPath(this, prev, prev_arc); - PathEnumed *copy = new PathEnumed(p.vertexId(this), - p.tagIndex(this), - p.arrival(this), - nullptr, // prev_path made in next pass. - prev_arc); + Path *prev_copy = nullptr; + while (p) { + // prev_path made in next pass. + Path *copy = new Path(p->vertex(this), + p->tag(this), + p->arrival(), + // Replaced on next pass. + p->prevPath(), + p->prevEdge(this), + p->prevArc(this), + true, this); if (prev_copy) prev_copy->setPrevPath(copy); copies.push_back(copy); - if (Path::equal(&p, after_div, this)) + if (Path::equal(p, after_div, this)) after_div_copy = copy; if (first) div_path = copy; - else if (network_->isLatchData(p.pin(this))) + else if (network_->isLatchData(p->pin(this))) break; - if (Path::equal(&p, before_div, this)) { - copy->setPrevArc(div_arc); + if (Path::equal(p, before_div, this)) { + // Replaced on next pass. + copy->setPrevPath(after_div); + copy->setPrevEdgeArc(div_edge, div_arc, this); // Update the delays forward from before_div to the end of the path. updatePathHeadDelays(copies, after_div); - p.init(after_div); + p = after_div; found_div = true; } else - p.init(prev); + p = p->prevPath(); + prev_copy = copy; first = false; } @@ -589,16 +581,16 @@ PathEnum::makeDivertedPath(Path *path, } void -PathEnum::updatePathHeadDelays(PathEnumedSeq &paths, +PathEnum::updatePathHeadDelays(PathSeq &paths, Path *after_div) { Tag *prev_tag = after_div->tag(this); ClkInfo *prev_clk_info = prev_tag->clkInfo(); Arrival prev_arrival = search_->clkPathArrival(after_div); for (int i = paths.size() - 1; i >= 0; i--) { - PathEnumed *path = paths[i]; + Path *path = paths[i]; TimingArc *arc = path->prevArc(this); - Edge *edge = path->prevEdge(arc, this); + Edge *edge = path->prevEdge(this); if (edge) { PathAnalysisPt *path_ap = path->pathAnalysisPt(this); ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_), @@ -607,9 +599,9 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths, debugPrint(debug_, "path_enum", 5, "update arrival %s %s %s -> %s", path->vertex(this)->name(network_), path->tag(this)->asString(this), - delayAsString(path->arrival(this), this), + delayAsString(path->arrival(), this), delayAsString(arrival, this)); - path->setArrival(arrival, this); + path->setArrival(arrival); prev_arrival = arrival; if (sdc_->crprActive() // D->Q paths use the EN->Q clk info so no need to update. diff --git a/search/PathEnum.hh b/search/PathEnum.hh index 859cef80..b48b0d32 100644 --- a/search/PathEnum.hh +++ b/search/PathEnum.hh @@ -36,11 +36,9 @@ namespace sta { class Diversion; class PathEnumFaninVisitor; -class PathEnumed; class DiversionGreater; typedef Vector DiversionSeq; -typedef Vector PathEnumedSeq; typedef std::priority_queue DiversionQueue; @@ -60,8 +58,8 @@ private: class PathEnum : public Iterator, StaState { public: - PathEnum(int group_path_count, - int endpoint_path_count, + PathEnum(size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, bool cmp_slack, const StaState *sta); @@ -75,29 +73,29 @@ private: void makeDiversions(PathEnd *path_end, Path *before); void makeDiversion(PathEnd *div_end, - PathEnumed *after_div_copy); + Path *after_div_copy); void makeDivertedPath(Path *path, Path *before_div, Path *after_div, + Edge *div_edge, TimingArc *div_arc, // Returned values. - PathEnumed *&div_path, - PathEnumed *&after_div_copy); - void updatePathHeadDelays(PathEnumedSeq &path, + Path *&div_path, + Path *&after_div_copy); + void updatePathHeadDelays(PathSeq &path, Path *after_div); Arrival divSlack(Path *path, Path *after_div, - TimingArc *div_arc, + const Edge *div_edge, + const TimingArc *div_arc, const PathAnalysisPt *path_ap); void reportDiversionPath(Diversion *div); void pruneDiversionQueue(); - Edge *divEdge(Path *before_div, - TimingArc *div_arc); void findNext(); bool cmp_slack_; - int group_path_count_; - int endpoint_path_count_; + size_t group_path_count_; + size_t endpoint_path_count_; bool unique_pins_; DiversionQueue div_queue_; int div_count_; diff --git a/search/PathEnumed.cc b/search/PathEnumed.cc deleted file mode 100644 index 3c0adc87..00000000 --- a/search/PathEnumed.cc +++ /dev/null @@ -1,192 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "PathEnumed.hh" - -#include "Set.hh" -#include "Graph.hh" -#include "Corner.hh" -#include "Search.hh" -#include "Tag.hh" -#include "PathRef.hh" - -namespace sta { - -PathEnumed:: PathEnumed(VertexId vertex_id, - TagIndex tag_index, - Arrival arrival, - PathEnumed *prev_path, - TimingArc *prev_arc) : - Path(), - prev_path_(prev_path), - prev_arc_(prev_arc), - arrival_(arrival), - vertex_id_(vertex_id), - tag_index_(tag_index) -{ -} - -void -deletePathEnumed(PathEnumed *path) -{ - while (path) { - PathEnumed *prev = path->prevPathEnumed(); - delete path; - path = prev; - } -} - -void -PathEnumed::setRef(PathRef *ref) const -{ - ref->init(const_cast(this)); -} - -Vertex * -PathEnumed::vertex(const StaState *sta) const -{ - const Graph *graph = sta->graph(); - return graph->vertex(vertex_id_); -} - -VertexId -PathEnumed::vertexId(const StaState *) const -{ - return vertex_id_; -} - -Tag * -PathEnumed::tag(const StaState *sta) const -{ - const Search *search = sta->search(); - return search->tag(tag_index_); -} - -void -PathEnumed::setTag(Tag *tag) -{ - tag_index_ = tag->index(); -} - -const RiseFall * -PathEnumed::transition(const StaState *sta) const -{ - return tag(sta)->transition(); -} - -int -PathEnumed::trIndex(const StaState *sta) const -{ - return tag(sta)->rfIndex(); -} - -PathAnalysisPt * -PathEnumed::pathAnalysisPt(const StaState *sta) const -{ - const Corners *corners = sta->corners(); - return corners->findPathAnalysisPt(pathAnalysisPtIndex(sta)); -} - -PathAPIndex -PathEnumed::pathAnalysisPtIndex(const StaState *sta) const -{ - return tag(sta)->pathAPIndex(); -} - -Arrival -PathEnumed::arrival(const StaState *) const -{ - return arrival_; -} - -void -PathEnumed::setArrival(Arrival arrival, - const StaState *) -{ - arrival_ = arrival; -} - -const Required & -PathEnumed::required(const StaState *sta) const -{ - // Required times are never needed for enumerated paths. - sta->report()->critical(1380, "enumerated path required time"); - return delay_zero; -} - -void -PathEnumed::setRequired(const Required &, - const StaState *sta) -{ - // Required times are never needed for enumerated paths. - sta->report()->critical(1381, "enumerated path required time"); -} - -Path * -PathEnumed::prevPath(const StaState *) const -{ - return prev_path_; -} - -void -PathEnumed::prevPath(const StaState *, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const -{ - if (prev_path_) { - prev_path_->setRef(prev_path); - prev_arc = prev_arc_; - } - else { - prev_path.init(); - prev_arc = nullptr; - } -} - -TimingArc * -PathEnumed::prevArc(const StaState *) const -{ - return prev_arc_; -} - -PathEnumed * -PathEnumed::prevPathEnumed() const -{ - return prev_path_; -} - -void -PathEnumed::setPrevPath(PathEnumed *prev) -{ - prev_path_ = prev; -} - -void -PathEnumed::setPrevArc(TimingArc *arc) -{ - prev_arc_ = arc; -} - -} // namespace diff --git a/search/PathEnumed.hh b/search/PathEnumed.hh deleted file mode 100644 index 8613ed69..00000000 --- a/search/PathEnumed.hh +++ /dev/null @@ -1,80 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include "Path.hh" - -namespace sta { - -// Implements Path API for paths returned by PathEnum. -class PathEnumed : public Path -{ -public: - PathEnumed(VertexId vertex_id, - TagIndex tag_index, - Arrival arrival, - PathEnumed *prev_path, - TimingArc *prev_arc); - virtual void setRef(PathRef *ref) const; - virtual bool isNull() const { return vertex_id_ == 0; } - virtual Vertex *vertex(const StaState *sta) const; - virtual VertexId vertexId(const StaState *sta) const; - virtual Tag *tag(const StaState *sta) const; - virtual const RiseFall *transition(const StaState *sta) const; - virtual int trIndex(const StaState *) const; - virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const; - virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const; - virtual Arrival arrival(const StaState *sta) const; - virtual void setArrival(Arrival arrival, const StaState *sta); - virtual const Required &required(const StaState *sta) const; - virtual void setRequired(const Required &required, - const StaState *sta); - virtual Path *prevPath(const StaState *sta) const; - virtual void prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const; - virtual TimingArc *prevArc(const StaState *sta) const; - PathEnumed *prevPathEnumed() const; - void setPrevPath(PathEnumed *prev); - void setPrevArc(TimingArc *arc); - void setTag(Tag *tag); - - using Path::setRef; - using Path::prevPath; - -protected: - // Pointer to previous path. - // A path is traversed by following prev_path/arcs. - PathEnumed *prev_path_; - TimingArc *prev_arc_; - Arrival arrival_; - VertexId vertex_id_; - TagIndex tag_index_; -}; - -void deletePathEnumed(PathEnumed *path); - -} // namespace diff --git a/search/PathExpanded.cc b/search/PathExpanded.cc index 93c54946..a8b7a498 100644 --- a/search/PathExpanded.cc +++ b/search/PathExpanded.cc @@ -29,7 +29,7 @@ #include "Network.hh" #include "Clock.hh" #include "Search.hh" -#include "PathRef.hh" +#include "Path.hh" #include "Latches.hh" #include "Genclks.hh" @@ -61,35 +61,32 @@ PathExpanded::expand(const Path *path, bool expand_genclks) { const Latches *latches = sta_->latches(); - // Push the paths from the end into an array of PathRefs. - PathRef p(path); - PathRef last_path; + // Push the paths from the end into an array of Paths. + const Path *p = path; + const Path *last_path = nullptr; size_t i = 0; bool found_start = false; - while (!p.isNull()) { - PathRef prev_path; - TimingArc *prev_arc; - p.prevPath(sta_, prev_path, prev_arc); + while (p) { + const Path *prev_path = p->prevPath(); + const TimingArc *prev_arc = p->prevArc(sta_); if (!found_start) { if (prev_arc) { - TimingRole *prev_role = prev_arc->role(); + const TimingRole *prev_role = prev_arc->role(); if (prev_role == TimingRole::regClkToQ() || prev_role == TimingRole::latchEnToQ()) { start_index_ = i; found_start = true; } else if (prev_role == TimingRole::latchDtoQ()) { - Edge *prev_edge = p.prevEdge(prev_arc, sta_); + const Edge *prev_edge = p->prevEdge(sta_); if (prev_edge && latches->isLatchDtoQ(prev_edge)) { start_index_ = i; found_start = true; paths_.push_back(p); - prev_arcs_.push_back(prev_arc); // Push latch D path. paths_.push_back(prev_path); - prev_arcs_.push_back(nullptr); // This breaks latch loop paths. break; } @@ -97,43 +94,37 @@ PathExpanded::expand(const Path *path, } } paths_.push_back(p); - prev_arcs_.push_back(prev_arc); - last_path.init(p); - p.init(prev_path); + last_path = p; + p = prev_path; i++; } if (!found_start) start_index_ = i - 1; if (expand_genclks) - expandGenclk(&last_path); + expandGenclk(last_path); } void -PathExpanded::expandGenclk(PathRef *clk_path) +PathExpanded::expandGenclk(const Path *clk_path) { - if (!clk_path->isNull()) { + if (clk_path) { const Clock *src_clk = clk_path->clock(sta_); if (src_clk && src_clk->isGenerated()) { - PathVertex src_path = sta_->search()->genclks()->srcPath(clk_path); - if (!src_path.isNull()) { + const Path *src_path = sta_->search()->genclks()->srcPath(clk_path); + if (src_path) { // The head of the genclk src path is already in paths_, // so skip past it. - PathRef prev_path; - TimingArc *prev_arc; - src_path.prevPath(sta_, prev_path, prev_arc); - - PathRef p(prev_path); - PathRef last_path; - while (!p.isNull()) { - p.prevPath(sta_, prev_path, prev_arc); - + Path *prev_path = src_path->prevPath(); + Path *p = prev_path; + Path *last_path = nullptr; + while (p) { + prev_path = p->prevPath(); paths_.push_back(p); - prev_arcs_.push_back(prev_arc); - last_path.init(p); - p.init(prev_path); + last_path = p; + p = prev_path; } - expandGenclk(&last_path); + expandGenclk(last_path); } } } @@ -153,91 +144,84 @@ PathExpanded::startIndex() const return pathsIndex(start_index_); } -const PathRef * +const Path * PathExpanded::path(size_t index) const { if (index < paths_.size()) - return &paths_[pathsIndex(index)]; + return paths_[pathsIndex(index)]; else return nullptr; } -TimingArc * -PathExpanded::prevArc(size_t index) const -{ - return prev_arcs_[pathsIndex(index)]; -} - -const PathRef * +const Path * PathExpanded::startPath() const { - return &paths_[start_index_]; + return paths_[start_index_]; } -const PathRef * +const Path * PathExpanded::endPath() const { - return &paths_[0]; + return paths_[0]; } -TimingArc * +const TimingArc * PathExpanded::startPrevArc() const { - return prev_arcs_[start_index_]; + return paths_[start_index_]->prevArc(sta_); } -const PathRef * +const Path * PathExpanded::startPrevPath() const { size_t start1 = start_index_ + 1; if (start1 < paths_.size()) - return &paths_[start1]; + return paths_[start1]; else return nullptr; } -void -PathExpanded::clkPath(PathRef &clk_path) const +const Path * +PathExpanded::clkPath() const { const Latches *latches = sta_->latches(); - const PathRef *start = startPath(); + const Path *start = startPath(); const TimingArc *prev_arc = startPrevArc(); if (start && prev_arc) { TimingRole *role = prev_arc->role(); if (role == TimingRole::latchDtoQ()) { - Edge *prev_edge = start->prevEdge(prev_arc, sta_); + Edge *prev_edge = start->prevEdge(sta_); if (prev_edge && latches->isLatchDtoQ(prev_edge)) { - PathVertex enable_path; - latches->latchEnablePath(start, prev_edge, enable_path); - clk_path.init(enable_path); + return latches->latchEnablePath(start, prev_edge); } } else if (role == TimingRole::regClkToQ() || role == TimingRole::latchEnToQ()) { - const PathRef *start_prev = startPrevPath(); + const Path *start_prev = startPrevPath(); if (start_prev) - clk_path.init(start_prev); + return start_prev; } } else if (start && start->isClock(sta_)) - clk_path.init(start); + return start; + return nullptr; } void PathExpanded::latchPaths(// Return values. - const PathRef *&d_path, - const PathRef *&q_path, + const Path *&d_path, + const Path *&q_path, Edge *&d_q_edge) const { d_path = nullptr; q_path = nullptr; d_q_edge = nullptr; - const PathRef *start = startPath(); + const Path *start = startPath(); const TimingArc *prev_arc = startPrevArc(); if (start && prev_arc && prev_arc->role() == TimingRole::latchDtoQ()) { - Edge *prev_edge = start->prevEdge(prev_arc, sta_); + Edge *prev_edge = start->prevEdge(sta_); // This breaks latch loop paths. if (prev_edge && sta_->latches()->isLatchDtoQ(prev_edge)) { diff --git a/search/PathGroup.cc b/search/PathGroup.cc index 34692a47..05243428 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -46,7 +46,7 @@ namespace sta { -int PathGroup::group_path_count_max = std::numeric_limits::max(); +size_t PathGroup::group_path_count_max = std::numeric_limits::max(); PathGroup * PathGroup::makePathGroupSlack(const char *name, @@ -74,8 +74,8 @@ PathGroup::makePathGroupArrival(const char *name, } PathGroup::PathGroup(const char *name, - int group_path_count, - int endpoint_path_count, + size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, float slack_min, float slack_max, @@ -148,7 +148,7 @@ PathGroup::enumMinSlackUnderMin(PathEnd *path_end) path->transition(sta_), other_ap, sta_); while (other_iter.hasNext()) { - PathVertex *other = other_iter.next(); + Path *other = other_iter.next(); if (tagMatchCrpr(other->tag(sta_), tag)) { PathEnd *end_min = path_end->copy(); end_min->setPath(other); @@ -168,7 +168,7 @@ PathGroup::insert(PathEnd *path_end) LockGuard lock(lock_); path_ends_.push_back(path_end); if (group_path_count_ != group_path_count_max - && static_cast(path_ends_.size()) > group_path_count_ * 2) + && path_ends_.size() > group_path_count_ * 2) prune(); } @@ -177,7 +177,7 @@ PathGroup::prune() { sort(); VertexPathCountMap path_counts; - int end_count = 0; + size_t end_count = 0; for (unsigned i = 0; i < path_ends_.size(); i++) { PathEnd *path_end = path_ends_[i]; Vertex *vertex = path_end->vertex(sta_); @@ -220,7 +220,7 @@ PathGroup::iterator() void PathGroup::ensureSortedMaxPaths() { - if (static_cast(path_ends_.size()) > group_path_count_) + if (path_ends_.size() > group_path_count_) prune(); else sort(); diff --git a/search/PathPrev.cc b/search/PathPrev.cc deleted file mode 100644 index 8de8d78a..00000000 --- a/search/PathPrev.cc +++ /dev/null @@ -1,246 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "PathPrev.hh" - -#include "Graph.hh" -#include "TimingArc.hh" -#include "SearchClass.hh" -#include "Tag.hh" -#include "TagGroup.hh" -#include "Search.hh" -#include "PathAnalysisPt.hh" -#include "PathVertex.hh" - -namespace sta { - -PathPrev::PathPrev() -{ - init(); -} - -void -PathPrev::init() -{ - prev_edge_id_ = edge_id_null; - prev_arc_idx_ = 0; - prev_tag_index_ = tag_index_null; -} - -void -PathPrev::init(const PathPrev *path) -{ - if (path) { - prev_edge_id_ = path->prev_edge_id_; - prev_arc_idx_ = path->prev_arc_idx_; - prev_tag_index_ = path->prev_tag_index_; - } - else - init(); -} - -void -PathPrev::init(const PathPrev &path) -{ - prev_edge_id_ = path.prev_edge_id_; - prev_arc_idx_ = path.prev_arc_idx_; - prev_tag_index_ = path.prev_tag_index_; -} - -void -PathPrev::init(const PathVertex *path, - const Edge *prev_edge, - const TimingArc *prev_arc, - const StaState *sta) -{ - if (path == nullptr || path->isNull()) - init(); - else { - const Graph *graph = sta->graph(); - prev_edge_id_ = graph->id(prev_edge); - prev_arc_idx_ = prev_arc->index(); - prev_tag_index_ = path->tag(sta)->index(); - } -} - -const char * -PathPrev::name(const StaState *sta) const -{ - const Network *network = sta->network(); - const Search *search = sta->search(); - Vertex *vertex = this->vertex(sta); - if (vertex) { - const char *vertex_name = vertex->name(network); - const Tag *tag = this->tag(search); - const RiseFall *rf = tag->transition(); - const char *rf_str = rf->asString(); - const PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta); - int ap_index = path_ap->index(); - const char *min_max = path_ap->pathMinMax()->asString(); - TagIndex tag_index = tag->index(); - return stringPrintTmp("%s %s %s/%d %d", - vertex_name, rf_str, min_max, - ap_index, tag_index); - } - else - return "NULL"; -} - -bool -PathPrev::isNull() const -{ - return prev_edge_id_ == edge_id_null; -} - -VertexId -PathPrev::vertexId(const StaState *sta) const -{ - if (prev_edge_id_ == edge_id_null) - return vertex_id_null; - else { - const Graph *graph = sta->graph(); - const Edge *edge = graph->edge(prev_edge_id_); - return edge->from(); - } -} - -Vertex * -PathPrev::vertex(const StaState *sta) const -{ - if (prev_edge_id_ == edge_id_null) - return nullptr; - else { - const Graph *graph = sta->graph(); - const Edge *edge = graph->edge(prev_edge_id_); - return edge->from(graph); - } -} - -Edge * -PathPrev::prevEdge(const StaState *sta) const -{ - if (prev_edge_id_ == edge_id_null) - return nullptr; - else { - const Graph *graph = sta->graph(); - return graph->edge(prev_edge_id_); - } -} - -TimingArc * -PathPrev::prevArc(const StaState *sta) const -{ - if (prev_edge_id_ == edge_id_null) - return nullptr; - else { - const Graph *graph = sta->graph(); - const Edge *edge = graph->edge(prev_edge_id_); - TimingArcSet *arc_set = edge->timingArcSet(); - return arc_set->findTimingArc(prev_arc_idx_); - } -} - -Tag * -PathPrev::tag(const StaState *sta) const -{ - const Search *search = sta->search(); - return search->tag(prev_tag_index_); -} - -Arrival -PathPrev::arrival(const StaState *sta) const -{ - Graph *graph = sta->graph(); - const Search *search = sta->search(); - Tag *tag = search->tag(prev_tag_index_); - Vertex *vertex = this->vertex(sta); - TagGroup *tag_group = search->tagGroup(vertex); - if (tag_group) { - int arrival_index; - bool arrival_exists; - tag_group->arrivalIndex(tag, arrival_index, arrival_exists); - if (!arrival_exists) - sta->report()->critical(1420, "tag group missing tag"); - Arrival *arrivals = graph->arrivals(vertex); - if (arrivals) - return arrivals[arrival_index]; - else - sta->report()->critical(1421, "missing arrivals"); - } - else - sta->report()->error(1422, "missing arrivals."); - return 0.0; -} - -void -PathPrev::prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const -{ - PathVertex path_vertex(this, sta); - path_vertex.prevPath(sta, prev_path, prev_arc); -} - -//////////////////////////////////////////////////////////////// - -bool -PathPrev::equal(const PathPrev *path1, - const PathPrev *path2) -{ - return path1->prev_edge_id_ == path2->prev_edge_id_ - && path1->prev_tag_index_ == path2->prev_tag_index_; -} - -bool -PathPrev::equal(const PathPrev &path1, - const PathPrev &path2) -{ - return path1.prev_edge_id_ == path2.prev_edge_id_ - && path1.prev_tag_index_ == path2.prev_tag_index_; -} - -int -PathPrev::cmp(const PathPrev &path1, - const PathPrev &path2) -{ - EdgeId edge_id1 = path1.prev_edge_id_; - EdgeId edge_id2 = path2.prev_edge_id_; - if (edge_id1 == edge_id2) { - TagIndex tag_index1 = path1.prev_tag_index_; - TagIndex tag_index2 = path2.prev_tag_index_; - if (tag_index1 == tag_index2) - return 0; - else if (tag_index1 < tag_index2) - return -1; - else - return 1; - } - else if (edge_id1 < edge_id2) - return -1; - else - return 1; -} - -} // namespace diff --git a/search/PathRef.cc b/search/PathRef.cc deleted file mode 100644 index 74bb0aae..00000000 --- a/search/PathRef.cc +++ /dev/null @@ -1,284 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "PathRef.hh" - -#include "Graph.hh" -#include "TagGroup.hh" -#include "PathEnumed.hh" -#include "PathVertex.hh" -#include "Search.hh" - - -namespace sta { - -PathRef::PathRef() : - path_enumed_(nullptr) -{ -} - -PathRef::PathRef(const Path *path) : - path_enumed_(nullptr) -{ - if (path) - path->setRef(this); -} - -PathRef::PathRef(const PathRef &path) : - path_vertex_(path.path_vertex_), - path_enumed_(path.path_enumed_) -{ -} - -PathRef::PathRef(const PathRef *path) : - path_vertex_(path->path_vertex_), - path_enumed_(path->path_enumed_) -{ -} - -PathRef::PathRef(const PathVertex &path) : - path_vertex_(&path), - path_enumed_(nullptr) -{ -} - -void -PathRef::init() -{ - path_vertex_.init(); - path_enumed_ = nullptr; -} - -void -PathRef::init(const PathRef &path) -{ - path_vertex_ = path.path_vertex_; - path_enumed_ = path.path_enumed_; -} - -void -PathRef::init(const PathRef *path) -{ - path_vertex_ = path->path_vertex_; - path_enumed_ = path->path_enumed_; -} - -void -PathRef::init(const PathVertex *path) -{ - path_vertex_ = path; -} - -void -PathRef::init(const PathVertex &path) -{ - path_vertex_ = path; -} - -void -PathRef::init(const PathPrev &path, - const StaState *sta) -{ - int arrival_index = 0; - TagIndex tag_index = path.tagIndex(); - Tag *tag = nullptr; - if (tag_index != tag_index_null) { - const Search *search = sta->search(); - tag = search->tag(tag_index); - Vertex *vertex = path.vertex(sta); - TagGroup *tag_group = search->tagGroup(vertex); - if (tag_group) { - bool arrival_exists; - tag_group->arrivalIndex(tag, arrival_index, arrival_exists); - } - } - path_vertex_.init(path.vertex(sta), tag, arrival_index); -} - -void -PathRef::init(Vertex *vertex, - Tag *tag, - int arrival_index) -{ - path_vertex_.init(vertex, tag, arrival_index); - path_enumed_ = nullptr; -} - -void -PathRef::init(PathEnumed *path) -{ - path_enumed_ = path; -} - -void -PathRef::setRef(PathRef *ref) const -{ - ref->path_vertex_ = path_vertex_; - ref->path_enumed_ = path_enumed_; -} - -void -PathRef::deleteRep() -{ - if (path_enumed_) - deletePathEnumed(path_enumed_); -} - -bool -PathRef::isNull() const -{ - return path_enumed_ == nullptr - && path_vertex_.isNull(); -} - -Vertex * -PathRef::vertex(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->vertex(sta); - else - return path_vertex_.vertex(sta); -} - -VertexId -PathRef::vertexId(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->vertexId(sta); - else - return path_vertex_.vertexId(sta); -} - -Tag * -PathRef::tag(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->tag(sta); - else - return path_vertex_.tag(sta); -} - -TagIndex -PathRef::tagIndex(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->tagIndex(sta); - else - return path_vertex_.tagIndex(sta); -} - -const RiseFall * -PathRef::transition(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->transition(sta); - else - return path_vertex_.transition(sta); -} - -int -PathRef::rfIndex(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->rfIndex(sta); - else - return path_vertex_.rfIndex(sta); -} - -PathAnalysisPt * -PathRef::pathAnalysisPt(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->pathAnalysisPt(sta); - else - return path_vertex_.pathAnalysisPt(sta); -} - -PathAPIndex -PathRef::pathAnalysisPtIndex(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->pathAnalysisPtIndex(sta); - else - return path_vertex_.pathAnalysisPtIndex(sta); -} - -Arrival -PathRef::arrival(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->arrival(sta); - else - return path_vertex_.arrival(sta); -} - -void -PathRef::setArrival(Arrival arrival, - const StaState *sta) -{ - if (path_enumed_) - return path_enumed_->setArrival(arrival, sta); - else - return path_vertex_.setArrival(arrival, sta); -} - -const Required & -PathRef::required(const StaState *sta) const -{ - if (path_enumed_) - return path_enumed_->required(sta); - else - return path_vertex_.required(sta); -} - -void -PathRef::setRequired(const Required &required, - const StaState *sta) -{ - if (path_enumed_) - return path_enumed_->setRequired(required, sta); - else - return path_vertex_.setRequired(required, sta); -} - -void -PathRef::prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const -{ - if (path_enumed_) - path_enumed_->prevPath(sta, prev_path, prev_arc); - else - path_vertex_.prevPath(sta, prev_path, prev_arc); -} - -void -PathRef::arrivalIndex(int &arrival_index, - bool &arrival_exists) const -{ - return path_vertex_.arrivalIndex(arrival_index, arrival_exists); -} - -} // namespace diff --git a/search/PathVertex.cc b/search/PathVertex.cc deleted file mode 100644 index 9efcc03e..00000000 --- a/search/PathVertex.cc +++ /dev/null @@ -1,628 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "PathVertex.hh" - -#include - -#include "Fuzzy.hh" -#include "Graph.hh" -#include "ExceptionPath.hh" -#include "Sdc.hh" -#include "GraphDelayCalc.hh" -#include "Corner.hh" -#include "Tag.hh" -#include "TagGroup.hh" -#include "PathAnalysisPt.hh" -#include "PathRef.hh" -#include "PathPrev.hh" -#include "PathVertexPtr.hh" -#include "Search.hh" - -namespace sta { - -PathVertex::PathVertex() : - vertex_(nullptr), - tag_(nullptr), - arrival_index_(0) -{ -} - -PathVertex::PathVertex(const PathVertex &path) : - vertex_(path.vertex_), - tag_(path.tag_), - arrival_index_(path.arrival_index_) -{ -} - -PathVertex::PathVertex(const PathVertex *path) : - vertex_(nullptr), - tag_(nullptr), - arrival_index_(0) -{ - if (path) { - vertex_ = path->vertex_; - tag_ = path->tag_; - arrival_index_ = path->arrival_index_; - } -} - -PathVertex::PathVertex(Vertex *vertex, - Tag *tag, - const StaState *sta) -{ - init(vertex, tag, sta); -} - -PathVertex::PathVertex(Vertex *vertex, - Tag *tag, - int arrival_index) : - vertex_(vertex), - tag_(tag), - arrival_index_(arrival_index) -{ -} - -PathVertex::PathVertex(const PathPrev *path, - const StaState *sta) -{ - if (path) - init(path->vertex(sta), path->tag(sta), sta); - else - init(); -} - -PathVertex::PathVertex(const PathPrev &path, - const StaState *sta) -{ - if (path.isNull()) - init(); - else - init(path.vertex(sta), path.tag(sta), sta); -} - -PathVertex::PathVertex(const PathVertexPtr &path, - const StaState *sta) -{ - if (path.isNull()) - init(); - else - init(path.vertex(sta), path.tag(sta), sta); -} - -void -PathVertex::init() -{ - vertex_ = nullptr; - tag_ = nullptr; - arrival_index_ = 0; -} - -void -PathVertex::init(Vertex *vertex, - Tag *tag, - const StaState *sta) -{ - vertex_ = nullptr; - tag_ = nullptr; - arrival_index_ = 0; - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex); - if (tag_group) { - bool arrival_exists; - tag_group->arrivalIndex(tag, arrival_index_, arrival_exists); - if (arrival_exists) { - vertex_ = vertex; - tag_ = tag; - } - } -} - -void -PathVertex::init(Vertex *vertex, - Tag *tag, - int arrival_index) -{ - vertex_ = vertex; - tag_ = tag; - arrival_index_ = arrival_index; -} - -void -PathVertex::init(const PathPrev *path, - const StaState *sta) -{ - if (path) - init(path->vertex(sta), path->tag(sta), sta); - else - init(); -} - -void -PathVertex::init(const PathPrev &path, - const StaState *sta) -{ - if (!path.isNull()) - init(path.vertex(sta), path.tag(sta), sta); - else - init(); -} - -void -PathVertex::init(const PathVertexPtr &path, - const StaState *sta) -{ - if (!path.isNull()) - init(path.vertex(sta), path.tag(sta), sta); - else - init(); -} - -void -PathVertex::operator=(const PathVertex &path) -{ - vertex_ = path.vertex_; - tag_ = path.tag_; - arrival_index_ = path.arrival_index_; -} - -bool -PathVertex::isNull() const -{ - return tag_ == nullptr; -} - -void -PathVertex::setRef(PathRef *ref) const -{ - ref->init(vertex_, tag_, arrival_index_); -} - -VertexId -PathVertex::vertexId(const StaState *sta) const -{ - const Graph *graph = sta->graph(); - return graph->id(vertex_); -} - -TagIndex -PathVertex::tagIndex(const StaState *) const -{ - return tag_->index(); -} - -const RiseFall * -PathVertex::transition(const StaState *) const -{ - return tag_->transition(); -} - -int -PathVertex::rfIndex(const StaState *) const -{ - return tag_->rfIndex(); -} - -PathAnalysisPt * -PathVertex::pathAnalysisPt(const StaState *sta) const -{ - return tag_->pathAnalysisPt(sta); -} - -PathAPIndex -PathVertex::pathAnalysisPtIndex(const StaState *) const -{ - return tag_->pathAPIndex(); -} - -void -PathVertex::arrivalIndex(int &arrival_index, - bool &arrival_exists) const -{ - if (tag_) { - arrival_index = arrival_index_; - arrival_exists = true; - } - else - arrival_exists = false; -} - -void -PathVertex::setArrivalIndex(int arrival_index) -{ - arrival_index_ = arrival_index; -} - -Arrival -PathVertex::arrival(const StaState *sta) const -{ - Arrival *arrivals = sta->graph()->arrivals(vertex_); - if (arrivals) - return arrivals[arrival_index_]; - else { - sta->report()->error(1400, "missing arrivals."); - return 0.0; - } -} - -void -PathVertex::setArrival(Arrival arrival, - const StaState *sta) -{ - if (tag_) { - Arrival *arrivals = sta->graph()->arrivals(vertex_); - if (arrivals) - arrivals[arrival_index_] = arrival; - else - sta->report()->error(1401, "missing arrivals."); - } -} - -const Required & -PathVertex::required(const StaState *sta) const -{ - if (tag_) { - Required *requireds = sta->graph()->requireds(vertex_); - if (requireds) - return requireds[arrival_index_]; - } - return delayInitValue(minMax(sta)->opposite()); -} - -void -PathVertex::setRequired(const Required &required, - const StaState *sta) -{ - Graph *graph = sta->graph(); - Required *requireds = graph->requireds(vertex_); - if (requireds == nullptr) { - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex_); - if (tag_group) { - int arrival_count = tag_group->arrivalCount(); - requireds = graph->makeRequireds(vertex_, arrival_count); - } - else - sta->report()->error(1402, "missing requireds."); - } - requireds[arrival_index_] = required; -} - -bool -PathVertex::equal(const PathVertex *path1, - const PathVertex *path2) -{ - return path1->vertex_ == path2->vertex_ - && path1->tag_ == path2->tag_; -} - -//////////////////////////////////////////////////////////////// - -// EvalPred but search to clk source pin. -class PrevPred2 : public SearchPred0 -{ -public: - explicit PrevPred2(const StaState *sta); - virtual bool searchThru(Edge *edge); -}; - -PrevPred2::PrevPred2(const StaState *sta) : - SearchPred0(const_cast(sta)) -{ -} - -bool -PrevPred2::searchThru(Edge *edge) -{ - const Sdc *sdc = sta_->sdc(); - TimingRole *role = edge->role(); - return SearchPred0::searchThru(edge) - && (sdc->dynamicLoopBreaking() - || !edge->isDisabledLoop()) - && !role->isTimingCheck(); -} - -class PrevPathVisitor : public PathVisitor -{ -public: - PrevPathVisitor(const Path *path, - SearchPred *pred, - const StaState *sta); - virtual VertexVisitor *copy() const; - virtual void visit(Vertex *) {} - virtual bool visitFromToPath(const Pin *from_pin, - Vertex *from_vertex, - const RiseFall *from_rf, - Tag *from_tag, - PathVertex *from_path, - const Arrival &from_arrival, - Edge *edge, - TimingArc *arc, - ArcDelay arc_delay, - Vertex *to_vertex, - const RiseFall *to_rf, - Tag *to_tag, - Arrival &to_arrival, - const MinMax *min_max, - const PathAnalysisPt *path_ap); - PathVertex &prevPath() { return prev_path_; } - TimingArc *prevArc() const { return prev_arc_; } - -protected: - Tag *unfilteredTag(const Tag *tag) const; - - const Path *path_; - Arrival path_arrival_; - Tag *path_tag_; - int path_rf_index_; - PathAPIndex path_ap_index_; - PathVertex prev_path_; - TimingArc *prev_arc_; - float dcalc_tol_; -}; - -PrevPathVisitor::PrevPathVisitor(const Path *path, - SearchPred *pred, - const StaState *sta) : - PathVisitor(pred, sta), - path_(path), - path_arrival_(path->arrival(sta)), - path_tag_(path->tag(sta)), - path_rf_index_(path->rfIndex(sta)), - path_ap_index_(path->pathAnalysisPtIndex(sta)), - prev_path_(), - prev_arc_(nullptr), - dcalc_tol_(sta->graphDelayCalc()->incrementalDelayTolerance()) -{ -} - -VertexVisitor * -PrevPathVisitor::copy() const -{ - return new PrevPathVisitor(path_, pred_, this); -} - -bool -PrevPathVisitor::visitFromToPath(const Pin *, - Vertex *, - const RiseFall *, - Tag *from_tag, - PathVertex *from_path, - const Arrival &, - Edge *, - TimingArc *arc, - ArcDelay, - Vertex *, - const RiseFall *to_rf, - Tag *to_tag, - Arrival &to_arrival, - const MinMax *, - const PathAnalysisPt *path_ap) -{ - PathAPIndex path_ap_index = path_ap->index(); - if (to_rf->index() == path_rf_index_ - && path_ap_index == path_ap_index_ - && delayEqual(to_arrival, path_arrival_) - && (tagMatch(to_tag, path_tag_, this) - // If the filter exception became active searching from - // from_path to to_path the tag includes the filter, but - // to_vertex still has paths from previous searches that do - // not have the filter. - || (!from_tag->isFilter() - && to_tag->isFilter() - && tagMatch(unfilteredTag(to_tag), path_tag_, this)))) { - int arrival_index; - bool arrival_exists; - from_path->arrivalIndex(arrival_index, arrival_exists); - if (arrival_exists) { - prev_path_ = from_path; - prev_arc_ = arc; - // Stop looking for the previous path/arc. - return false; - } - } - return true; -} - -Tag * -PrevPathVisitor::unfilteredTag(const Tag *tag) const -{ - ExceptionStateSet *unfiltered_states = nullptr; - const ExceptionStateSet *states = tag->states(); - ExceptionStateSet::ConstIterator state_iter(states); - while (state_iter.hasNext()) { - ExceptionState *state = state_iter.next(); - ExceptionPath *except = state->exception(); - if (!except->isFilter()) { - if (unfiltered_states == nullptr) - unfiltered_states = new ExceptionStateSet(); - unfiltered_states->insert(state); - } - } - return search_->findTag(tag->transition(), - corners_->findPathAnalysisPt(tag->pathAPIndex()), - tag->clkInfo(), - tag->isClock(), - tag->inputDelay(), - tag->isSegmentStart(), - unfiltered_states, true); -} - -//////////////////////////////////////////////////////////////// - -void -PathVertex::prevPath(const StaState *sta, - // Return values. - PathVertex &prev_path, - TimingArc *&prev_arc) const -{ - PrevPred2 pred(sta); - PrevPathVisitor visitor(this, &pred, sta); - visitor.visitFaninPaths(vertex(sta)); - prev_path = visitor.prevPath(); - prev_arc = visitor.prevArc(); -} - -void -PathVertex::prevPath(const StaState *sta, - // Return values. - PathVertex &prev_path) const -{ - PrevPred2 pred(sta); - PrevPathVisitor visitor(this, &pred, sta); - visitor.visitFaninPaths(vertex(sta)); - prev_path = visitor.prevPath(); -} - -void -PathVertex::prevPath(const StaState *sta, - // Return values. - PathRef &prev_path, - TimingArc *&prev_arc) const -{ - const Graph *graph = sta->graph(); - Vertex *vertex = this->vertex(graph); - PathPrev *prev_paths = vertex->prevPaths(); - if (prev_paths) { - PathPrev &prev = prev_paths[arrival_index_]; - prev_path.init(prev, sta); - prev_arc = prev.isNull() ? nullptr : prev.prevArc(sta); - } - else { - PathVertex prev; - prevPath(sta, prev, prev_arc); - prev.setRef(prev_path); - } -} - -//////////////////////////////////////////////////////////////// - -VertexPathIterator::VertexPathIterator(Vertex *vertex, - const StaState *sta) : - search_(sta->search()), - vertex_(vertex), - rf_(nullptr), - path_ap_(nullptr), - min_max_(nullptr) -{ - TagGroup *tag_group = search_->tagGroup(vertex); - if (tag_group) { - arrival_iter_.init(tag_group->arrivalMap()); - findNext(); - } -} - -// Iterate over vertex paths with the same transition and -// analysis pt but different but different tags. -VertexPathIterator::VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const PathAnalysisPt *path_ap, - const StaState *sta) : - search_(sta->search()), - vertex_(vertex), - rf_(rf), - path_ap_(path_ap), - min_max_(nullptr) -{ - TagGroup *tag_group = search_->tagGroup(vertex); - if (tag_group) { - arrival_iter_.init(tag_group->arrivalMap()); - findNext(); - } -} - -VertexPathIterator::VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const MinMax *min_max, - const StaState *sta) : - search_(sta->search()), - vertex_(vertex), - rf_(rf), - path_ap_(nullptr), - min_max_(min_max) -{ - TagGroup *tag_group = search_->tagGroup(vertex); - if (tag_group) { - arrival_iter_.init(tag_group->arrivalMap()); - findNext(); - } -} - -VertexPathIterator::VertexPathIterator(Vertex *vertex, - const RiseFall *rf, - const PathAnalysisPt *path_ap, - const MinMax *min_max, - const StaState *sta) : - search_(sta->search()), - vertex_(vertex), - rf_(rf), - path_ap_(path_ap), - min_max_(min_max) -{ - TagGroup *tag_group = search_->tagGroup(vertex); - if (tag_group) { - arrival_iter_.init(tag_group->arrivalMap()); - findNext(); - } -} - -VertexPathIterator::~VertexPathIterator() -{ -} - -bool -VertexPathIterator::hasNext() -{ - return !next_.isNull(); -} - -void -VertexPathIterator::findNext() -{ - while (arrival_iter_.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter_.next(tag, arrival_index); - if ((rf_ == nullptr - || tag->rfIndex() == rf_->index()) - && (path_ap_ == nullptr - || tag->pathAPIndex() == path_ap_->index()) - && (min_max_ == nullptr - || tag->pathAnalysisPt(search_)->pathMinMax() == min_max_)) { - next_.init(vertex_, tag, arrival_index); - return; - } - } - next_.init(); -} - -PathVertex * -VertexPathIterator::next() -{ - path_ = next_; - findNext(); - return &path_; -} - -} // namespace diff --git a/search/PathVertexPtr.cc b/search/PathVertexPtr.cc deleted file mode 100644 index 16fc7d9d..00000000 --- a/search/PathVertexPtr.cc +++ /dev/null @@ -1,201 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "PathVertexPtr.hh" - -#include "Graph.hh" -#include "TimingArc.hh" -#include "SearchClass.hh" -#include "Tag.hh" -#include "TagGroup.hh" -#include "Search.hh" -#include "PathAnalysisPt.hh" -#include "PathVertex.hh" - -namespace sta { - -PathVertexPtr::PathVertexPtr() : - vertex_id_(vertex_id_null), - tag_index_(tag_index_null) -{ -} - -PathVertexPtr::PathVertexPtr(const PathVertex *path, - const StaState *sta) -{ - init(path, sta); -} - -void -PathVertexPtr::init() -{ - vertex_id_ = vertex_id_null; - tag_index_ = tag_index_null; -} - -void -PathVertexPtr::init(const PathVertexPtr *path) -{ - if (path) { - vertex_id_ = path->vertex_id_; - tag_index_ = path->tag_index_; - } - else { - vertex_id_ = vertex_id_null; - tag_index_ = tag_index_null; - } -} - -void -PathVertexPtr::init(const PathVertexPtr &path) -{ - vertex_id_ = path.vertex_id_; - tag_index_ = path.tag_index_; -} - -void -PathVertexPtr::init(const PathVertex *path, - const StaState *sta) -{ - if (path == nullptr || path->isNull()) - init(); - else { - vertex_id_ = path->vertexId(sta); - tag_index_ = path->tagIndex(sta); - } -} - -const char * -PathVertexPtr::name(const StaState *sta) const -{ - const Network *network = sta->network(); - const Search *search = sta->search(); - Vertex *vertex = this->vertex(sta); - if (vertex) { - const char *vertex_name = vertex->name(network); - const Tag *tag = this->tag(search); - const RiseFall *rf = tag->transition(); - const char *rf_str = rf->asString(); - const PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta); - int ap_index = path_ap->index(); - const char *min_max = path_ap->pathMinMax()->asString(); - TagIndex tag_index = tag->index(); - return stringPrintTmp("%s %s %s/%d %d", - vertex_name, rf_str, min_max, - ap_index, tag_index); - } - else - return "NULL"; -} - -bool -PathVertexPtr::isNull() const -{ - return vertex_id_ == vertex_id_null; -} - -Vertex * -PathVertexPtr::vertex(const StaState *sta) const -{ - if (vertex_id_ == vertex_id_null) - return nullptr; - else { - const Graph *graph = sta->graph(); - return graph->vertex(vertex_id_); - } -} - -Tag * -PathVertexPtr::tag(const StaState *sta) const -{ - const Search *search = sta->search(); - return search->tag(tag_index_); -} - -Arrival -PathVertexPtr::arrival(const StaState *sta) const -{ - const Vertex *vertex = this->vertex(sta); - Arrival *arrivals = sta->graph()->arrivals(vertex); - if (arrivals) { - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex); - Tag *tag = this->tag(sta); - int arrival_index; - bool arrival_exists; - tag_group->arrivalIndex(tag, arrival_index, arrival_exists); - if (arrival_exists) - return arrivals[arrival_index]; - else { - sta->report()->error(1403, "missing arrival."); - return 0.0; - } - } - else { - sta->report()->error(1404, "missing arrivals."); - return 0.0; - } -} - -//////////////////////////////////////////////////////////////// - -bool -PathVertexPtr::equal(const PathVertexPtr *path1, - const PathVertexPtr *path2) -{ - return path1->vertex_id_ == path2->vertex_id_ - && path1->tag_index_ == path2->tag_index_; -} - -bool -PathVertexPtr::equal(const PathVertexPtr &path1, - const PathVertexPtr &path2) -{ - return path1.vertex_id_ == path2.vertex_id_ - && path1.tag_index_ == path2.tag_index_; -} - -int -PathVertexPtr::cmp(const PathVertexPtr &path1, - const PathVertexPtr &path2) -{ - VertexId vertex_id1 = path1.vertex_id_; - VertexId vertex_id2 = path2.vertex_id_; - if (vertex_id1 == vertex_id2) { - TagIndex tag_index1 = path1.tagIndex(); - TagIndex tag_index2 = path2.tagIndex(); - if (tag_index1 == tag_index2) - return 0; - else if (tag_index1 < tag_index2) - return -1; - else - return 1; - } - else if (vertex_id1 < vertex_id2) - return -1; - else - return 1; -} - -} // namespace diff --git a/search/Property.cc b/search/Property.cc index de8b2b80..4e312293 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -37,7 +37,7 @@ #include "Corner.hh" #include "PathEnd.hh" #include "PathExpanded.hh" -#include "PathRef.hh" +#include "Path.hh" #include "power/Power.hh" #include "Sta.hh" @@ -318,9 +318,9 @@ PropertyValue::PropertyValue(ClockSet *value) : } } -PropertyValue::PropertyValue(PathRefSeq *value) : - type_(type_path_refs), - path_refs_(new PathRefSeq(*value)), +PropertyValue::PropertyValue(ConstPathSeq *value) : + type_(type_paths), + paths_(new ConstPathSeq(*value)), unit_(nullptr) { } @@ -384,8 +384,8 @@ PropertyValue::PropertyValue(const PropertyValue &value) : case Type::type_clks: clks_ = value.clks_ ? new ClockSeq(*value.clks_) : nullptr; break; - case Type::type_path_refs: - path_refs_ = value.path_refs_ ? new PathRefSeq(*value.path_refs_) : nullptr; + case Type::type_paths: + paths_ = value.paths_ ? new ConstPathSeq(*value.paths_) : nullptr; break; case Type::type_pwr_activity: pwr_activity_ = value.pwr_activity_; @@ -450,8 +450,8 @@ PropertyValue::PropertyValue(PropertyValue &&value) : // Steal the value. value.clks_ = nullptr; break; - case Type::type_path_refs: - path_refs_ = value.path_refs_; + case Type::type_paths: + paths_ = value.paths_; // Steal the value. value.clks_ = nullptr; break; @@ -473,8 +473,8 @@ PropertyValue::~PropertyValue() case Type::type_pins: delete pins_; break; - case Type::type_path_refs: - delete path_refs_; + case Type::type_paths: + delete paths_; break; default: break; @@ -535,8 +535,8 @@ PropertyValue::operator=(const PropertyValue &value) case Type::type_clks: clks_ = value.clks_ ? new ClockSeq(*value.clks_) : nullptr; break; - case Type::type_path_refs: - path_refs_ = value.path_refs_ ? new PathRefSeq(*value.path_refs_) : nullptr; + case Type::type_paths: + paths_ = value.paths_ ? new ConstPathSeq(*value.paths_) : nullptr; break; case Type::type_pwr_activity: pwr_activity_ = value.pwr_activity_; @@ -602,8 +602,8 @@ PropertyValue::operator=(PropertyValue &&value) clks_ = value.clks_; value.clks_ = nullptr; break; - case Type::type_path_refs: - path_refs_ = value.path_refs_; + case Type::type_paths: + paths_ = value.paths_; value.clks_ = nullptr; break; case Type::type_pwr_activity: @@ -650,7 +650,7 @@ PropertyValue::asString(const Network *network) const case Type::type_none: case Type::type_pins: case Type::type_clks: - case Type::type_path_refs: + case Type::type_paths: case Type::type_pwr_activity: return nullptr; } @@ -1271,10 +1271,10 @@ getProperty(PathEnd *end, return PropertyValue(delayPropertyValue(end->slack(sta), sta)); else if (stringEqual(property, "points")) { PathExpanded expanded(end->path(), sta); - PathRefSeq paths; + ConstPathSeq paths; for (size_t i = expanded.startIndex(); i < expanded.size(); i++) { - const PathRef *path = expanded.path(i); - paths.push_back(*path); + const Path *path = expanded.path(i); + paths.push_back(path); } return PropertyValue(&paths); } @@ -1283,16 +1283,16 @@ getProperty(PathEnd *end, } PropertyValue -getProperty(PathRef *path, +getProperty(Path *path, const char *property, Sta *sta) { if (stringEqual(property, "pin")) return PropertyValue(path->pin(sta)); else if (stringEqual(property, "arrival")) - return PropertyValue(delayPropertyValue(path->arrival(sta), sta)); + return PropertyValue(delayPropertyValue(path->arrival(), sta)); else if (stringEqual(property, "required")) - return PropertyValue(delayPropertyValue(path->required(sta), sta)); + return PropertyValue(delayPropertyValue(path->required(), sta)); else if (stringEqual(property, "slack")) return PropertyValue(delayPropertyValue(path->slack(sta), sta)); else diff --git a/search/ReportPath.cc b/search/ReportPath.cc index bd23c47d..6efeeef8 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -48,13 +48,12 @@ #include "GraphDelayCalc.hh" #include "ClkInfo.hh" #include "Tag.hh" -#include "PathVertex.hh" #include "PathAnalysisPt.hh" #include "PathGroup.hh" #include "CheckMinPulseWidths.hh" #include "CheckMinPeriods.hh" #include "CheckMaxSkews.hh" -#include "PathRef.hh" +#include "Path.hh" #include "Search.hh" #include "PathExpanded.hh" #include "Latches.hh" @@ -925,7 +924,7 @@ ReportPath::reportFull(const PathEndDataCheck *end) const // It is like a target because crpr and uncertainty are reported. // It is always propagated, even if the clock is ideal. reportTgtClk(end, 0.0, true); - const PathVertex *data_clk_path = end->dataClkPath(); + const Path *data_clk_path = end->dataClkPath(); if (!data_clk_path->isClock(this)) { // Report the path from the clk network to the data check. PathExpanded clk_expanded(data_clk_path, this); @@ -1037,7 +1036,7 @@ string ReportPath::pathStartpoint(const PathEnd *end, const PathExpanded &expanded) const { - const PathRef *start = expanded.startPath(); + const Path *start = expanded.startPath(); Pin *pin = start->pin(graph_); const char *pin_name = cmd_network_->pathName(pin); if (network_->isTopLevelPort(pin)) { @@ -1103,7 +1102,7 @@ ReportPath::reportJson(const PathEnd *end, sdc_network_->pathName(endpoint)); const ClockEdge *src_clk_edge = end->sourceClkEdge(this); - const PathVertex *tgt_clk_path = end->targetClkPath(); + const Path *tgt_clk_path = end->targetClkPath(); if (src_clk_edge) { stringAppend(result, " \"source_clock\": \"%s\",\n", src_clk_edge->clock()->name()); @@ -1181,7 +1180,7 @@ ReportPath::reportJson(const PathExpanded &expanded, { stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name); for (size_t i = 0; i < expanded.size(); i++) { - const PathRef *path = expanded.path(i); + const Path *path = expanded.path(i); const Pin *pin = path->vertex(this)->pin(); const Net *net = network_->net(pin); const Instance *inst = network_->instance(pin); @@ -1238,7 +1237,7 @@ ReportPath::reportJson(const PathExpanded &expanded, stringAppend(result, "%*s \"arrival\": %.3e,\n", indent, "", - delayAsFloat(path->arrival(this))); + delayAsFloat(path->arrival())); if (is_driver) stringAppend(result, "%*s \"capacitance\": %.3e,\n", indent, "", @@ -1592,7 +1591,7 @@ ReportPath::reportShort(const MaxSkewCheck *check) const reportDescription(what.c_str(), line); const EarlyLate *early_late = EarlyLate::early(); reportSpaceFieldDelay(check->maxSkew(this), early_late, line); - reportSpaceFieldDelay(check->skew(this), early_late, line); + reportSpaceFieldDelay(check->skew(), early_late, line); reportSpaceSlack(check->slack(this), line); report_->reportLineString(line); } @@ -1621,7 +1620,7 @@ ReportPath::reportVerbose(const MaxSkewCheck *check) const reportDashLine(); reportLine("allowable skew", check->maxSkew(this), EarlyLate::early()); - reportLine("actual skew", check->skew(this), EarlyLate::late()); + reportLine("actual skew", check->skew(), EarlyLate::late()); reportDashLine(); reportSlack(check->slack(this)); } @@ -1629,7 +1628,7 @@ ReportPath::reportVerbose(const MaxSkewCheck *check) const // Based on reportTgtClk. void ReportPath::reportSkewClkPath(const char *arrival_msg, - const PathVertex *clk_path) const + const Path *clk_path) const { const ClockEdge *clk_edge = clk_path->clkEdge(this); const Clock *clk = clk_edge->clock(); @@ -1767,9 +1766,9 @@ ReportPath::reportStartpoint(const PathEnd *end, const PathExpanded &expanded) const { const Path *path = end->path(); - const PathRef *start = expanded.startPath(); + const Path *start = expanded.startPath(); const TimingArc *prev_arc = expanded.startPrevArc(); - const Edge *prev_edge = start->prevEdge(prev_arc, this); + const Edge *prev_edge = start->prevEdge(this); const Pin *pin = start->pin(graph_); const ClockEdge *clk_edge = path->clkEdge(this); const Clock *clk = path->clock(search_); @@ -1795,10 +1794,9 @@ ReportPath::reportStartpoint(const PathEnd *end, const char *inst_name = cmd_network_->pathName(inst); if (clk_edge) { const RiseFall *clk_rf = clk_edge->transition(); - PathRef clk_path; - expanded.clkPath(clk_path); - bool clk_inverted = !clk_path.isNull() - && clk_rf != clk_path.transition(this); + const Path *clk_path = expanded.clkPath(); + bool clk_inverted = clk_path + && clk_rf != clk_path->transition(this); string clk_name = clkName(clk, clk_inverted); const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); @@ -1830,8 +1828,8 @@ ReportPath::reportStartpoint(const PathEnd *end, bool ReportPath::pathFromClkPin(const PathExpanded &expanded) const { - const PathRef *start = expanded.startPath(); - const PathRef *end = expanded.endPath(); + const Path *start = expanded.startPath(); + const Path *end = expanded.endPath(); const Pin *start_pin = start->pin(graph_); return pathFromClkPin(end, start_pin); } @@ -2069,13 +2067,12 @@ ReportPath::reportSrcClkAndPath(const Path *path, bool path_from_input = false; bool input_has_ref_path = false; Arrival clk_delay, clk_end_time; - PathRef clk_path; - expanded.clkPath(clk_path); + const Path *clk_path = expanded.clkPath(); const RiseFall *clk_end_rf; - if (!clk_path.isNull()) { - clk_end_time = search_->clkPathArrival(&clk_path) + time_offset; + if (clk_path) { + clk_end_time = search_->clkPathArrival(clk_path) + time_offset; clk_delay = clk_end_time - clk_time; - clk_end_rf = clk_path.transition(this); + clk_end_rf = clk_path->transition(this); } else { // Path from input port or clk used as data. @@ -2083,16 +2080,16 @@ ReportPath::reportSrcClkAndPath(const Path *path, clk_delay = clk_insertion + clk_latency; clk_end_time = clk_time + clk_delay; - const PathRef *first_path = expanded.startPath(); + const Path *first_path = expanded.startPath(); const InputDelay *input_delay = pathInputDelay(first_path); if (input_delay) { path_from_input = true; const Pin *ref_pin = input_delay->refPin(); if (ref_pin && clk->isPropagated()) { - PathRef ref_path; + Path ref_path; pathInputDelayRefPath(first_path, input_delay, ref_path); if (!ref_path.isNull()) { - const Arrival &ref_end_time = ref_path.arrival(this); + const Arrival &ref_end_time = ref_path.arrival(); clk_delay = ref_end_time - clk_time; clk_end_time = ref_end_time + time_offset; input_has_ref_path = true; @@ -2105,8 +2102,7 @@ ReportPath::reportSrcClkAndPath(const Path *path, bool clk_used_as_data = pathFromClkPin(expanded); bool is_prop = isPropagated(path); const EarlyLate *early_late = min_max; - if (reportGenClkSrcPath(clk_path.isNull() ? nullptr : &clk_path, - clk, clk_rf, min_max, early_late) + if (reportGenClkSrcPath(clk_path, clk, clk_rf, min_max, early_late) && !(path_from_input && !input_has_ref_path)) { reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max); @@ -2137,7 +2133,7 @@ ReportPath::reportSrcClkAndPath(const Path *path, reportPath1(path, expanded, true, time_offset); else { Arrival clk_arrival = clk_end_time; - Arrival end_arrival = path->arrival(this) + time_offset; + Arrival end_arrival = path->arrival() + time_offset; Delay clk_delay = end_arrival - clk_arrival; reportLine("clock network delay", clk_delay, end_arrival, early_late); @@ -2395,10 +2391,10 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk, { PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late); const MinMax *min_max = path_ap->pathMinMax(); - PathVertex src_path = - search_->genclks()->srcPath(clk, clk_pin, clk_rf, insert_ap); - if (!src_path.isNull()) { - ClkInfo *src_clk_info = src_path.clkInfo(search_); + 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(); const Clock *src_clk = src_clk_info->clock(); if (src_clk) { @@ -2419,12 +2415,12 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk, early_late, path_ap); reportClkSrcLatency(insertion, gclk_time, early_late); } - PathExpanded src_expanded(&src_path, this); - reportPath4(&src_path, src_expanded, skip_first_path, false, + PathExpanded src_expanded(src_path, this); + reportPath4(src_path, src_expanded, skip_first_path, false, clk_used_as_data, gclk_time); if (!clk->isPropagated()) reportLine("clock network delay (ideal)", 0.0, - src_path.arrival(this), min_max); + src_path->arrival(), min_max); } } else { @@ -2433,7 +2429,7 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk, else if (!clk_used_as_data) reportLine("clock network delay (ideal)", 0.0, gclk_time, min_max); } - return !src_path.isNull(); + return src_path != nullptr; } void @@ -2610,22 +2606,21 @@ ReportPath::reportPath1(const Path *path, bool clk_used_as_data, float time_offset) const { - const PathRef *d_path, *q_path; + const Path *d_path, *q_path; Edge *d_q_edge; expanded.latchPaths(d_path, q_path, d_q_edge); if (d_path) { Arrival latch_time_given, latch_enable_time; - PathVertex latch_enable_path; + Path *latch_enable_path; latches_->latchTimeGivenToStartpoint(d_path, q_path, d_q_edge, - latch_time_given, - latch_enable_path); - if (!latch_enable_path.isNull()) { - const EarlyLate *early_late = latch_enable_path.minMax(this); - latch_enable_time = search_->clkPathArrival(&latch_enable_path); + latch_time_given, latch_enable_path); + if (latch_enable_path) { + const EarlyLate *early_late = latch_enable_path->minMax(this); + latch_enable_time = search_->clkPathArrival(latch_enable_path); if (reportClkPath()) { - PathExpanded enable_expanded(&latch_enable_path, this); + PathExpanded enable_expanded(latch_enable_path, this); // Report the path to the latch enable. - reportPath2(&latch_enable_path, enable_expanded, false, + reportPath2(latch_enable_path, enable_expanded, false, time_offset); } Arrival time = latch_enable_time + latch_time_given; @@ -2689,8 +2684,8 @@ ReportPath::reportPath4(const Path *path, Arrival prev_time(0.0); if (skip_first_path) { path_first_index = 1; - const PathRef *start = expanded.path(0); - prev_time = start->arrival(this) + time_offset; + const Path *start = expanded.path(0); + prev_time = start->arrival() + time_offset; } size_t path_last_index = expanded.size() - 1; if (skip_last_path @@ -2719,15 +2714,14 @@ ReportPath::reportPath5(const Path *path, const MinMax *min_max = path->minMax(this); DcalcAnalysisPt *dcalc_ap = path->pathAnalysisPt(this)->dcalcAnalysisPt(); DcalcAPIndex ap_index = dcalc_ap->index(); - PathRef clk_path; - expanded.clkPath(clk_path); - Vertex *clk_start = clk_path.vertex(this); + const Path *clk_path = expanded.clkPath(); + Vertex *clk_start = clk_path ? clk_path->vertex(this) : nullptr; for (size_t i = path_first_index; i <= path_last_index; i++) { - const PathRef *path1 = expanded.path(i); - TimingArc *prev_arc = expanded.prevArc(i); + const Path *path1 = expanded.path(i); + const TimingArc *prev_arc = path1->prevArc(this); Vertex *vertex = path1->vertex(this); Pin *pin = vertex->pin(); - Arrival time = path1->arrival(this) + time_offset; + Arrival time = path1->arrival() + time_offset; Delay incr = 0.0; const char *line_case = nullptr; bool is_clk_start = path1->vertex(this) == clk_start; @@ -2747,7 +2741,7 @@ ReportPath::reportPath5(const Path *path, // First path. reportInputExternalDelay(path1, time_offset); size_t next_index = i + 1; - const PathRef *next_path = expanded.path(next_index); + const Path *next_path = expanded.path(next_index); if (network_->isTopLevelPort(pin) && next_path && !nextArcAnnotated(next_path, next_index, expanded, ap_index) @@ -2756,7 +2750,7 @@ ReportPath::reportPath5(const Path *path, // The delay calculator annotates wire delays on the edges // from the input to the loads. Report the wire delay on the // input pin instead. - Arrival next_time = next_path->arrival(this) + time_offset; + Arrival next_time = next_path->arrival() + time_offset; incr = delayIncr(next_time, time, min_max); time = next_time; line_case = "input_drive"; @@ -2833,7 +2827,7 @@ ReportPath::reportPath5(const Path *path, prev_time = time; } else { - reportHierPinsThru(path1, prev_arc); + reportHierPinsThru(path1); if (report_input_pin_ || (i == 0) || (i == path_last_index) @@ -2852,11 +2846,10 @@ ReportPath::reportPath5(const Path *path, } void -ReportPath::reportHierPinsThru(const Path *path, - const TimingArc *prev_arc) const +ReportPath::reportHierPinsThru(const Path *path) const { if (report_hier_pins_) { - const Edge *prev_edge = path->prevEdge(prev_arc, this); + const Edge *prev_edge = path->prevEdge(this); if (prev_edge && prev_edge->isWire()) { for (const Pin *hpin : hierPinsThruEdge(prev_edge, network_, graph_)) { const string what = descriptionField(hpin); @@ -2880,13 +2873,13 @@ ReportPath::delayIncr(Delay time, } bool -ReportPath::nextArcAnnotated(const PathRef *next_path, +ReportPath::nextArcAnnotated(const Path *next_path, size_t next_index, const PathExpanded &expanded, DcalcAPIndex ap_index) const { - TimingArc *arc = expanded.prevArc(next_index); - Edge *edge = next_path->prevEdge(arc, this); + const TimingArc *arc = expanded.path(next_index)->prevArc(this); + Edge *edge = next_path->prevEdge(this); return graph_->arcDelayAnnotated(edge, arc, ap_index); } @@ -2983,13 +2976,13 @@ ReportPath::reportInputExternalDelay(const Path *first_path, const Pin *first_pin = first_path->pin(graph_); if (!pathFromClkPin(first_path, first_pin)) { const RiseFall *rf = first_path->transition(this); - Arrival time = first_path->arrival(this) + time_offset; + Arrival time = first_path->arrival() + time_offset; const EarlyLate *early_late = first_path->minMax(this); InputDelay *input_delay = pathInputDelay(first_path); if (input_delay) { const Pin *ref_pin = input_delay->refPin(); if (ref_pin) { - PathRef ref_path; + Path ref_path; pathInputDelayRefPath(first_path, input_delay, ref_path); if (!ref_path.isNull() && reportClkPath()) { PathExpanded ref_expanded(&ref_path, this); @@ -3018,7 +3011,7 @@ void ReportPath::pathInputDelayRefPath(const Path *path, const InputDelay *input_delay, // Return value. - PathRef &ref_path) const + Path &ref_path) const { const Pin *ref_pin = input_delay->refPin(); const RiseFall *ref_rf = input_delay->refTransition(); @@ -3028,10 +3021,10 @@ ReportPath::pathInputDelayRefPath(const Path *path, const ClockEdge *clk_edge = path->clkEdge(this); VertexPathIterator path_iter(ref_vertex, ref_rf, path_ap, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); if (path->isClock(this) && path->clkEdge(this) == clk_edge) { - ref_path.init(path); + ref_path = path; break; } } diff --git a/search/ReportPath.hh b/search/ReportPath.hh index 10ef2d0e..4f3a6812 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -326,8 +326,7 @@ protected: bool report_clk_path, Arrival prev_time, float time_offset) const; - void reportHierPinsThru(const Path *path, - const TimingArc *prev_arc) const; + void reportHierPinsThru(const Path *path) const; void reportInputExternalDelay(const Path *path, float time_offset) const; void reportLine(const char *what, @@ -426,7 +425,7 @@ protected: const MinMax *min_max) const; const char *mpwCheckHiLow(const MinPulseWidthCheck *check) const; void reportSkewClkPath(const char *arrival_msg, - const PathVertex *clk_path) const; + const Path *clk_path) const; const char *edgeRegLatchDesc(const Edge *edge, const TimingArc *arc) const; const char *checkRegLatchDesc(const TimingRole *role, @@ -434,7 +433,7 @@ protected: const char *regDesc(const RiseFall *clk_rf) const; const char *latchDesc(const RiseFall *clk_rf) const; void pathClkPath(const Path *path, - const PathRef &clk_path) const; + const Path &clk_path) const; bool isPropagated(const Path *clk_path) const; bool isPropagated(const Path *clk_path, const Clock *clk) const; @@ -443,10 +442,10 @@ protected: const Pin *start_pin) const; void latchPaths(const Path *path, // Return values. - PathRef &d_path, - PathRef &q_path, + Path &d_path, + Path &q_path, Edge *&d_q_edge) const; - bool nextArcAnnotated(const PathRef *next_path, + bool nextArcAnnotated(const Path *next_path, size_t next_index, const PathExpanded &expanded, DcalcAPIndex ap_index) const; @@ -458,7 +457,7 @@ protected: void pathInputDelayRefPath(const Path *path, const InputDelay *input_delay, // Return value. - PathRef &ref_path) const; + Path &ref_path) const; const char *asRisingFalling(const RiseFall *rf) const; const char *asRiseFall(const RiseFall *rf) const; Delay delayIncr(Delay time, diff --git a/search/Search.cc b/search/Search.cc index 3108f6ae..7af4326b 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -54,9 +54,7 @@ #include "Bfs.hh" #include "Corner.hh" #include "Sim.hh" -#include "PathVertex.hh" -#include "PathPrev.hh" -#include "PathRef.hh" +#include "Path.hh" #include "ClkInfo.hh" #include "Tag.hh" #include "TagGroup.hh" @@ -142,11 +140,7 @@ DynLoopSrchPred::hasPendingLoopPaths(Edge *edge, Corners *corners = search->corners(); Vertex *from_vertex = edge->from(graph); TagGroup *prev_tag_group = search->tagGroup(from_vertex); - ArrivalMap::Iterator arrival_iter(tag_bldr_->arrivalMap()); - while (arrival_iter.hasNext()) { - Tag *from_tag; - int arrival_index; - arrival_iter.next(from_tag, arrival_index); + for (auto const [from_tag, path_index] : tag_bldr_->pathIndexMap()) { if (from_tag->isLoop()) { // Loop false path exceptions apply to rise/fall edges so to_rf // does not matter. @@ -255,7 +249,6 @@ Search::init(StaState *sta) path_groups_ = nullptr; endpoints_ = nullptr; invalid_endpoints_ = nullptr; - always_save_prev_paths_ = true; filter_ = nullptr; filter_from_ = nullptr; filter_to_ = nullptr; @@ -274,6 +267,7 @@ Search::initVars() Search::~Search() { + deletePathGroups(); deletePaths(); deleteTags(); delete tag_set_; @@ -299,7 +293,6 @@ Search::~Search() delete genclks_; delete filtered_arrivals_; deleteFilter(); - deletePathGroups(); } void @@ -433,6 +426,8 @@ Search::deletePathsIncr(Vertex *vertex) void Search::deletePaths(Vertex *vertex) { + debugPrint(debug_, "search", 4, "delete paths %s", + vertex->name(network_)); TagGroup *tag_group = tagGroup(vertex); if (tag_group) graph_->deletePaths(vertex); @@ -450,8 +445,8 @@ Search::findPathEnds(ExceptionFrom *from, bool unconstrained, const Corner *corner, const MinMaxAll *min_max, - int group_path_count, - int endpoint_path_count, + size_t group_path_count, + size_t endpoint_path_count, bool unique_pins, float slack_min, float slack_max, @@ -490,9 +485,6 @@ Search::findFilteredArrivals(ExceptionFrom *from, bool thru_latches) { unconstrained_paths_ = unconstrained; - // Delete results from last findPathEnds. - // Filtered arrivals are deleted by Sta::searchPreamble. - deletePathGroups(); checkFromThrusTo(from, thrus, to); filter_from_ = from; filter_to_ = to; @@ -618,6 +610,7 @@ Search::findFilteredArrivals(bool thru_latches) int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_); deleteTagsPrev(); + genclks_->updateSrcPathPrevs(); debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count); } arrivals_exist_ = true; @@ -725,6 +718,20 @@ Search::deleteVertexBefore(Vertex *vertex) invalid_endpoints_->erase(vertex); } +void +Search::deleteEdgeBefore(Edge *edge) +{ + Vertex *from = edge->from(graph_); + Vertex *to = edge->to(graph_); + arrivalInvalid(to); + requiredInvalid(from); + VertexPathIterator path_iter(to, graph_); + while (path_iter.hasNext()) { + Path *path = path_iter.next(); + path->clearPrevPath(this); + } +} + bool Search::arrivalsValid() { @@ -740,6 +747,7 @@ Search::arrivalsInvalid() // Delete paths to make sure no state is left over. // For example, set_disable_timing strands a vertex, which means // the search won't revisit it to clear the previous arrival. + deletePathGroups(); deletePaths(); deleteTags(); genclks_->clear(); @@ -865,6 +873,7 @@ Search::findClkArrivals() arrival_visitor_->init(false, &search_clk); arrival_iter_->visitParallel(levelize_->maxLevel(), arrival_visitor_); deleteTagsPrev(); + genclks_->updateSrcPathPrevs(); arrivals_exist_ = true; stats.report("Find clk arrivals"); } @@ -1036,6 +1045,7 @@ Search::findArrivals1(Level level) Stats stats(debug_, report_); int arrival_count = arrival_iter_->visitParallel(level, arrival_visitor_); deleteTagsPrev(); + genclks_->updateSrcPathPrevs(); stats.report("Find arrivals"); if (arrival_iter_->empty() && invalid_arrivals_->empty()) { @@ -1043,7 +1053,7 @@ Search::findArrivals1(Level level) arrivals_at_endpoints_exist_ = true; } arrivals_exist_ = true; - debugPrint(debug_, "search", 1, "found %u arrivals", arrival_count); + debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count); } void @@ -1066,8 +1076,7 @@ Search::findArrivalsSeed() //////////////////////////////////////////////////////////////// ArrivalVisitor::ArrivalVisitor(const StaState *sta) : - PathVisitor(nullptr, sta), - always_save_prev_paths_(true) + PathVisitor(nullptr, sta) { init0(); init(true); @@ -1104,8 +1113,6 @@ ArrivalVisitor::init(bool always_to_endpoints, always_to_endpoints_ = always_to_endpoints; pred_ = pred; crpr_active_ = sdc_->crprActive(); - if (search_) - always_save_prev_paths_ = search_->alwaysSavePrevPaths(); } @@ -1187,9 +1194,7 @@ ArrivalVisitor::visit(Vertex *vertex) || arrivals_changed) search_->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_); if (arrivals_changed) { - debugPrint(debug_, "search", 4, "arrival changed"); - // Only update arrivals when delays change by more than - // fuzzyEqual can distinguish. + debugPrint(debug_, "search", 4, "arrivals changed"); search_->setVertexArrivals(vertex, tag_bldr_); search_->tnsInvalid(vertex); constrainedRequiredsInvalid(vertex, is_clk); @@ -1239,28 +1244,21 @@ bool Search::arrivalsChanged(Vertex *vertex, TagGroupBldr *tag_bldr) { - Arrival *arrivals1 = graph_->arrivals(vertex); - PathPrev *prev_paths1 = graph_->prevPaths(vertex); - if (arrivals1) { + Path *paths1 = graph_->paths(vertex); + if (paths1) { TagGroup *tag_group = tagGroup(vertex); if (tag_group == nullptr - || tag_group->arrivalMap()->size() != tag_bldr->arrivalMap()->size()) + || tag_group->pathCount() != tag_bldr->pathCount()) return true; - ArrivalMap::Iterator arrival_iter1(tag_group->arrivalMap()); - while (arrival_iter1.hasNext()) { - Tag *tag1; - int arrival_index1; - arrival_iter1.next(tag1, arrival_index1); - Arrival &arrival1 = arrivals1[arrival_index1]; - Tag *tag2; - Arrival arrival2; - int arrival_index2; - tag_bldr->tagMatchArrival(tag1, tag2, arrival2, arrival_index2); - if (tag2 != tag1 - || !delayEqual(arrival1, arrival2) - || (prev_paths1 - && !PathPrev::equal(prev_paths1[arrival_index1], - tag_bldr->prevPath(arrival_index2)))) + for (auto const [tag1, path_index1] : *tag_group->pathIndexMap()) { + Path *path1 = &paths1[path_index1]; + Path *path2 = tag_bldr->tagMatchPath(tag1); + if (path2 == nullptr + || 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()) return true; } return false; @@ -1270,11 +1268,11 @@ Search::arrivalsChanged(Vertex *vertex, } bool -ArrivalVisitor::visitFromToPath(const Pin *, +ArrivalVisitor::visitFromToPath(const Pin * /* from_pin */, Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, @@ -1298,39 +1296,27 @@ ArrivalVisitor::visitFromToPath(const Pin *, to_tag->asString(this)); ClkInfo *to_clk_info = to_tag->clkInfo(); bool to_is_clk = to_tag->isClock(); - Arrival arrival; - int arrival_index; - Tag *tag_match; - tag_bldr_->tagMatchArrival(to_tag, tag_match, arrival, arrival_index); - if (tag_match == nullptr - || delayGreater(to_arrival, arrival, min_max, this)) { + Path *match; + size_t path_index; + tag_bldr_->tagMatchPath(to_tag, match, path_index); + if (match == nullptr + || delayGreater(to_arrival, match->arrival(), min_max, this)) { debugPrint(debug_, "search", 3, " %s + %s = %s %s %s", delayAsString(from_arrival, this), delayAsString(arc_delay, this), delayAsString(to_arrival, this), min_max == MinMax::max() ? ">" : "<", - tag_match ? delayAsString(arrival, this) : "MIA"); - PathPrev prev_path; - bool always_save_prev_paths = true; - bool save_prev = always_save_prev_paths - || to_tag->isClock() - || to_tag->isGenClkSrcPath(); - if (save_prev) - prev_path.init(from_path, edge, arc, this); - tag_bldr_->setMatchArrival(to_tag, tag_match, - to_arrival, arrival_index, - &prev_path); + match ? delayAsString(match->arrival(), this) : "MIA"); + tag_bldr_->setMatchPath(match, path_index, to_tag, to_arrival, from_path, edge, arc); if (crpr_active_ && !has_fanin_one_ && to_clk_info->hasCrprClkPin() && !to_is_clk) { - tag_bldr_no_crpr_->tagMatchArrival(to_tag, tag_match, - arrival, arrival_index); - if (tag_match == nullptr - || delayGreater(to_arrival, arrival, min_max, this)) { - tag_bldr_no_crpr_->setMatchArrival(to_tag, tag_match, - to_arrival, arrival_index, - &prev_path); + tag_bldr_no_crpr_->tagMatchPath(to_tag, match, path_index); + if (match == nullptr + || delayGreater(to_arrival, match->arrival(), min_max, this)) { + tag_bldr_no_crpr_->setMatchPath(match, path_index, to_tag, to_arrival, + from_path, edge, arc); } } } @@ -1341,23 +1327,20 @@ void ArrivalVisitor::pruneCrprArrivals() { CheckCrpr *crpr = search_->checkCrpr(); - ArrivalMap *arrival_map = tag_bldr_->arrivalMap(); - for (auto arrival_itr = arrival_map->cbegin(); arrival_itr != arrival_map->cend(); ) { - Tag *tag = arrival_itr->first; - int arrival_index = arrival_itr->second; + PathIndexMap &path_index_map = tag_bldr_->pathIndexMap(); + for (auto path_itr = path_index_map.cbegin(); path_itr != path_index_map.cend(); ) { + Tag *tag = path_itr->first; + size_t path_index = path_itr->second; ClkInfo *clk_info = tag->clkInfo(); bool deleted_tag = false; if (!tag->isClock() && clk_info->hasCrprClkPin()) { PathAnalysisPt *path_ap = tag->pathAnalysisPt(this); const MinMax *min_max = path_ap->pathMinMax(); - Tag *tag_no_crpr; - Arrival max_arrival; - int max_arrival_index; - tag_bldr_no_crpr_->tagMatchArrival(tag, tag_no_crpr, - max_arrival, max_arrival_index); - if (tag_no_crpr) { - ClkInfo *clk_info_no_crpr = tag_no_crpr->clkInfo(); + Path *path_no_crpr = tag_bldr_no_crpr_->tagMatchPath(tag); + if (path_no_crpr) { + Arrival max_arrival = path_no_crpr->arrival(); + ClkInfo *clk_info_no_crpr = path_no_crpr->clkInfo(this); Arrival max_crpr = crpr->maxCrpr(clk_info_no_crpr); Arrival max_arrival_max_crpr = (min_max == MinMax::max()) ? max_arrival - max_crpr @@ -1367,17 +1350,17 @@ ArrivalVisitor::pruneCrprArrivals() delayAsString(max_arrival, this), delayAsString(max_crpr, this), delayAsString(max_arrival_max_crpr, this)); - Arrival arrival = tag_bldr_->arrival(arrival_index); + Arrival arrival = tag_bldr_->arrival(path_index); if (delayGreater(max_arrival_max_crpr, arrival, min_max, this)) { debugPrint(debug_, "search", 3, " pruned %s", tag->asString(this)); - arrival_itr = arrival_map->erase(arrival_itr); + path_itr = path_index_map.erase(path_itr); deleted_tag = true; } } } if (!deleted_tag) - arrival_itr++; + path_itr++; } } @@ -1506,8 +1489,9 @@ Search::seedArrival(Vertex *vertex) } } else { - debugPrint(debug_, "search", 2, "arrival enqueue %s", - network_->pathName(pin)); + debugPrint(debug_, "search", 4, "arrival enqueue %s %u", + network_->pathName(pin), + vertex->level()); arrival_iter_->enqueue(vertex); } } @@ -1599,7 +1583,7 @@ Search::seedClkArrival(const Pin *pin, sdc_->exceptionFromClkStates(pin,rf,clk,rf,min_max,states); Tag *tag = findTag(rf, path_ap, clk_info, true, nullptr, false, states, true); Arrival arrival(clk_edge->time() + insertion); - tag_bldr->setArrival(tag, arrival, nullptr); + tag_bldr->setArrival(tag, arrival); } void @@ -1616,7 +1600,7 @@ Search::seedClkDataArrival(const Pin *pin, if (tag) { // Data arrivals include insertion delay. Arrival arrival(clk_edge->time() + insertion); - tag_bldr->setArrival(tag, arrival, nullptr); + tag_bldr->setArrival(tag, arrival); } } @@ -1658,7 +1642,7 @@ Search::makeUnclkedPaths(Vertex *vertex, is_segment_start, require_exception); if (tag) { - tag_bldr->setArrival(tag, delay_zero, nullptr); + tag_bldr->setArrival(tag, delay_zero); search_from = true; } } @@ -1869,7 +1853,7 @@ Search::inputDelayRefPinArrival(Path *ref_path, Clock *clk = clk_edge->clock(); if (clk->isPropagated()) { ClkInfo *clk_info = ref_path->clkInfo(this); - ref_arrival = delayAsFloat(ref_path->arrival(this)); + ref_arrival = delayAsFloat(ref_path->arrival()); ref_insertion = delayAsFloat(clk_info->insertion()); ref_latency = clk_info->latency(); } @@ -1930,7 +1914,7 @@ Search::seedInputDelayArrival(const Pin *pin, Tag *tag = inputDelayTag(pin, rf, clk_edge, clk_insertion, clk_latency, input_delay, is_segment_start, min_max, path_ap); if (tag) - tag_bldr->setArrival(tag, arrival, nullptr); + tag_bldr->setArrival(tag, arrival); } void @@ -2075,7 +2059,7 @@ PathVisitor::visitEdge(const Pin *from_pin, TimingArcSet *arc_set = edge->timingArcSet(); VertexPathIterator from_iter(from_vertex, search_); while (from_iter.hasNext()) { - PathVertex *from_path = from_iter.next(); + Path *from_path = from_iter.next(); PathAnalysisPt *path_ap = from_path->pathAnalysisPt(this); const MinMax *min_max = path_ap->pathMinMax(); const RiseFall *from_rf = from_path->transition(this); @@ -2098,7 +2082,7 @@ bool PathVisitor::visitArc(const Pin *from_pin, Vertex *from_vertex, const RiseFall *from_rf, - PathVertex *from_path, + Path *from_path, Edge *edge, TimingArc *arc, const Pin *to_pin, @@ -2120,7 +2104,7 @@ bool PathVisitor::visitFromPath(const Pin *from_pin, Vertex *from_vertex, const RiseFall *from_rf, - PathVertex *from_path, + Path *from_path, Edge *edge, TimingArc *arc, const Pin *to_pin, @@ -2135,7 +2119,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, Tag *to_tag = nullptr; const ClockEdge *clk_edge = from_clk_info->clkEdge(); const Clock *clk = from_clk_info->clock(); - Arrival from_arrival = from_path->arrival(this); + Arrival from_arrival = from_path->arrival(); ArcDelay arc_delay = 0.0; Arrival to_arrival; if (from_clk_info->isGenClkSrcPath()) { @@ -2202,7 +2186,7 @@ PathVisitor::visitFromPath(const Pin *from_pin, && from_tag->isClock())) { const RiseFall *clk_rf = clk_edge ? clk_edge->transition() : nullptr; ClkInfo *to_clk_info = from_clk_info; - if (from_clk_info->crprClkPath().isNull() + if (from_clk_info->crprClkPath(this) == nullptr || network_->direction(to_pin)->isInternal()) to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info, from_path, path_ap); @@ -2308,7 +2292,7 @@ Search::clkPathArrival(const Path *clk_path, + clk_info->latency(); } else - return clk_path->arrival(this); + return clk_path->arrival(); } Arrival @@ -2316,9 +2300,9 @@ Search::pathClkPathArrival(const Path *path) const { ClkInfo *clk_info = path->clkInfo(this); if (clk_info->isPropagated()) { - PathRef src_clk_path = pathClkPathArrival1(path); - if (!src_clk_path.isNull()) - return clkPathArrival(&src_clk_path); + const Path *src_clk_path = pathClkPathArrival1(path); + if (src_clk_path) + return clkPathArrival(src_clk_path); } // Check for input arrival clock. const ClockEdge *clk_edge = path->clkEdge(this); @@ -2328,34 +2312,30 @@ Search::pathClkPathArrival(const Path *path) const } // PathExpanded::expand() and PathExpanded::clkPath(). -PathRef +const Path * Search::pathClkPathArrival1(const Path *path) const { - PathRef p(path); - while (!p.isNull()) { - PathRef prev_path; - TimingArc *prev_arc; - p.prevPath(this, prev_path, prev_arc); + const Path *p = path; + while (p) { + Path *prev_path = p->prevPath(); + Edge *prev_edge = p->prevEdge(this); - if (p.isClock(this)) + if (p->isClock(this)) return p; - if (prev_arc) { - TimingRole *prev_role = prev_arc->role(); + if (prev_edge) { + TimingRole *prev_role = prev_edge->role(); if (prev_role == TimingRole::regClkToQ() || prev_role == TimingRole::latchEnToQ()) { - p.prevPath(this, prev_path, prev_arc); - return prev_path; + return p->prevPath(); } else if (prev_role == TimingRole::latchDtoQ()) { - Edge *prev_edge = p.prevEdge(prev_arc, this); - PathVertex enable_path; - latches_->latchEnablePath(&p, prev_edge, enable_path); + Path *enable_path = latches_->latchEnablePath(p, prev_edge); return enable_path; } } - p.init(prev_path); + p = prev_path; } - return PathRef(); + return nullptr; } //////////////////////////////////////////////////////////////// @@ -2405,7 +2385,7 @@ Search::fromRegClkTag(const Pin *from_pin, // Insert from_path as ClkInfo crpr_clk_path. ClkInfo * Search::clkInfoWithCrprClkPath(ClkInfo *from_clk_info, - PathVertex *from_path, + Path *from_path, const PathAnalysisPt *path_ap) { if (sdc_->crprActive()) @@ -2447,7 +2427,7 @@ Search::thruTag(Tag *from_tag, // thruTag for clocks. Tag * -Search::thruClkTag(PathVertex *from_path, +Search::thruClkTag(Path *from_path, Vertex *from_vertex, Tag *from_tag, bool to_propagates_clk, @@ -2479,7 +2459,7 @@ Search::thruClkTag(PathVertex *from_path, } ClkInfo * -Search::thruClkInfo(PathVertex *from_path, +Search::thruClkInfo(Path *from_path, Vertex *from_vertex, ClkInfo *from_clk_info, bool from_is_clk, @@ -2516,7 +2496,7 @@ Search::thruClkInfo(PathVertex *from_path, changed = true; } - PathVertex *to_crpr_clk_path = nullptr; + Path *to_crpr_clk_path = nullptr; if (sdc_->crprActive() // Update crpr clk path for combinational paths leaving the clock // network (ie, tristate en->out) and buffer driving reg clk. @@ -2747,54 +2727,27 @@ Search::setVertexArrivals(Vertex *vertex, deletePathsIncr(vertex); else { TagGroup *prev_tag_group = tagGroup(vertex); - Arrival *prev_arrivals = graph_->arrivals(vertex); - PathPrev *prev_paths = graph_->prevPaths(vertex); - bool save_prev = always_save_prev_paths_ - || tag_bldr->hasClkTag() - || tag_bldr->hasGenClkSrcTag(); - + Path *prev_paths = graph_->paths(vertex); TagGroup *tag_group = findTagGroup(tag_bldr); - int arrival_count = tag_group->arrivalCount(); - bool has_requireds = vertex->hasRequireds(); - // Reuse arrival array if it is the same size. + size_t path_count = tag_group->pathCount(); + // Reuse path array if it is the same size. if (prev_tag_group - && arrival_count == prev_tag_group->arrivalCount()) { - if (save_prev) { - if (prev_paths == nullptr) - prev_paths = graph_->makePrevPaths(vertex, arrival_count); - } - else { - // Prev paths not required. - prev_paths = nullptr; - graph_->deletePrevPaths(vertex); - } - tag_bldr->copyArrivals(tag_group, prev_arrivals, prev_paths); + && path_count == prev_tag_group->pathCount()) { + tag_bldr->copyPaths(tag_group, prev_paths); vertex->setTagGroupIndex(tag_group->index()); if (tag_group->hasFilterTag()) { LockGuard lock(filtered_arrivals_lock_); filtered_arrivals_->insert(vertex); } - - if (has_requireds) { - requiredInvalid(vertex); - if (tag_group != prev_tag_group) - // Requireds can only be reused if the tag group is unchanged. - graph_->deleteRequireds(vertex); - } + requiredInvalid(vertex); } else { if (prev_tag_group) { - graph_->deleteArrivals(vertex); - if (has_requireds) { - requiredInvalid(vertex); - graph_->deleteRequireds(vertex); - } + graph_->deletePaths(vertex); + requiredInvalid(vertex); } - Arrival *arrivals = graph_->makeArrivals(vertex, arrival_count); - prev_paths = nullptr; - if (save_prev) - prev_paths = graph_->makePrevPaths(vertex, arrival_count); - tag_bldr->copyArrivals(tag_group, arrivals, prev_paths); + Path *paths = graph_->makePaths(vertex, path_count); + tag_bldr->copyPaths(tag_group, paths); vertex->setTagGroupIndex(tag_group->index()); if (tag_group->hasFilterTag()) { @@ -2810,56 +2763,38 @@ Search::reportArrivals(Vertex *vertex) const { report_->reportLine("Vertex %s", vertex->name(sdc_network_)); TagGroup *tag_group = tagGroup(vertex); - Arrival *arrivals = graph_->arrivals(vertex); - Required *requireds = graph_->requireds(vertex); - PathPrev *prev_paths = graph_->prevPaths(vertex); if (tag_group) { report_->reportLine("Group %u", tag_group->index()); - ArrivalMap::Iterator arrival_iter(tag_group->arrivalMap()); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); - PathAnalysisPt *path_ap = tag->pathAnalysisPt(this); + VertexPathIterator path_iter(vertex, this); + while (path_iter.hasNext()) { + const Path *path = path_iter.next(); + const Tag *tag = path->tag(this); + const PathAnalysisPt *path_ap = tag->pathAnalysisPt(this); const RiseFall *rf = tag->transition(); - const char *req = "?"; - if (requireds) - req = delayAsString(requireds[arrival_index], this); - bool report_clk_prev = false; - const char *clk_prev = ""; - if (report_clk_prev - && tag_group->hasClkTag()) { - PathVertex prev = check_crpr_->clkPathPrev(vertex, arrival_index); - if (!prev.isNull()) - clk_prev = prev.name(this); - } + const char *req = delayAsString(path->required(), this); string prev_str; - if (prev_paths) { - PathPrev &prev = prev_paths[arrival_index]; - if (!prev.isNull()) { - prev_str += prev.name(this); - prev_str += " "; - const Edge *prev_edge = prev.prevEdge(this); - TimingArc *arc = prev.prevArc(this); - prev_str += prev_edge->from(graph_)->name(network_); - prev_str += " "; - prev_str += arc->fromEdge()->asString(); - prev_str += " -> "; - prev_str += prev_edge->to(graph_)->name(network_); - prev_str += " "; - prev_str += arc->toEdge()->asString(); - } - else - prev_str = "NULL"; + Path *prev_path = path->prevPath(); + if (prev_path) { + prev_str += prev_path->name(this); + prev_str += " "; + const Edge *prev_edge = path->prevEdge(this); + TimingArc *arc = path->prevArc(this); + prev_str += prev_edge->from(graph_)->name(network_); + prev_str += " "; + prev_str += arc->fromEdge()->asString(); + prev_str += " -> "; + prev_str += prev_edge->to(graph_)->name(network_); + prev_str += " "; + prev_str += arc->toEdge()->asString(); } - report_->reportLine(" %d %s %s %s / %s %s %s prev %s", - arrival_index, + else + prev_str = "NULL"; + report_->reportLine(" %s %s %s / %s %s prev %s", rf->asString(), path_ap->pathMinMax()->asString(), - delayAsString(arrivals[arrival_index], this), + delayAsString(path->arrival(), this), req, tag->asString(true, false, this), - clk_prev, prev_str.c_str()); } } @@ -2913,7 +2848,7 @@ Search::reportTagGroups() const } void -Search::reportArrivalCountHistogram() const +Search::reportPathCountHistogram() const { Vector vertex_counts(10); VertexIterator vertex_iter(graph_); @@ -2921,17 +2856,17 @@ Search::reportArrivalCountHistogram() const Vertex *vertex = vertex_iter.next(); TagGroup *tag_group = tagGroup(vertex); if (tag_group) { - size_t arrival_count = tag_group->arrivalCount(); - if (arrival_count >= vertex_counts.size()) - vertex_counts.resize(arrival_count * 2); - vertex_counts[arrival_count]++; + size_t path_count = tag_group->pathCount(); + if (path_count >= vertex_counts.size()) + vertex_counts.resize(path_count * 2); + vertex_counts[path_count]++; } } - for (size_t arrival_count = 0; arrival_count < vertex_counts.size(); arrival_count++) { - int vertex_count = vertex_counts[arrival_count]; + for (size_t path_count = 0; path_count < vertex_counts.size(); path_count++) { + int vertex_count = vertex_counts[path_count]; if (vertex_count > 0) - report_->reportLine("%6lu %6d", arrival_count, vertex_count); + report_->reportLine("%6lu %6d",path_count, vertex_count); } } @@ -3043,19 +2978,18 @@ Search::findClkInfo(const ClockEdge *clk_edge, float latency, ClockUncertainties *uncertainties, const PathAnalysisPt *path_ap, - PathVertex *crpr_clk_path) + Path *crpr_clk_path) { - PathVertexPtr crpr_clk_path_ptr(crpr_clk_path, this); ClkInfo probe(clk_edge, clk_src, is_propagated, gen_clk_src, gen_clk_src_path, pulse_clk_sense, insertion, latency, uncertainties, - path_ap->index(), crpr_clk_path_ptr, this); + path_ap->index(), crpr_clk_path, this); LockGuard lock(clk_info_lock_); ClkInfo *clk_info = clk_info_set_->findKey(&probe); if (clk_info == nullptr) { clk_info = new ClkInfo(clk_edge, clk_src, is_propagated, gen_clk_src, gen_clk_src_path, pulse_clk_sense, insertion, latency, uncertainties, - path_ap->index(), crpr_clk_path_ptr, this); + path_ap->index(), crpr_clk_path, this); clk_info_set_->insert(clk_info); } return clk_info; @@ -3234,6 +3168,7 @@ 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"); @@ -3398,13 +3333,11 @@ void FindEndRequiredVisitor::visit(PathEnd *path_end) { if (!path_end->isUnconstrained()) { - PathRef &path = path_end->pathRef(); - const MinMax *req_min = path.minMax(sta_)->opposite(); - int arrival_index; - bool arrival_exists; - path.arrivalIndex(arrival_index, arrival_exists); + Path *path = path_end->path(); + const MinMax *min_max = path->minMax(sta_)->opposite(); + size_t path_index = path->pathIndex(sta_); Required required = path_end->requiredTime(sta_); - required_cmp_->requiredSet(arrival_index, required, req_min, sta_); + required_cmp_->requiredSet(path_index, required, min_max, sta_); } } @@ -3449,31 +3382,27 @@ RequiredCmp::requiredsInit(Vertex *vertex, Search *search = sta->search(); TagGroup *tag_group = search->tagGroup(vertex); if (tag_group) { - requireds_.resize(tag_group->arrivalCount()); - ArrivalMap *arrival_entries = tag_group->arrivalMap(); - ArrivalMap::Iterator arrival_iter(arrival_entries); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); + size_t path_count = tag_group->pathCount(); + requireds_.resize(path_count); + for (auto const [tag, path_index] : *tag_group->pathIndexMap()) { PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta); const MinMax *min_max = path_ap->pathMinMax(); - requireds_[arrival_index] = delayInitValue(min_max->opposite()); + requireds_[path_index] = delayInitValue(min_max->opposite()); } } else - requireds_.resize(0); + requireds_.clear(); have_requireds_ = false; } void -RequiredCmp::requiredSet(int arrival_index, - Required required, +RequiredCmp::requiredSet(size_t path_index, + Required &required, const MinMax *min_max, const StaState *sta) { - if (delayGreater(required, requireds_[arrival_index], min_max, sta)) { - requireds_[arrival_index] = required; + if (delayGreater(required, requireds_[path_index], min_max, sta)) { + requireds_[path_index] = required; have_requireds_ = true; } } @@ -3483,53 +3412,26 @@ RequiredCmp::requiredsSave(Vertex *vertex, const StaState *sta) { bool requireds_changed = false; - bool prev_reqs = vertex->hasRequireds(); - if (have_requireds_) { - if (!prev_reqs) - requireds_changed = true; - Debug *debug = sta->debug(); - VertexPathIterator path_iter(vertex, sta); - while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); - int arrival_index; - bool arrival_exists; - path->arrivalIndex(arrival_index, arrival_exists); - Required req = requireds_[arrival_index]; - if (prev_reqs) { - Required prev_req = path->required(sta); - if (!delayEqual(prev_req, req)) { - debugPrint(debug, "search", 3, "required save %s -> %s", - delayAsString(prev_req, sta), - delayAsString(req, sta)); - path->setRequired(req, sta); - requireds_changed = true; - } - } - else { - debugPrint(debug, "search", 3, "required save MIA -> %s", - delayAsString(req, sta)); - path->setRequired(req, sta); - } - } - } - else if (prev_reqs) { - Graph *graph = sta->graph(); - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex); - if (tag_group == nullptr) - requireds_changed = true; - else { - graph->deleteRequireds(vertex); - requireds_changed = true; - } + Debug *debug = sta->debug(); + VertexPathIterator path_iter(vertex, sta); + while (path_iter.hasNext()) { + Path *path = path_iter.next(); + size_t path_index = path->pathIndex(sta); + Required req = requireds_[path_index]; + Required &prev_req = path->required(); + debugPrint(debug, "search", 3, "required save %s -> %s", + delayAsString(prev_req, sta), + delayAsString(req, sta)); + requireds_changed |= !delayEqual(prev_req, req); + path->setRequired(req); } return requireds_changed; } Required -RequiredCmp::required(int arrival_index) +RequiredCmp::required(size_t path_index) { - return requireds_[arrival_index]; + return requireds_[path_index]; } //////////////////////////////////////////////////////////////// @@ -3575,10 +3477,10 @@ RequiredVisitor::visit(Vertex *vertex) bool RequiredVisitor::visitFromToPath(const Pin *, - Vertex *, + Vertex * /* from_vertex */, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &, Edge *edge, TimingArc *, @@ -3599,15 +3501,14 @@ RequiredVisitor::visitFromToPath(const Pin *, debugPrint(debug_, "search", 3, " from tag %2u: %s", from_tag->index(), from_tag->asString(this)); - int arrival_index; - bool arrival_exists; - from_path->arrivalIndex(arrival_index, arrival_exists); + size_t path_index = from_path->pathIndex(this); const MinMax *req_min = min_max->opposite(); TagGroup *to_tag_group = search_->tagGroup(to_vertex); // Check to see if to_tag was pruned. if (to_tag_group && to_tag_group->hasTag(to_tag)) { - PathVertex to_path(to_vertex, to_tag, this); - Required to_required = to_path.required(this); + size_t to_path_index = to_tag_group->pathIndex(to_tag); + Path &to_path = to_vertex->paths()[to_path_index]; + Required &to_required = to_path.required(); Required from_required = to_required - arc_delay; debugPrint(debug_, "search", 3, " to tag %2u: %s", to_tag->index(), @@ -3617,8 +3518,8 @@ RequiredVisitor::visitFromToPath(const Pin *, delayAsString(arc_delay, this), delayAsString(from_required, this), min_max == MinMax::max() ? "<" : ">", - delayAsString(required_cmp_->required(arrival_index), this)); - required_cmp_->requiredSet(arrival_index, from_required, req_min, this); + delayAsString(required_cmp_->required(path_index), this)); + required_cmp_->requiredSet(path_index, from_required, req_min, this); } else { if (search_->crprApproxMissingRequireds()) { @@ -3627,10 +3528,10 @@ RequiredVisitor::visitFromToPath(const Pin *, // as an appromate required. VertexPathIterator to_iter(to_vertex, to_rf, path_ap, this); while (to_iter.hasNext()) { - PathVertex *to_path = to_iter.next(); + Path *to_path = to_iter.next(); Tag *to_path_tag = to_path->tag(this); if (tagMatchNoCrpr(to_path_tag, to_tag)) { - Required to_required = to_path->required(this); + Required to_required = to_path->required(); Required from_required = to_required - arc_delay; debugPrint(debug_, "search", 3, " to tag %2u: %s", to_path_tag->index(), @@ -3640,9 +3541,9 @@ RequiredVisitor::visitFromToPath(const Pin *, delayAsString(arc_delay, this), delayAsString(from_required, this), min_max == MinMax::max() ? "<" : ">", - delayAsString(required_cmp_->required(arrival_index), + delayAsString(required_cmp_->required(path_index), this)); - required_cmp_->requiredSet(arrival_index, from_required, req_min, this); + required_cmp_->requiredSet(path_index, from_required, req_min, this); break; } } @@ -4024,8 +3925,8 @@ void FindEndSlackVisitor::visit(PathEnd *path_end) { if (!path_end->isUnconstrained()) { - PathRef &path = path_end->pathRef(); - PathAPIndex path_ap_index = path.pathAnalysisPtIndex(sta_); + Path *path = path_end->path(); + PathAPIndex path_ap_index = path->pathAnalysisPtIndex(sta_); Slack slack = path_end->slack(sta_); if (delayLess(slack, slacks_[path_ap_index], sta_)) slacks_[path_ap_index] = slack; diff --git a/search/Search.i b/search/Search.i index 9548941e..b1922710 100644 --- a/search/Search.i +++ b/search/Search.i @@ -51,11 +51,11 @@ private: ~VertexPathIterator(); }; -class PathRef +class Path { private: - PathRef(); - ~PathRef(); + Path(); + ~Path(); }; class PathEnd @@ -221,44 +221,32 @@ worst_slack_corner(const Corner *corner, return worst_slack; } -PathRef * +Path * vertex_worst_arrival_path(Vertex *vertex, const MinMax *min_max) { Sta *sta = Sta::sta(); sta->ensureLibLinked(); - PathRef path = sta->vertexWorstArrivalPath(vertex, min_max); - if (!path.isNull()) - return new PathRef(path); - else - return nullptr; + return sta->vertexWorstArrivalPath(vertex, min_max); } -PathRef * +Path * vertex_worst_arrival_path_rf(Vertex *vertex, const RiseFall *rf, MinMax *min_max) { Sta *sta = Sta::sta(); sta->ensureLibLinked(); - PathRef path = sta->vertexWorstArrivalPath(vertex, rf, min_max); - if (!path.isNull()) - return new PathRef(path); - else - return nullptr; + return sta->vertexWorstArrivalPath(vertex, rf, min_max); } -PathRef * +Path * vertex_worst_slack_path(Vertex *vertex, const MinMax *min_max) { Sta *sta = Sta::sta(); sta->ensureLibLinked(); - PathRef path = sta->vertexWorstSlackPath(vertex, min_max); - if (!path.isNull()) - return new PathRef(path); - else - return nullptr; + return sta->vertexWorstSlackPath(vertex, min_max); } int @@ -280,9 +268,9 @@ report_tag_arrivals_cmd(Vertex *vertex) } void -report_arrival_count_histogram() +report_path_count_histogram() { - Sta::sta()->search()->reportArrivalCountHistogram(); + Sta::sta()->search()->reportPathCountHistogram(); } int @@ -310,15 +298,9 @@ clk_info_count() } int -arrival_count() +path_count() { - return Sta::sta()->arrivalCount(); -} - -int -required_count() -{ - return Sta::sta()->requiredCount(); + return Sta::sta()->pathCount(); } int @@ -494,13 +476,7 @@ set_report_path_sigmas(bool report_sigmas) } void -delete_path_ref(PathRef *path) -{ - delete path; -} - -void -report_path_cmd(PathRef *path) +report_path_cmd(Path *path) { Sta::sta()->reportPath(path); } @@ -1245,7 +1221,7 @@ path_end_property(PathEnd *end, } PropertyValue -path_ref_property(PathRef *path, +path_ref_property(Path *path, const char *property) { return getProperty(path, property, Sta::sta()); @@ -1275,7 +1251,7 @@ bool is_output_delay() { return self->isOutputDelay(); } bool is_path_delay() { return self->isPathDelay(); } bool is_gated_clock() { return self->isGatedClock(); } Vertex *vertex() { return self->vertex(Sta::sta()); } -PathRef *path() { return &self->pathRef(); } +Path *path() { return self->path(); } RiseFall *end_transition() { return const_cast(self->path()->transition(Sta::sta())); } Slack slack() { return self->slack(Sta::sta()); } @@ -1312,19 +1288,17 @@ Delay clk_skew() { return self->clkSkew(Sta::sta()); } } -%extend PathRef { +%extend Path { float arrival() { - Sta *sta = Sta::sta(); - return delayAsFloat(self->arrival(sta)); + return delayAsFloat(self->arrival()); } float required() { - Sta *sta = Sta::sta(); - return delayAsFloat(self->required(sta)); + return delayAsFloat(self->required()); } float @@ -1354,12 +1328,10 @@ pins() { Sta *sta = Sta::sta(); PinSeq pins; - PathRef path1(self); - while (!path1.isNull()) { - pins.push_back(path1.vertex(sta)->pin()); - PathRef prev_path; - path1.prevPath(sta, prev_path); - path1.init(prev_path); + Path *path1 = self; + while (path1) { + pins.push_back(path1->vertex(sta)->pin()); + path1 = path1->prevPath(); } return pins; } @@ -1368,11 +1340,10 @@ pins() %extend VertexPathIterator { bool has_next() { return self->hasNext(); } -PathRef * +Path * next() { - Path *path = self->next(); - return new PathRef(path); + return self->next(); } void finish() { delete self; } diff --git a/search/Search.tcl b/search/Search.tcl index 26494e90..6e6aa78c 100644 --- a/search/Search.tcl +++ b/search/Search.tcl @@ -854,7 +854,6 @@ proc_redirect report_path { report_line "Tag: [$path tag]" } report_path_cmd $path - delete_path_ref $path set first 0 } $path_iter finish @@ -865,7 +864,6 @@ proc_redirect report_path { report_line "Tag: [$worst_path tag]" } report_path_cmd $worst_path - delete_path_ref $worst_path } } } diff --git a/search/Sta.cc b/search/Sta.cc index 48ad81b4..c407656d 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2488,6 +2488,8 @@ Sta::searchPreamble() findDelays(); updateGeneratedClks(); sdc_->searchPreamble(); + // Delete results from last findPathEnds because they point to filtered arrivals. + search_->deletePathGroups(); search_->deleteFilteredArrivals(); } @@ -2759,82 +2761,82 @@ Sta::vertexPathIterator(Vertex *vertex, return new VertexPathIterator(vertex, rf, min_max, this); } -PathRef +Path * Sta::vertexWorstArrivalPath(Vertex *vertex, const MinMax *min_max) { return vertexWorstArrivalPath(vertex, nullptr, min_max); } -PathRef +Path * Sta::vertexWorstArrivalPath(Vertex *vertex, const RiseFall *rf, const MinMax *min_max) { - PathRef worst_path; + Path *worst_path = nullptr; Arrival worst_arrival = min_max->initValue(); VertexPathIterator path_iter(vertex, rf, min_max, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); - Arrival arrival = path->arrival(this); + Path *path = path_iter.next(); + Arrival arrival = path->arrival(); if (!path->tag(this)->isGenClkSrcPath() && delayGreater(arrival, worst_arrival, min_max, this)) { worst_arrival = arrival; - worst_path.init(path); + worst_path = path; } } return worst_path; } -PathRef +Path * Sta::vertexWorstRequiredPath(Vertex *vertex, const MinMax *min_max) { return vertexWorstRequiredPath(vertex, nullptr, min_max); } -PathRef +Path * Sta::vertexWorstRequiredPath(Vertex *vertex, const RiseFall *rf, const MinMax *min_max) { - PathRef worst_path; + Path *worst_path = nullptr; const MinMax *req_min_max = min_max->opposite(); Arrival worst_req = req_min_max->initValue(); VertexPathIterator path_iter(vertex, rf, min_max, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); - const Required path_req = path->required(this); + Path *path = path_iter.next(); + const Required path_req = path->required(); if (!path->tag(this)->isGenClkSrcPath() && delayGreater(path_req, worst_req, req_min_max, this)) { worst_req = path_req; - worst_path.init(path); + worst_path = path; } } return worst_path; } -PathRef +Path * Sta::vertexWorstSlackPath(Vertex *vertex, const RiseFall *rf, const MinMax *min_max) { - PathRef worst_path; + Path *worst_path = nullptr; Slack min_slack = MinMax::min()->initValue(); VertexPathIterator path_iter(vertex, rf, min_max, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); Slack slack = path->slack(this); if (!path->tag(this)->isGenClkSrcPath() && delayLess(slack, min_slack, this)) { min_slack = slack; - worst_path.init(path); + worst_path = path; } } return worst_path; } -PathRef +Path * Sta::vertexWorstSlackPath(Vertex *vertex, const MinMax *min_max) @@ -2891,12 +2893,12 @@ Sta::vertexArrival(Vertex *vertex, VertexPathIterator path_iter(vertex, rf, path_ap, this); while (path_iter.hasNext()) { Path *path = path_iter.next(); - const Arrival &path_arrival = path->arrival(this); + const Arrival &path_arrival = path->arrival(); ClkInfo *clk_info = path->clkInfo(search_); if ((clk_edge == clk_edge_wildcard || clk_info->clkEdge() == clk_edge) && !clk_info->isGenClkSrcPath() - && delayGreater(path->arrival(this), arrival, min_max, this)) + && delayGreater(path->arrival(), arrival, min_max, this)) arrival = path_arrival; } return arrival; @@ -2949,7 +2951,7 @@ Sta::vertexRequired(Vertex *vertex, VertexPathIterator path_iter(vertex, rf, path_ap, min_max, this); while (path_iter.hasNext()) { const Path *path = path_iter.next(); - const Required path_required = path->required(this); + const Required path_required = path->required(); if ((clk_edge == clk_edge_wildcard || path->clkEdge(search_) == clk_edge) && delayGreater(path_required, required, req_min_max, this)) @@ -3177,7 +3179,7 @@ bool MinPeriodEndVisitor::pathIsFromInputPort(PathEnd *path_end) { PathExpanded expanded(path_end->path(), sta_); - const PathRef *start = expanded.startPath(); + const Path *start = expanded.startPath(); Graph *graph = sta_->graph(); const Pin *first_pin = start->pin(graph); Network *network = sta_->network(); @@ -3539,14 +3541,14 @@ Sta::pathDcalcAnalysisPt(Path *path) } Vertex * -Sta::maxArrivalCountVertex() const +Sta::maxPathCountVertex() const { Vertex *max_vertex = nullptr; int max_count = 0; VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); - int count = vertexArrivalCount(vertex); + int count = vertexPathCount(vertex); if (count > max_count) { max_count = count; max_vertex = vertex; @@ -3556,36 +3558,23 @@ Sta::maxArrivalCountVertex() const } int -Sta::vertexArrivalCount(Vertex *vertex) const +Sta::vertexPathCount(Vertex *vertex) const { TagGroup *tag_group = search_->tagGroup(vertex); if (tag_group) - return tag_group->arrivalCount(); + return tag_group->pathCount(); else return 0; } int -Sta::arrivalCount() const +Sta::pathCount() const { int count = 0; VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); - count += vertexArrivalCount(vertex); - } - return count; -} - -int -Sta::requiredCount() const -{ - int count = 0; - VertexIterator vertex_iter(graph_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); - if (vertex->hasRequireds()) - count += vertexArrivalCount(vertex); + count += vertexPathCount(vertex); } return count; } @@ -4195,6 +4184,8 @@ Sta::makePortPin(const char *port_name, void Sta::makeInstanceAfter(const Instance *inst) { + debugPrint(debug_, "network_edit", 1, "make instance %s", + sdc_network_->pathName(inst)); if (graph_) { LibertyCell *lib_cell = network_->libertyCell(inst); if (lib_cell) { @@ -4367,6 +4358,9 @@ Sta::replaceCellAfter(const Instance *inst) void Sta::connectPinAfter(const Pin *pin) { + debugPrint(debug_, "network_edit", 1, "connect %s to %s", + sdc_network_->pathName(pin), + sdc_network_->pathName(network_->net(pin))); if (graph_) { if (network_->isHierarchical(pin)) { graph_->makeWireEdgesThruPin(pin); @@ -4453,6 +4447,9 @@ Sta::connectLoadPinAfter(Vertex *vertex) void Sta::disconnectPinBefore(const Pin *pin) { + debugPrint(debug_, "network_edit", 1, "disconnect %s from %s", + sdc_network_->pathName(pin), + sdc_network_->pathName(network_->net(pin))); parasitics_->disconnectPinBefore(pin, network_); sdc_->disconnectPinBefore(pin); sim_->disconnectPinBefore(pin); @@ -4500,10 +4497,11 @@ Sta::disconnectPinBefore(const Pin *pin) void Sta::deleteEdge(Edge *edge) { - Vertex *from = edge->from(graph_); + debugPrint(debug_, "network_edit", 1, "delete edge %s -> %s", + edge->from(graph_)->name(sdc_network_), + edge->to(graph_)->name(sdc_network_)); Vertex *to = edge->to(graph_); - search_->arrivalInvalid(to); - search_->requiredInvalid(from); + search_->deleteEdgeBefore(edge); graph_delay_calc_->delayInvalid(to); levelize_->relevelizeFrom(to); levelize_->deleteEdgeBefore(edge); @@ -4514,6 +4512,8 @@ Sta::deleteEdge(Edge *edge) void Sta::deleteNetBefore(const Net *net) { + debugPrint(debug_, "network_edit", 1, "delete net %s", + sdc_network_->pathName(net)); if (graph_) { NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); while (pin_iter->hasNext()) { @@ -4540,6 +4540,8 @@ Sta::deleteNetBefore(const Net *net) void Sta::deleteInstanceBefore(const Instance *inst) { + debugPrint(debug_, "network_edit", 1, "delete instance %s", + sdc_network_->pathName(inst)); if (network_->isLeaf(inst)) { deleteInstancePinsBefore(inst); deleteLeafInstanceBefore(inst); @@ -5715,7 +5717,7 @@ Sta::activity(const Pin *pin) //////////////////////////////////////////////////////////////// void -Sta::writePathSpice(PathRef *path, +Sta::writePathSpice(Path *path, const char *spice_filename, const char *subckt_filename, const char *lib_subckt_filename, diff --git a/search/Tag.cc b/search/Tag.cc index 3b4ac5de..c04cda93 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -148,10 +148,10 @@ Tag::asString(bool report_index, result += network->pathName(clk_src); } - const PathVertex crpr_clk_path(clk_info_->crprClkPath(), sta); - if (!crpr_clk_path.isNull()) { + const Path *crpr_clk_path = clk_info_->crprClkPath(sta); + if (crpr_clk_path != nullptr) { result += " crpr_pin "; - result += network->pathName(crpr_clk_path.pin(sta)); + result += network->pathName(crpr_clk_path->pin(sta)); } if (input_delay_) { @@ -280,11 +280,12 @@ Tag::findHash() } size_t -Tag::matchHash(bool match_crpr_clk_pin) const +Tag::matchHash(bool match_crpr_clk_pin, + const StaState *sta) const { if (match_crpr_clk_pin) // match_hash_ with crpr clk pin thrown in. - return hashSum(match_hash_, clk_info_->crprClkVertexId()); + return hashSum(match_hash_, clk_info_->crprClkVertexId(sta)); else return match_hash_; } @@ -421,7 +422,7 @@ tagMatch(const Tag *tag1, && clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath() && (!match_crpr_clk_pin || !sta->sdc()->crprActive() - || clk_info1->crprClkVertexId() == clk_info2->crprClkVertexId()) + || clk_info1->crprClkVertexId(sta) == clk_info2->crprClkVertexId(sta)) && tagStateEqual(tag1, tag2)); } @@ -482,8 +483,8 @@ tagMatchCmp(const Tag *tag1, if (match_crpr_clk_pin && sta->sdc()->crprActive()) { - VertexId crpr_vertex1 = clk_info1->crprClkVertexId(); - VertexId crpr_vertex2 = clk_info2->crprClkVertexId(); + VertexId crpr_vertex1 = clk_info1->crprClkVertexId(sta); + VertexId crpr_vertex2 = clk_info2->crprClkVertexId(sta); if (crpr_vertex1 < crpr_vertex2) return -1; if (crpr_vertex1 > crpr_vertex2) @@ -676,7 +677,7 @@ TagMatchHash::TagMatchHash(bool match_crpr_clk_pin, size_t TagMatchHash::operator()(const Tag *tag) const { - return tag->matchHash(match_crpr_clk_pin_); + return tag->matchHash(match_crpr_clk_pin_, sta_); } TagMatchEqual::TagMatchEqual(bool match_crpr_clk_pin, diff --git a/search/Tag.hh b/search/Tag.hh index 10c77d5d..bc74dac9 100644 --- a/search/Tag.hh +++ b/search/Tag.hh @@ -29,7 +29,7 @@ #include "Transition.hh" #include "SdcClass.hh" #include "SearchClass.hh" -#include "PathRef.hh" +#include "Path.hh" namespace sta { @@ -86,7 +86,8 @@ public: bool isFilter() const { return is_filter_; } bool isSegmentStart() const { return is_segment_start_; } size_t hash() const { return hash_; } - size_t matchHash(bool match_crpr_clk_pin) const; + size_t matchHash(bool match_crpr_clk_pin, + const StaState *sta) const; protected: void findHash(); diff --git a/search/TagGroup.cc b/search/TagGroup.cc index 12e6f4e1..ba7bf45d 100644 --- a/search/TagGroup.cc +++ b/search/TagGroup.cc @@ -32,66 +32,70 @@ #include "Tag.hh" #include "Corner.hh" #include "Search.hh" -#include "PathPrev.hh" +#include "Path.hh" namespace sta { TagGroup::TagGroup(TagGroupIndex index, - ArrivalMap *arrival_map, + PathIndexMap *path_index_map, bool has_clk_tag, bool has_genclk_src_tag, bool has_filter_tag, bool has_loop_tag) : - arrival_map_(arrival_map), - hash_(arrivalMapHash(arrival_map_)), + path_index_map_(path_index_map), + hash_(pathIndexMapHash(path_index_map)), index_(index), has_clk_tag_(has_clk_tag), has_genclk_src_tag_(has_genclk_src_tag), has_filter_tag_(has_filter_tag), has_loop_tag_(has_loop_tag), - own_arrival_map_(true) + own_path_map_(true) { } TagGroup::TagGroup(TagGroupBldr *tag_bldr) : - arrival_map_(tag_bldr->arrivalMap()), - hash_(arrivalMapHash(arrival_map_)), - own_arrival_map_(false) + path_index_map_(&tag_bldr->pathIndexMap()), + hash_(pathIndexMapHash(path_index_map_)), + own_path_map_(false) { } TagGroup::~TagGroup() { - if (own_arrival_map_) - delete arrival_map_; + if (own_path_map_) + delete path_index_map_; } size_t -TagGroup::arrivalMapHash(ArrivalMap *arrival_map) +TagGroup::pathIndexMapHash(PathIndexMap *path_index_map) { size_t hash = 0; - ArrivalMap::Iterator arrival_iter(arrival_map); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); + for (auto const [tag, path_index] : *path_index_map) hash += tag->hash(); - } return hash; } bool TagGroup::hasTag(Tag *tag) const { - return arrival_map_->hasKey(tag); + return path_index_map_->hasKey(tag); +} + +size_t +TagGroup::pathIndex(Tag *tag) const +{ + size_t path_index; + bool exists; + pathIndex(tag, path_index, exists); + return path_index; } void -TagGroup::arrivalIndex(Tag *tag, - int &arrival_index, - bool &exists) const +TagGroup::pathIndex(Tag *tag, + size_t &path_index, + bool &exists) const { - arrival_map_->findKey(tag, arrival_index, exists); + path_index_map_->findKey(tag, path_index, exists); } void @@ -99,29 +103,24 @@ TagGroup::report(const StaState *sta) const { Report *report = sta->report(); report->reportLine("Group %u hash = %zu", index_, hash_); - arrivalMapReport(arrival_map_, sta); + pathIndexMapReport(path_index_map_, sta); } void TagGroup::reportArrivalMap(const StaState *sta) const { - arrivalMapReport(arrival_map_, sta); + pathIndexMapReport(path_index_map_, sta); } void -arrivalMapReport(const ArrivalMap *arrival_map, - const StaState *sta) +pathIndexMapReport(const PathIndexMap *path_index_map, + const StaState *sta) { Report *report = sta->report(); - ArrivalMap::ConstIterator arrival_iter(arrival_map); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); - report->reportLine(" %2u %s", - arrival_index, + for (auto const [tag, path_index] : *path_index_map) + report->reportLine(" %2zu %s", + path_index, tag->asString(sta)); - } report->reportBlankLine(); } @@ -129,14 +128,13 @@ arrivalMapReport(const ArrivalMap *arrival_map, TagGroupBldr::TagGroupBldr(bool match_crpr_clk_pin, const StaState *sta) : - default_arrival_count_(sta->corners()->count() - * RiseFall::index_count - * MinMax::index_count), - arrival_map_(default_arrival_count_, - TagMatchHash(match_crpr_clk_pin, sta), - TagMatchEqual(match_crpr_clk_pin, sta)), - arrivals_(default_arrival_count_), - prev_paths_(default_arrival_count_), + default_path_count_(sta->corners()->count() + * RiseFall::index_count + * MinMax::index_count), + path_index_map_(default_path_count_, + TagMatchHash(match_crpr_clk_pin, sta), + TagMatchEqual(match_crpr_clk_pin, sta)), + paths_(default_path_count_), has_clk_tag_(false), has_genclk_src_tag_(false), has_filter_tag_(false), @@ -149,16 +147,15 @@ TagGroupBldr::TagGroupBldr(bool match_crpr_clk_pin, bool TagGroupBldr::empty() { - return arrival_map_.empty(); + return path_index_map_.empty(); } void TagGroupBldr::init(Vertex *vertex) { vertex_ = vertex; - arrival_map_.clear(); - arrivals_.clear(); - prev_paths_.clear(); + path_index_map_.clear(); + paths_.clear(); has_clk_tag_ = false; has_genclk_src_tag_ = false; has_filter_tag_ = false; @@ -168,147 +165,152 @@ TagGroupBldr::init(Vertex *vertex) void TagGroupBldr::reportArrivalEntries() const { - arrivalMapReport(&arrival_map_, sta_); + pathIndexMapReport(&path_index_map_, sta_); +} + +Path * +TagGroupBldr::tagMatchPath(Tag *tag) +{ + Path *match; + size_t path_index; + tagMatchPath(tag, match, path_index); + return match; } void -TagGroupBldr::tagMatchArrival(Tag *tag, - // Return values. - Tag *&tag_match, - Arrival &arrival, - int &arrival_index) const +TagGroupBldr::tagMatchPath(Tag *tag, + // Return values. + Path *&match, + size_t &path_index) { // Find matching group tag. // Match is not necessarily equal to original tag because it // must only satisfy tagMatch. bool exists; - arrival_map_.findKey(tag, tag_match, arrival_index, exists); + Tag *tag_match; + path_index_map_.findKey(tag, tag_match, path_index, exists); if (exists) - arrival = arrivals_[arrival_index]; + match = &paths_[path_index]; else { - tag_match = nullptr; - arrival = -1.0; - arrival_index = -1; + match = nullptr; + path_index = 0; } } Arrival -TagGroupBldr::arrival(int arrival_index) const +TagGroupBldr::arrival(size_t path_index) const { - return arrivals_[arrival_index]; + return paths_[path_index].arrival(); } void TagGroupBldr::setArrival(Tag *tag, - const Arrival &arrival, - PathPrev *prev_path) + const Arrival &arrival) { - Tag *tag_match; - Arrival ignore; - int arrival_index; // Find matching group tag (not necessarily equal to original tag). - tagMatchArrival(tag, tag_match, ignore, arrival_index); - setMatchArrival(tag, tag_match, arrival, arrival_index, prev_path); + Path *match; + size_t path_index; + tagMatchPath(tag, match, path_index); + setMatchPath(match, path_index, tag, arrival, nullptr, nullptr, nullptr); } void -TagGroupBldr::setMatchArrival(Tag *tag, - Tag *tag_match, - const Arrival &arrival, - int arrival_index, - PathPrev *prev_path) +TagGroupBldr::setMatchPath(Path *match, + size_t path_index, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc) { - if (tag_match) { - // If the group_tag exists there has to be an arrival map entry for it. + if (match) { + Tag *tag_match = match->tag(sta_); + // If the tag match exists there has to be a path map entry for it. if (tag_match != tag) { // Replace tag in arrival map. - arrival_map_.erase(tag_match); - arrival_map_.insert(tag, arrival_index); + path_index_map_.erase(tag_match); + path_index_map_.insert(tag, path_index); } - arrivals_[arrival_index] = arrival; - prev_paths_[arrival_index].init(prev_path); + paths_[path_index].init(vertex_, tag, arrival, prev_path, + prev_edge, prev_arc, sta_); } - else { - arrival_index = arrivals_.size(); - arrival_map_.insert(tag, arrival_index); - arrivals_.push_back(arrival); - if (prev_path) - prev_paths_.push_back(*prev_path); - else - prev_paths_.push_back(PathPrev()); + else + insertPath(tag, arrival, prev_path, prev_edge, prev_arc); +} - if (tag->isClock()) - has_clk_tag_ = true; - if (tag->isGenClkSrcPath()) - has_genclk_src_tag_ = true; - if (tag->isFilter() - || tag->clkInfo()->refsFilter(sta_)) - has_filter_tag_ = true; - if (tag->isLoop()) - has_loop_tag_ = true; - if (tag->clkInfo()->isPropagated()) - has_propagated_clk_ = true; - } +void +TagGroupBldr::insertPath(Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc) + +{ + size_t path_index = paths_.size(); + path_index_map_.insert(tag, path_index); + paths_.emplace_back(vertex_, tag, arrival, prev_path, + prev_edge, prev_arc, sta_); + + if (tag->isClock()) + has_clk_tag_ = true; + if (tag->isGenClkSrcPath()) + has_genclk_src_tag_ = true; + if (tag->isFilter() + || tag->clkInfo()->refsFilter(sta_)) + has_filter_tag_ = true; + if (tag->isLoop()) + has_loop_tag_ = true; + if (tag->clkInfo()->isPropagated()) + has_propagated_clk_ = true; +} + +void +TagGroupBldr::insertPath(const Path &path) +{ + insertPath(path.tag(sta_), path.arrival(), path.prevPath(), + path.prevEdge(sta_), path.prevArc(sta_)); } TagGroup * TagGroupBldr::makeTagGroup(TagGroupIndex index, const StaState *sta) { - return new TagGroup(index, makeArrivalMap(sta), + return new TagGroup(index, makePathIndexMap(sta), has_clk_tag_, has_genclk_src_tag_, has_filter_tag_, has_loop_tag_); } -ArrivalMap * -TagGroupBldr::makeArrivalMap(const StaState *sta) +PathIndexMap * +TagGroupBldr::makePathIndexMap(const StaState *sta) { - ArrivalMap *arrival_map = new ArrivalMap(arrival_map_.size(), - TagMatchHash(true, sta), - TagMatchEqual(true, sta)); - int arrival_index = 0; - ArrivalMap::Iterator arrival_iter(arrival_map_); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index1; - arrival_iter.next(tag, arrival_index1); - arrival_map->insert(tag, arrival_index); - arrival_index++; + PathIndexMap *path_index_map = new PathIndexMap(path_index_map_.size(), + TagMatchHash(true, sta), + TagMatchEqual(true, sta)); + + size_t path_index = 0; + for (auto const [tag, path_index1] : path_index_map_) { + path_index_map->insert(tag, path_index); + path_index++; } - return arrival_map; + return path_index_map; } void -TagGroupBldr::copyArrivals(TagGroup *tag_group, - Arrival *arrivals, - PathPrev *prev_paths) +TagGroupBldr::copyPaths(TagGroup *tag_group, + Path *paths) { - ArrivalMap::Iterator arrival_iter1(arrival_map_); - while (arrival_iter1.hasNext()) { - Tag *tag1; - int arrival_index1, arrival_index2; - arrival_iter1.next(tag1, arrival_index1); + for (auto const [tag1, path_index1] : path_index_map_) { + size_t path_index2; bool exists2; - tag_group->arrivalIndex(tag1, arrival_index2, exists2); - if (exists2) { - arrivals[arrival_index2] = arrivals_[arrival_index1]; - if (prev_paths) { - PathPrev *prev_path = &prev_paths_[arrival_index1]; - prev_paths[arrival_index2].init(prev_path); - } - } + tag_group->pathIndex(tag1, path_index2, exists2); + if (exists2) + paths[path_index2] = paths_[path_index1]; else sta_->report()->critical(1351, "tag group missing tag"); } } -PathPrev & -TagGroupBldr::prevPath(int arrival_index) -{ - return prev_paths_[arrival_index]; -} - //////////////////////////////////////////////////////////////// size_t @@ -318,19 +320,15 @@ TagGroupHash::operator()(const TagGroup *group) const } static bool -arrivalMapEqual(const ArrivalMap *arrival_map1, - const ArrivalMap *arrival_map2) +pathIndexMapEqual(const PathIndexMap *path_index_map1, + const PathIndexMap *path_index_map2) { - int arrival_count1 = arrival_map1->size(); - int arrival_count2 = arrival_map2->size(); - if (arrival_count1 == arrival_count2) { - ArrivalMap::ConstIterator arrival_iter1(arrival_map1); - while (arrival_iter1.hasNext()) { - Tag *tag1, *tag2; - int arrival_index1, arrival_index2; - arrival_iter1.next(tag1, arrival_index1); + if (path_index_map1->size() == path_index_map2->size()) { + for (auto const [tag1, path_index1] : *path_index_map1) { + Tag *tag2; + size_t path_index2; bool exists2; - arrival_map2->findKey(tag1, tag2, arrival_index2, exists2); + path_index_map2->findKey(tag1, tag2, path_index2, exists2); if (!exists2 // ArrivalMap equal function is TagMatchEqual, so make sure // the tag is an exact match. @@ -349,8 +347,8 @@ TagGroupEqual::operator()(const TagGroup *tag_group1, { return tag_group1 == tag_group2 || (tag_group1->hash() == tag_group2->hash() - && arrivalMapEqual(tag_group1->arrivalMap(), - tag_group2->arrivalMap())); + && pathIndexMapEqual(tag_group1->pathIndexMap(), + tag_group2->pathIndexMap())); } } // namespace diff --git a/search/TagGroup.hh b/search/TagGroup.hh index 9467e757..2d36aedf 100644 --- a/search/TagGroup.hh +++ b/search/TagGroup.hh @@ -37,13 +37,11 @@ namespace sta { class TagGroupBldr; -typedef Vector PathPrevSeq; - class TagGroup { public: TagGroup(TagGroupIndex index, - ArrivalMap *arrival_map, + PathIndexMap *path_index_map, bool has_clk_tag, bool has_genclk_src_tag, bool has_filter_tag, @@ -59,26 +57,27 @@ public: bool hasGenClkSrcTag() const { return has_genclk_src_tag_; } bool hasFilterTag() const { return has_filter_tag_; } bool hasLoopTag() const { return has_loop_tag_; } - bool ownArrivalMap() const { return own_arrival_map_; } - int arrivalCount() const { return arrival_map_->size(); } - void arrivalIndex(Tag *tag, - int &arrival_index, - bool &exists) const; - ArrivalMap *arrivalMap() const { return arrival_map_; } + bool ownPathMap() const { return own_path_map_; } + size_t pathCount() const { return path_index_map_->size(); } + void pathIndex(Tag *tag, + size_t &path_index, + bool &exists) const; + size_t pathIndex(Tag *tag) const; + PathIndexMap *pathIndexMap() const { return path_index_map_; } bool hasTag(Tag *tag) const; protected: - size_t arrivalMapHash(ArrivalMap *arrival_map); + static size_t pathIndexMapHash(PathIndexMap *path_index_map); - // tag -> arrival index - ArrivalMap *arrival_map_; + // tag -> path index + PathIndexMap *path_index_map_; size_t hash_; unsigned int index_:tag_group_index_bits; bool has_clk_tag_:1; bool has_genclk_src_tag_:1; bool has_filter_tag_:1; bool has_loop_tag_:1; - bool own_arrival_map_:1; + bool own_path_map_:1; }; class TagGroupHash @@ -106,40 +105,46 @@ public: void reportArrivalEntries() const; TagGroup *makeTagGroup(TagGroupIndex index, const StaState *sta); + size_t pathCount() const { return path_index_map_.size();; } bool hasClkTag() const { return has_clk_tag_; } bool hasGenClkSrcTag() const { return has_genclk_src_tag_; } bool hasFilterTag() const { return has_filter_tag_; } bool hasLoopTag() const { return has_loop_tag_; } bool hasPropagatedClk() const { return has_propagated_clk_; } - void tagMatchArrival(Tag *tag, - // Return values. - Tag *&tag_match, - Arrival &arrival, - int &arrival_index) const; - Arrival arrival(int arrival_index) const; + Path *tagMatchPath(Tag *tag); + void tagMatchPath(Tag *tag, + // Return values. + Path *&match, + size_t &path_index); + Arrival arrival(size_t path_index) const; + // prev_path == hull void setArrival(Tag *tag, - const Arrival &arrival, - PathPrev *prev_path); - void setMatchArrival(Tag *tag, - Tag *tag_match, - const Arrival &arrival, - int arrival_index, - PathPrev *prev_path); - ArrivalMap *arrivalMap() { return &arrival_map_; } - PathPrev &prevPath(int arrival_index); - void copyArrivals(TagGroup *tag_group, - Arrival *arrivals, - PathPrev *prev_paths); + const Arrival &arrival); + void setMatchPath(Path *match, + size_t path_index, + Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc); + void insertPath(Tag *tag, + Arrival arrival, + Path *prev_path, + Edge *prev_edge, + TimingArc *prev_arc); + void insertPath(const Path &path); + PathIndexMap &pathIndexMap() { return path_index_map_; } + void copyPaths(TagGroup *tag_group, + Path *paths); protected: int tagMatchIndex(); - ArrivalMap *makeArrivalMap(const StaState *sta); + PathIndexMap *makePathIndexMap(const StaState *sta); Vertex *vertex_; - int default_arrival_count_; - ArrivalMap arrival_map_; - ArrivalSeq arrivals_; - PathPrevSeq prev_paths_; + int default_path_count_; + PathIndexMap path_index_map_; + vector paths_; bool has_clk_tag_; bool has_genclk_src_tag_; bool has_filter_tag_; @@ -149,7 +154,7 @@ protected: }; void -arrivalMapReport(const ArrivalMap *arrival_map, - const StaState *sta); +pathIndexMapReport(const PathIndexMap *path_index_map, + const StaState *sta); } // namespace diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index d7d409d9..71c5bce3 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -34,7 +34,7 @@ #include "Graph.hh" #include "ClkInfo.hh" #include "Tag.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "PathAnalysisPt.hh" #include "PathEnd.hh" #include "Search.hh" @@ -91,7 +91,7 @@ VisitPathEnds::visitClkedPathEnds(const Pin *pin, bool is_segment_start = search_->isSegmentStart(pin); VertexPathIterator path_iter(vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); PathAnalysisPt *path_ap = path->pathAnalysisPt(this); const MinMax *path_min_max = path_ap->pathMinMax(); const RiseFall *end_rf = path->transition(this); @@ -161,7 +161,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin, VertexPathIterator tgt_clk_path_iter(tgt_clk_vertex, clk_rf, tgt_clk_path_ap, this); while (tgt_clk_path_iter.hasNext()) { - PathVertex *tgt_clk_path = tgt_clk_path_iter.next(); + Path *tgt_clk_path = tgt_clk_path_iter.next(); ClkInfo *tgt_clk_info = tgt_clk_path->clkInfo(this); const ClockEdge *tgt_clk_edge = tgt_clk_path->clkEdge(this); const Clock *tgt_clk = tgt_clk_path->clock(this); @@ -318,7 +318,7 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, RiseFall *ref_rf = output_delay->refTransition(); VertexPathIterator ref_path_iter(ref_vertex,ref_rf,path_ap,this); while (ref_path_iter.hasNext()) { - PathVertex *ref_path = ref_path_iter.next(); + Path *ref_path = ref_path_iter.next(); if (ref_path->isClock(this) && (tgt_clk == nullptr || ref_path->clock(this) == tgt_clk)) @@ -343,7 +343,7 @@ VisitPathEnds::visitOutputDelayEnd1(OutputDelay *output_delay, Path *path, const RiseFall *end_rf, const ClockEdge *tgt_clk_edge, - PathVertex *ref_path, + Path *ref_path, const MinMax *min_max, PathEndVisitor *visitor, bool &is_constrained) @@ -414,7 +414,7 @@ VisitPathEnds::visitGatedClkEnd(const Pin *pin, min_max); VertexPathIterator clk_path_iter(clk_vertex, clk_rf, clk_path_ap, this); while (clk_path_iter.hasNext()) { - PathVertex *clk_path = clk_path_iter.next(); + Path *clk_path = clk_path_iter.next(); const ClockEdge *clk_edge = clk_path->clkEdge(this); const Clock *clk = clk_edge ? clk_edge->clock() : nullptr; if (clk_path->isClock(this) @@ -544,7 +544,7 @@ VisitPathEnds::visitDataCheckEnd1(DataCheck *check, bool found_from_path = false; VertexPathIterator tgt_clk_path_iter(from_vertex,from_rf,clk_ap,this); while (tgt_clk_path_iter.hasNext()) { - PathVertex *tgt_clk_path = tgt_clk_path_iter.next(); + Path *tgt_clk_path = tgt_clk_path_iter.next(); const ClockEdge *tgt_clk_edge = tgt_clk_path->clkEdge(this); // Ignore generated clock source paths. if (tgt_clk_edge @@ -584,7 +584,7 @@ VisitPathEnds::visitUnconstrainedPathEnds(const Pin *pin, { VertexPathIterator path_iter(vertex, this); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); PathAnalysisPt *path_ap = path->pathAnalysisPt(this); const MinMax *path_min_max = path_ap->pathMinMax(); if ((corner == nullptr diff --git a/search/VisitPathGroupVertices.cc b/search/VisitPathGroupVertices.cc index 2d4217bc..cada566e 100644 --- a/search/VisitPathGroupVertices.cc +++ b/search/VisitPathGroupVertices.cc @@ -28,21 +28,20 @@ #include "Graph.hh" #include "Bfs.hh" #include "Search.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "PathEnd.hh" #include "Tag.hh" #include "VisitPathEnds.hh" namespace sta { -typedef Set PathVertexSet; -typedef Map VertexPathSetMap; +typedef Set PathSet; +typedef Map VertexPathSetMap; static void vertexPathSetMapInsertPath(VertexPathSetMap *matching_path_map, Vertex *vertex, Tag *tag, - int arrival_index, const StaState *sta); // Visit each path end for a vertex and add the worst one in each @@ -87,7 +86,7 @@ protected: Vertex *from_vertex, const RiseFall *from_rf, Tag *from_tag, - PathVertex *from_path, + Path *from_path, const Arrival &from_arrival, Edge *edge, TimingArc *arc, @@ -99,8 +98,7 @@ protected: const MinMax *min_max, const PathAnalysisPt *path_ap); void fromMatches(Vertex *from_vertex, - Tag *from_tag, - int from_arrival_index); + Tag *from_tag); private: VertexVisitor *visitor_; @@ -139,10 +137,10 @@ visitPathGroupVertices(PathGroup *path_group, // Cleanup. VertexPathSetMap::Iterator matching_iter(matching_path_map); while (matching_iter.hasNext()) { - PathVertexSet *paths = matching_iter.next(); - PathVertexSet::Iterator path_iter(paths); + PathSet *paths = matching_iter.next(); + PathSet::Iterator path_iter(paths); while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); + Path *path = path_iter.next(); delete path; } delete paths; @@ -181,14 +179,9 @@ VisitPathGroupEnds::visit(PathEnd *path_end) { PathGroup *group = sta_->search()->pathGroup(path_end); if (group == path_group_) { - PathRef path(path_end->pathRef()); - Vertex *vertex = path.vertex(sta_); - - int arrival_index; - bool arrival_exists; - path.arrivalIndex(arrival_index, arrival_exists); - vertexPathSetMapInsertPath(matching_path_map_, vertex, path.tag(sta_), - arrival_index, sta_); + Path *path = path_end->path(); + Vertex *vertex = path->vertex(sta_); + vertexPathSetMapInsertPath(matching_path_map_, vertex, path->tag(sta_), sta_); vertex_matches_ = true; } } @@ -197,16 +190,15 @@ static void vertexPathSetMapInsertPath(VertexPathSetMap *matching_path_map, Vertex *vertex, Tag *tag, - int arrival_index, const StaState *sta) { - PathVertexSet *matching_paths = matching_path_map->findKey(vertex); + PathSet *matching_paths = matching_path_map->findKey(vertex); if (matching_paths == nullptr) { PathLess path_less(sta); - matching_paths = new PathVertexSet(path_less); + matching_paths = new PathSet(path_less); (*matching_path_map)[vertex] = matching_paths; } - PathVertex *vpath = new PathVertex(vertex, tag, arrival_index); + Path *vpath = new Path(vertex, tag, sta); matching_paths->insert(vpath); } @@ -262,7 +254,7 @@ PathGroupPathVisitor::visitFromToPath(const Pin *, Vertex *from_vertex, const RiseFall *, Tag *from_tag, - PathVertex *from_path, + Path *, const Arrival &, Edge *, TimingArc *, @@ -274,12 +266,9 @@ PathGroupPathVisitor::visitFromToPath(const Pin *, const MinMax *, const PathAnalysisPt *path_ap) { - PathVertexSet *matching_paths = matching_path_map_->findKey(to_vertex); + PathSet *matching_paths = matching_path_map_->findKey(to_vertex); if (matching_paths) { - int arrival_index; - bool arrival_exists; - from_path->arrivalIndex(arrival_index, arrival_exists); - PathVertex to_path(to_vertex, to_tag, this); + Path to_path(to_vertex, to_tag, this); if (!to_path.isNull()) { if (matching_paths->hasKey(&to_path)) { debugPrint(debug_, "visit_path_group", 2, "match %s %s -> %s %s", @@ -287,13 +276,13 @@ PathGroupPathVisitor::visitFromToPath(const Pin *, from_tag->asString(this), to_vertex->name(network_), to_tag->asString(this)); - fromMatches(from_vertex, from_tag, arrival_index); + fromMatches(from_vertex, from_tag); } } else { VertexPathIterator to_iter(to_vertex, to_rf, path_ap, this); while (to_iter.hasNext()) { - PathVertex *to_path = to_iter.next(); + Path *to_path = to_iter.next(); if (tagMatchNoCrpr(to_path->tag(this), to_tag) && matching_paths->hasKey(to_path)) { debugPrint(debug_, "visit_path_group", 2, @@ -302,7 +291,7 @@ PathGroupPathVisitor::visitFromToPath(const Pin *, from_tag->asString(this), to_vertex->name(network_), to_tag->asString(this)); - fromMatches(from_vertex, from_tag, arrival_index); + fromMatches(from_vertex, from_tag); } } } @@ -312,12 +301,11 @@ PathGroupPathVisitor::visitFromToPath(const Pin *, void PathGroupPathVisitor::fromMatches(Vertex *from_vertex, - Tag *from_tag, - int from_arrival_index) + Tag *from_tag) { vertex_matches_ = true; vertexPathSetMapInsertPath(matching_path_map_, from_vertex, - from_tag, from_arrival_index, this); + from_tag, this); } } // namespace diff --git a/spice/WritePathSpice.cc b/spice/WritePathSpice.cc index bc4136ca..d1874c42 100644 --- a/spice/WritePathSpice.cc +++ b/spice/WritePathSpice.cc @@ -45,7 +45,6 @@ #include "Parasitics.hh" #include "PathAnalysisPt.hh" #include "Path.hh" -#include "PathRef.hh" #include "PathExpanded.hh" #include "StaState.hh" #include "search/Sim.hh" @@ -118,11 +117,11 @@ private: int stageGateInputPathIndex(Stage stage); int stageDrvrPathIndex(Stage stage); int stageLoadPathIndex(Stage stage); - const PathRef *stageGateInputPath(Stage stage); - const PathRef *stageDrvrPath(Stage stage); - const PathRef *stageLoadPath(Stage stage); - TimingArc *stageGateArc(Stage stage); - TimingArc *stageWireArc(Stage stage); + const Path *stageGateInputPath(Stage stage); + const Path *stageDrvrPath(Stage stage); + const Path *stageLoadPath(Stage stage); + const TimingArc *stageGateArc(Stage stage); + const TimingArc *stageWireArc(Stage stage); Edge *stageGateEdge(Stage stage); Edge *stageWireEdge(Stage stage); Pin *stageGateInputPin(Stage stage); @@ -139,7 +138,7 @@ private: float findSlew(const Path *path); float findSlew(const Path *path, const RiseFall *rf, - TimingArc *next_arc); + const TimingArc *next_arc); Path *path_; PathExpanded path_expanded_; // Input clock waveform cycles. @@ -246,7 +245,7 @@ float WritePathSpice::maxTime() { Stage input_stage = stageFirst(); - const PathRef *input_path = stageDrvrPath(input_stage); + const Path *input_path = stageDrvrPath(input_stage); if (input_path->isClock(this)) { const Clock *clk = input_path->clock(this); float period = clk->period(); @@ -264,7 +263,7 @@ WritePathSpice::pathMaxTime() { float max_time = 0.0; for (size_t i = 0; i < path_expanded_.size(); i++) { - const PathRef *path = path_expanded_.path(i); + const Path *path = path_expanded_.path(i); const RiseFall *rf = path->transition(this); Vertex *vertex = path->vertex(this); float path_max_slew = railToRailSlew(findSlew(vertex,rf,nullptr), rf); @@ -278,7 +277,7 @@ WritePathSpice::pathMaxTime() path_max_slew = load_slew; } } - float path_max_time = delayAsFloat(path->arrival(this)) + path_max_slew * 2.0; + float path_max_time = delayAsFloat(path->arrival()) + path_max_slew * 2.0; if (path_max_time > max_time) max_time = path_max_time; } @@ -321,7 +320,7 @@ WritePathSpice::writeInputSource() streamPrint(spice_stream_, "**************\n\n"); Stage input_stage = stageFirst(); - const PathRef *input_path = stageDrvrPath(input_stage); + const Path *input_path = stageDrvrPath(input_stage); if (input_path->isClock(this)) writeClkWaveform(); else @@ -333,9 +332,9 @@ void WritePathSpice::writeInputWaveform() { Stage input_stage = stageFirst(); - const PathRef *input_path = stageDrvrPath(input_stage); + const Path *input_path = stageDrvrPath(input_stage); const RiseFall *rf = input_path->transition(this); - TimingArc *next_arc = stageGateArc(input_stage + 1); + const TimingArc *next_arc = stageGateArc(input_stage + 1); float slew0 = findSlew(input_path, rf, next_arc); float threshold = default_library_->inputThreshold(rf); @@ -358,8 +357,8 @@ void WritePathSpice::writeClkWaveform() { Stage input_stage = stageFirst(); - const PathRef *input_path = stageDrvrPath(input_stage); - TimingArc *next_arc = stageGateArc(input_stage + 1); + const Path *input_path = stageDrvrPath(input_stage); + const TimingArc *next_arc = stageGateArc(input_stage + 1); const ClockEdge *clk_edge = input_path->clkEdge(this); const Clock *clk = clk_edge->clock(); @@ -403,7 +402,7 @@ WritePathSpice::findSlew(const Path *path) float WritePathSpice::findSlew(const Path *path, const RiseFall *rf, - TimingArc *next_arc) + const TimingArc *next_arc) { Vertex *vertex = path->vertex(this); return findSlew(vertex, rf, next_arc); @@ -419,9 +418,9 @@ WritePathSpice::writeMeasureStmts() streamPrint(spice_stream_, "********************\n\n"); for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { - const PathRef *gate_input_path = stageGateInputPath(stage); - const PathRef *drvr_path = stageDrvrPath(stage); - const PathRef *load_path = stageLoadPath(stage); + const Path *gate_input_path = stageGateInputPath(stage); + const Path *drvr_path = stageDrvrPath(stage); + const Path *load_path = stageLoadPath(stage); if (gate_input_path) { // gate input -> gate output writeMeasureSlewStmt(stage, gate_input_path); @@ -520,7 +519,7 @@ WritePathSpice::writeGateStage(Stage stage) drvr_port->name()); writeSubcktInst(inst); - const PathRef *drvr_path = stageDrvrPath(stage); + const Path *drvr_path = stageDrvrPath(stage); const RiseFall *drvr_rf = drvr_path->transition(this); Edge *gate_edge = stageGateEdge(stage); @@ -550,7 +549,7 @@ WritePathSpice::writeGateStage(Stage stage) void WritePathSpice::writeStageParasitics(Stage stage) { - const PathRef *drvr_path = stageDrvrPath(stage); + const Path *drvr_path = stageDrvrPath(stage); DcalcAnalysisPt *dcalc_ap = drvr_path->dcalcAnalysisPt(this); ParasiticAnalysisPt *parasitic_ap = dcalc_ap->parasiticAnalysisPt(); const Pin *drvr_pin = stageDrvrPin(stage); @@ -579,7 +578,7 @@ WritePathSpice::findPathCellNames() { StdStringSet path_cell_names; for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { - TimingArc *arc = stageGateArc(stage); + const TimingArc *arc = stageGateArc(stage); if (arc) { LibertyCell *cell = arc->set()->libertyCell(); if (cell) { @@ -643,64 +642,62 @@ WritePathSpice::stageLoadPathIndex(Stage stage) return stage * 2 - 1; } -const PathRef * +const Path * WritePathSpice::stageGateInputPath(Stage stage) { int path_index = stageGateInputPathIndex(stage); return path_expanded_.path(path_index); } -const PathRef * +const Path * WritePathSpice::stageDrvrPath(Stage stage) { int path_index = stageDrvrPathIndex(stage); return path_expanded_.path(path_index); } -const PathRef * +const Path * WritePathSpice::stageLoadPath(Stage stage) { int path_index = stageLoadPathIndex(stage); return path_expanded_.path(path_index); } -TimingArc * +const TimingArc * WritePathSpice::stageGateArc(Stage stage) { int path_index = stageDrvrPathIndex(stage); if (path_index >= 0) - return path_expanded_.prevArc(path_index); + return path_expanded_.path(path_index)->prevArc(this); else return nullptr; } -TimingArc * +const TimingArc * WritePathSpice::stageWireArc(Stage stage) { int path_index = stageLoadPathIndex(stage); - return path_expanded_.prevArc(path_index); + return path_expanded_.path(path_index)->prevArc(this); } Edge * WritePathSpice::stageGateEdge(Stage stage) { - const PathRef *path = stageDrvrPath(stage); - TimingArc *arc = stageGateArc(stage); - return path->prevEdge(arc, this); + const Path *path = stageDrvrPath(stage); + return path->prevEdge(this); } Edge * WritePathSpice::stageWireEdge(Stage stage) { - const PathRef *path = stageLoadPath(stage); - TimingArc *arc = stageWireArc(stage); - return path->prevEdge(arc, this); + const Path *path = stageLoadPath(stage); + return path->prevEdge(this); } Pin * WritePathSpice::stageGateInputPin(Stage stage) { - const PathRef *path = stageGateInputPath(stage); + const Path *path = stageGateInputPath(stage); return path->pin(this); } @@ -714,7 +711,7 @@ WritePathSpice::stageGateInputPort(Stage stage) Pin * WritePathSpice::stageDrvrPin(Stage stage) { - const PathRef *path = stageDrvrPath(stage); + const Path *path = stageDrvrPath(stage); return path->pin(this); } @@ -728,7 +725,7 @@ WritePathSpice::stageDrvrPort(Stage stage) Pin * WritePathSpice::stageLoadPin(Stage stage) { - const PathRef *path = stageLoadPath(stage); + const Path *path = stageLoadPath(stage); return path->pin(this); } diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index 14de0f34..1be4e187 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.cc @@ -39,7 +39,7 @@ #include "Graph.hh" #include "search/Sim.hh" #include "Clock.hh" -#include "PathVertex.hh" +#include "Path.hh" #include "DcalcAnalysisPt.hh" #include "Bdd.hh" @@ -474,7 +474,7 @@ WriteSpice::pgPortVoltage(LibertyPgPort *pg_port) float WriteSpice::findSlew(Vertex *vertex, const RiseFall *rf, - TimingArc *next_arc) + const TimingArc *next_arc) { float slew = delayAsFloat(graph_->slew(vertex, rf, dcalc_ap_->index())); if (slew == 0.0 && next_arc) @@ -486,7 +486,7 @@ WriteSpice::findSlew(Vertex *vertex, // Look up the smallest slew axis value in the timing arc delay table. float -WriteSpice::slewAxisMinValue(TimingArc *arc) +WriteSpice::slewAxisMinValue(const TimingArc *arc) { GateTableModel *gate_model = arc->gateTableModel(dcalc_ap_); if (gate_model) { diff --git a/spice/WriteSpice.hh b/spice/WriteSpice.hh index 373a22fb..0396764c 100644 --- a/spice/WriteSpice.hh +++ b/spice/WriteSpice.hh @@ -135,8 +135,8 @@ protected: const char *spiceTrans(const RiseFall *rf); float findSlew(Vertex *vertex, const RiseFall *rf, - TimingArc *next_arc); - float slewAxisMinValue(TimingArc *arc); + const TimingArc *next_arc); + float slewAxisMinValue(const TimingArc *arc); float clkWaveformTimeOffset(const Clock *clk); void gatePortValues(const Pin *input_pin, diff --git a/spice/WriteSpice.i b/spice/WriteSpice.i index 4078cd19..727bf82b 100644 --- a/spice/WriteSpice.i +++ b/spice/WriteSpice.i @@ -33,7 +33,7 @@ %inline %{ void -write_path_spice_cmd(PathRef *path, +write_path_spice_cmd(Path *path, const char *spice_filename, const char *subckt_filename, const char *lib_subckt_filename, diff --git a/tcl/Property.tcl b/tcl/Property.tcl index 4e08b5dd..db86f055 100644 --- a/tcl/Property.tcl +++ b/tcl/Property.tcl @@ -77,7 +77,7 @@ proc get_object_property { object prop } { return [edge_property $object $prop] } elseif { $object_type == "PathEnd" } { return [path_end_property $object $prop] - } elseif { $object_type == "PathRef" } { + } elseif { $object_type == "Path" } { return [path_ref_property $object $prop] } elseif { $object_type == "TimingArcSet" } { return [timing_arc_set_property $object $prop] diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index dd3f1c63..bcc2b2d3 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -42,7 +42,7 @@ #include "Clock.hh" #include "Corner.hh" #include "Search.hh" -#include "PathRef.hh" +#include "Path.hh" #include "search/Tag.hh" #include "PathEnd.hh" #include "SearchClass.hh" @@ -1138,17 +1138,17 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } -%typemap(out) PathRefSeq* { +%typemap(out) PathSeq* { Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false); Tcl_SetObjResult(interp, obj); Tcl_Obj *list = Tcl_NewListObj(0, nullptr); - PathRefSeq *paths = $1; - PathRefSeq::Iterator path_iter(paths); + PathSeq *paths = $1; + PathSeq::Iterator path_iter(paths); while (path_iter.hasNext()) { - PathRef *path = &path_iter.next(); - PathRef *copy = new PathRef(path); - Tcl_Obj *obj = SWIG_NewInstanceObj(copy, SWIGTYPE_p_PathRef, false); + Path *path = &path_iter.next(); + Path *copy = new Path(path); + Tcl_Obj *obj = SWIG_NewInstanceObj(copy, SWIGTYPE_p_Path, false); Tcl_ListObjAppendElement(interp, list, obj); } Tcl_SetObjResult(interp, list); @@ -1354,11 +1354,10 @@ using namespace sta; Tcl_SetObjResult(interp, list); } break; - case PropertyValue::Type::type_path_refs: { + case PropertyValue::Type::type_paths: { Tcl_Obj *list = Tcl_NewListObj(0, nullptr); - for (PathRef &path : *value.pathRefs()) { - PathRef *copy = new PathRef(path); - Tcl_Obj *obj = SWIG_NewInstanceObj(copy, SWIGTYPE_p_PathRef, false); + for (const Path *path : *value.paths()) { + Tcl_Obj *obj = SWIG_NewInstanceObj(const_cast(path), SWIGTYPE_p_Path, false); Tcl_ListObjAppendElement(interp, list, obj); } Tcl_SetObjResult(interp, list);