diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67b8de44..89f70ac0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -158,6 +158,7 @@ set(STA_SOURCE
search/CheckSlewLimits.cc
search/CheckTiming.cc
search/ClkInfo.cc
+ search/ClkNetwork.cc
search/ClkSkew.cc
search/Corner.cc
search/Crpr.cc
@@ -181,7 +182,6 @@ set(STA_SOURCE
search/ReportPath.cc
search/Search.cc
search/SearchPred.cc
- search/FindClkPins.cc
search/Sim.cc
search/Sta.cc
search/StaState.cc
diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc
index 99d97673..f4b0a20f 100644
--- a/dcalc/GraphDelayCalc1.cc
+++ b/dcalc/GraphDelayCalc1.cc
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include "GraphDelayCalc1.hh"
+
#include "Debug.hh"
#include "Stats.hh"
#include "MinMax.hh"
@@ -34,7 +36,7 @@
#include "ArcDelayCalc.hh"
#include "DcalcAnalysisPt.hh"
#include "NetCaps.hh"
-#include "GraphDelayCalc1.hh"
+#include "ClkNetwork.hh"
namespace sta {
@@ -1387,7 +1389,7 @@ GraphDelayCalc1::edgeFromSlew(const Vertex *from_vertex,
{
const TimingRole *role = edge->role();
if (role->genericRole() == TimingRole::regClkToQ()
- && isIdealClk(from_vertex))
+ && clk_network_->isIdealClock(from_vertex->pin()))
return idealClkSlew(from_vertex, from_rf, dcalc_ap->slewMinMax());
else
return graph_->slew(from_vertex, from_rf, dcalc_ap->index());
@@ -1399,7 +1401,7 @@ GraphDelayCalc1::idealClkSlew(const Vertex *vertex,
const MinMax *min_max)
{
float slew = min_max->initValue();
- const ClockSet *clks = idealClks(vertex);
+ const ClockSet *clks = clk_network_->idealClocks(vertex->pin());
ClockSet::ConstIterator clk_iter(clks);
while (clk_iter.hasNext()) {
Clock *clk = clk_iter.next();
@@ -1585,7 +1587,7 @@ GraphDelayCalc1::checkEdgeClkSlew(const Vertex *from_vertex,
const RiseFall *from_rf,
const DcalcAnalysisPt *dcalc_ap)
{
- if (isIdealClk(from_vertex))
+ if (clk_network_->isIdealClock(from_vertex->pin()))
return idealClkSlew(from_vertex, from_rf, dcalc_ap->checkClkSlewMinMax());
else
return graph_->slew(from_vertex, from_rf, dcalc_ap->checkClkSlewIndex());
@@ -1674,15 +1676,49 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex,
ClockSet *
GraphDelayCalc1::idealClks(const Vertex *vertex)
{
- return ideal_clks_map_.findKey(vertex);
+ ClockSet *ideal_clks = ideal_clks_map_.findKey(vertex);
+ const ClockSet *ideal_clks2 = clk_network_->idealClocks(vertex->pin());
+ if (ideal_clks) {
+ for (Clock *clk : *ideal_clks) {
+ if (ideal_clks2) {
+ if (!ideal_clks2->findKey(clk))
+ printf("pin %s clk_net missing1 %s\n",
+ vertex->name(network_),
+ clk->name());
+ }
+ else
+ printf("pin %s clk_net missing2 %s\n",
+ vertex->name(network_),
+ clk->name());
+ }
+ if (ideal_clks2) {
+ for (Clock *clk : *ideal_clks2) {
+ if (ideal_clks) {
+ if (!ideal_clks->findKey(clk)) {
+ printf("pin %s dcalc missing3 %s\n",
+ vertex->name(network_),
+ clk->name());
+ }
+ }
+ else
+ printf("pin %s dcalc missing4 %s\n",
+ vertex->name(network_),
+ clk->name());
+ }
+ }
+ }
+ return ideal_clks;
}
bool
GraphDelayCalc1::isIdealClk(const Vertex *vertex)
{
const ClockSet *clks = idealClks(vertex);
- return clks != 0
+ bool ideal = clks != 0
&& clks->size() > 0;
+ if (ideal != clk_network_->isIdealClock(vertex->pin()))
+ printf("ideal missmatch\n");
+ return ideal;
}
float
@@ -1765,7 +1801,7 @@ GraphDelayCalc1::reportDelayCalc(Edge *edge,
const Slew &from_slew = checkEdgeClkSlew(from_vertex, from_rf, dcalc_ap);
int slew_index = dcalc_ap->checkDataSlewIndex();
const Slew &to_slew = graph_->slew(to_vertex, to_rf, slew_index);
- bool from_ideal_clk = isIdealClk(from_vertex);
+ bool from_ideal_clk = clk_network_->isIdealClock(from_vertex->pin());
const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : nullptr;
arc_delay_calc_->reportCheckDelay(cell, arc, from_slew, from_slew_annotation,
to_slew, related_out_cap, pvt, dcalc_ap,
diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh
index 55b4f9d6..3c10aed6 100644
--- a/dcalc/GraphDelayCalc1.hh
+++ b/dcalc/GraphDelayCalc1.hh
@@ -18,6 +18,7 @@
#include
+#include "Delay.hh"
#include "GraphDelayCalc.hh"
namespace sta {
diff --git a/include/sta/ClkNetwork.hh b/include/sta/ClkNetwork.hh
new file mode 100644
index 00000000..9175abd3
--- /dev/null
+++ b/include/sta/ClkNetwork.hh
@@ -0,0 +1,67 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2020, 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 .
+
+#pragma once
+
+#include "Map.hh"
+#include "Set.hh"
+#include "StaState.hh"
+#include "NetworkClass.hh"
+#include "GraphClass.hh"
+#include "SdcClass.hh"
+
+namespace sta {
+
+typedef Map PinClksMap;
+typedef Map ClkPinsMap;
+
+class Sta;
+
+// Find clock network pins.
+// This is not as reliable as Search::isClock but is much cheaper.
+class ClkNetwork : public StaState
+{
+public:
+ ClkNetwork(StaState *sta);
+ void ensureClkNetwork();
+ void clear();
+ bool isClock(const Pin *pin) const;
+ bool isIdealClock(const Pin *pin) const;
+ const ClockSet *clocks(const Pin *pin);
+ const ClockSet *idealClocks(const Pin *pin);
+ void clkPinsInvalid();
+
+protected:
+ void deletePinBefore(const Pin *pin);
+ void connectPinAfter(const Pin *pin);
+ void disconnectPinBefore(const Pin *pin);
+ friend class Sta;
+
+private:
+ void findClkPins();
+ void findClkPins(bool ideal_only,
+ PinClksMap &clk_pin_map);
+
+ bool clk_pins_valid_;
+ // pin -> clks
+ PinClksMap pin_clks_map_;
+ // pin -> ideal clks
+ PinClksMap pin_ideal_clks_map_;
+ // clock -> pins
+ ClkPinsMap clk_pins_map_;
+};
+
+} // namespace
diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh
index af0b67e1..d971af89 100644
--- a/include/sta/Sta.hh
+++ b/include/sta/Sta.hh
@@ -1145,12 +1145,14 @@ public:
////////////////////////////////////////////////////////////////
- void ensureClkPins();
- bool isIdealClock(Pin *pin) const;
+ void ensureClkNetwork();
+ // Assumes ensureClkNetwork() has been called.
bool isClock(Pin *pin) const;
+ // Assumes ensureClkNetwork() has been called.
+ bool isIdealClock(Pin *pin) const;
void clkPinsInvalid();
-////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////
void setTclInterp(Tcl_Interp *interp);
Tcl_Interp *tclInterp();
@@ -1235,7 +1237,8 @@ protected:
virtual void makeGraphDelayCalc();
virtual void makeSim();
virtual void makeSearch();
- virtual void makeLatches();
+ virtual void makeLatches();
+ virtual void makeClkNetwork();
virtual void makeCheckTiming();
virtual void makeCheckSlewLimits();
virtual void makeCheckFanoutLimits();
@@ -1330,11 +1333,6 @@ protected:
void replaceCell(Instance *inst,
Cell *to_cell,
LibertyCell *to_lib_cell);
- void clkPinsConnectPinAfter(Vertex *vertex);
- void clkPinsDisconnectPinBefore(Vertex *vertex);
- void findClkPins();
- void findClkPins(bool ideal_only,
- PinSet &clk_pins);
void sdcChangedGraph();
void ensureGraphSdcAnnotated();
@@ -1356,10 +1354,6 @@ protected:
bool update_genclks_;
EquivCells *equiv_cells_;
bool graph_sdc_annotated_;
- // findClkPins
- PinSet clk_pins_;
- PinSet ideal_clk_pins_;
- bool clk_pins_valid_;
// Singleton sta used by tcl command interpreter.
static Sta *sta_;
diff --git a/include/sta/StaState.hh b/include/sta/StaState.hh
index 03d1fa2c..21c1c5f5 100644
--- a/include/sta/StaState.hh
+++ b/include/sta/StaState.hh
@@ -36,6 +36,7 @@ class Parasitics;
class ArcDelayCalc;
class GraphDelayCalc;
class Latches;
+class ClkNetwork;
class DispatchQueue;
// Most STA components use functionality in other components.
@@ -114,6 +115,7 @@ protected:
Sim *sim_;
Search *search_;
Latches *latches_;
+ ClkNetwork *clk_network_;
int thread_count_;
DispatchQueue *dispatch_queue_;
bool pocv_enabled_;
diff --git a/search/ClkNetwork.cc b/search/ClkNetwork.cc
new file mode 100644
index 00000000..c124e254
--- /dev/null
+++ b/search/ClkNetwork.cc
@@ -0,0 +1,183 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2020, 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 .
+
+#include "ClkNetwork.hh"
+
+#include "Debug.hh"
+#include "Network.hh"
+#include "Graph.hh"
+#include "Bfs.hh"
+#include "Sdc.hh"
+#include "SearchPred.hh"
+#include "Search.hh"
+
+namespace sta {
+
+ClkNetwork::ClkNetwork(StaState *sta) :
+ StaState(sta),
+ clk_pins_valid_(false)
+{
+}
+
+void
+ClkNetwork::ensureClkNetwork()
+{
+ if (!clk_pins_valid_)
+ findClkPins();
+}
+
+void
+ClkNetwork::clear()
+{
+ clk_pins_valid_ = false;
+ pin_clks_map_.clear();
+ clk_pins_map_.clear();
+ pin_ideal_clks_map_.clear();
+}
+
+void
+ClkNetwork::clkPinsInvalid()
+{
+ debugPrint0(debug_, "clk_network", 1, "clk network invalid\n");
+ clk_pins_valid_ = false;
+}
+
+void
+ClkNetwork::deletePinBefore(const Pin *pin)
+{
+ if (isClock(pin))
+ clkPinsInvalid();
+}
+
+void
+ClkNetwork::disconnectPinBefore(const Pin *pin)
+{
+ if (isClock(pin))
+ clkPinsInvalid();
+}
+
+void
+ClkNetwork::connectPinAfter(const Pin *pin)
+{
+ if (isClock(pin))
+ clkPinsInvalid();
+}
+
+class ClkSearchPred : public ClkTreeSearchPred
+{
+public:
+ ClkSearchPred(const StaState *sta);
+ virtual bool searchTo(const Vertex *to);
+};
+
+ClkSearchPred::ClkSearchPred(const StaState *sta) :
+ ClkTreeSearchPred(sta)
+{
+}
+
+bool
+ClkSearchPred::searchTo(const Vertex *to)
+{
+ const Sdc *sdc = sta_->sdc();
+ return !sdc->isLeafPinClock(to->pin());
+}
+
+void
+ClkNetwork::findClkPins()
+{
+ debugPrint0(debug_, "clk_network", 1, "find clk network\n");
+ clear();
+ findClkPins(false, pin_clks_map_);
+ findClkPins(true, pin_ideal_clks_map_);
+ clk_pins_valid_ = true;
+}
+
+void
+ClkNetwork::findClkPins(bool ideal_only,
+ PinClksMap &pin_clks_map)
+{
+ ClkSearchPred srch_pred(this);
+ BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
+ for (Clock *clk : sdc_->clks()) {
+ if (!ideal_only
+ || !clk->isPropagated()) {
+ PinSet &clk_pins = clk_pins_map_[clk];
+ for (Pin *pin : clk->leafPins()) {
+ if (!ideal_only
+ || !sdc_->isPropagatedClock(pin)) {
+ Vertex *vertex, *bidirect_drvr_vertex;
+ graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
+ bfs.enqueue(vertex);
+ if (bidirect_drvr_vertex)
+ bfs.enqueue(bidirect_drvr_vertex);
+ }
+ }
+ while (bfs.hasNext()) {
+ Vertex *vertex = bfs.next();
+ Pin *pin = vertex->pin();
+ if (!ideal_only
+ || !sdc_->isPropagatedClock(pin)) {
+ clk_pins.insert(pin);
+ ClockSet &pin_clks = pin_clks_map[pin];
+ pin_clks.insert(clk);
+ bfs.enqueueAdjacentVertices(vertex);
+ }
+ }
+ }
+ }
+}
+
+bool
+ClkNetwork::isClock(const Pin *pin) const
+{
+ ClockSet clks;
+ bool exists;
+ pin_clks_map_.findKey(pin, clks, exists);
+ if (exists && clks.empty())
+ printf("luse empty clks\n");
+ return exists;
+}
+
+bool
+ClkNetwork::isIdealClock(const Pin *pin) const
+{
+ ClockSet clks;
+ bool exists;
+ pin_ideal_clks_map_.findKey(pin, clks, exists);
+ if (exists && clks.empty())
+ printf("luse empty clks\n");
+ return exists;
+}
+
+const ClockSet *
+ClkNetwork::clocks(const Pin *pin)
+{
+ if (pin_clks_map_.hasKey(pin))
+ return &pin_clks_map_[pin];
+ else
+ return nullptr;
+}
+
+const ClockSet *
+ClkNetwork::idealClocks(const Pin *pin)
+{
+ if (pin_ideal_clks_map_.hasKey(pin))
+ return &pin_ideal_clks_map_[pin];
+ else
+ return nullptr;
+}
+
+} // namespace
diff --git a/search/FindClkPins.cc b/search/FindClkPins.cc
deleted file mode 100644
index e497e067..00000000
--- a/search/FindClkPins.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// OpenSTA, Static Timing Analyzer
-// Copyright (c) 2020, 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 .
-
-#include "Sta.hh"
-
-#include "Network.hh"
-#include "Graph.hh"
-#include "Bfs.hh"
-#include "Sdc.hh"
-#include "SearchPred.hh"
-#include "Search.hh"
-
-namespace sta {
-
-void
-Sta::ensureClkPins()
-{
- if (!clk_pins_valid_) {
- ensureLevelized();
- findClkPins();
- clk_pins_valid_ = true;
- }
-}
-
-void
-Sta::clkPinsInvalid()
-{
- clk_pins_valid_ = false;
- clk_pins_.clear();
- ideal_clk_pins_.clear();
-}
-
-void
-Sta::clkPinsDisconnectPinBefore(Vertex *vertex)
-{
- // If the pin is in the clock network but not a clock endpoint
- // everything downstream is invalid.
- if (clk_pins_.hasKey(vertex->pin())
- && !isClkEnd(vertex, graph_))
- clk_pins_valid_ = false;
-}
-
-void
-Sta::clkPinsConnectPinAfter(Vertex *vertex)
-{
- // If the pin fanin is part of the clock network
- VertexInEdgeIterator edge_iter(vertex, graph_);
- while (edge_iter.hasNext()) {
- Edge *edge = edge_iter.next();
- Vertex *from = edge->from(graph_);
- if (clk_pins_.hasKey(from->pin())) {
- clk_pins_valid_ = false;
- break;
- }
- }
-}
-
-// Find clock network pins.
-// This is not as reliable as Search::isClock but is much cheaper.
-void
-Sta::findClkPins()
-{
- // Use two passes to find ideal and propagated clock network pins.
- findClkPins(false, clk_pins_);
- findClkPins(true, ideal_clk_pins_);
-}
-
-void
-Sta::findClkPins(bool ideal_only,
- PinSet &clk_pins)
-{
- ClkArrivalSearchPred srch_pred(this);
- BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
- for (Clock *clk : sdc_->clks()) {
- if (!ideal_only
- || !clk->isPropagated()) {
- for (Pin *pin : clk->leafPins()) {
- if (!ideal_only
- || !sdc_->isPropagatedClock(pin)) {
- Vertex *vertex, *bidirect_drvr_vertex;
- graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
- bfs.enqueue(vertex);
- if (bidirect_drvr_vertex)
- bfs.enqueue(bidirect_drvr_vertex);
- }
- }
- }
- }
- while (bfs.hasNext()) {
- Vertex *vertex = bfs.next();
- Pin *pin = vertex->pin();
- if (!sdc_->isPropagatedClock(pin)) {
- clk_pins.insert(pin);
- bfs.enqueueAdjacentVertices(vertex);
- }
- }
-}
-
-bool
-Sta::isClock(Pin *pin) const
-{
- return clk_pins_.hasKey(pin);
-}
-
-bool
-Sta::isIdealClock(Pin *pin) const
-{
- return ideal_clk_pins_.hasKey(pin);
-}
-
-} // namespace
diff --git a/search/Sta.cc b/search/Sta.cc
index 8063d27e..3ce9849e 100644
--- a/search/Sta.cc
+++ b/search/Sta.cc
@@ -64,6 +64,7 @@
#include "ReportPath.hh"
#include "VisitPathGroupVertices.hh"
#include "Genclks.hh"
+#include "ClkNetwork.hh"
#include "Power.hh"
namespace sta {
@@ -268,8 +269,7 @@ Sta::Sta() :
link_make_black_boxes_(true),
update_genclks_(false),
equiv_cells_(nullptr),
- graph_sdc_annotated_(false),
- clk_pins_valid_(false)
+ graph_sdc_annotated_(false)
{
}
@@ -289,6 +289,7 @@ Sta::makeComponents()
makeSim();
makeSearch();
makeLatches();
+ makeClkNetwork();
makeSdcNetwork();
makeReportPath();
makePower();
@@ -348,6 +349,7 @@ Sta::updateComponentsState()
report_path_->copyState(this);
if (check_timing_)
check_timing_->copyState(this);
+ clk_network_->copyState(this);
if (power_)
power_->copyState(this);
}
@@ -478,6 +480,12 @@ Sta::makeReportPath()
report_path_ = new ReportPath(this);
}
+void
+Sta::makeClkNetwork()
+{
+ clk_network_ = new ClkNetwork(this);
+}
+
void
Sta::makePower()
{
@@ -525,6 +533,7 @@ Sta::~Sta()
delete debug_;
delete units_;
delete report_;
+ delete clk_network_;
delete power_;
delete equiv_cells_;
delete dispatch_queue_;
@@ -2090,6 +2099,7 @@ Sta::removeConstraints()
if (graph_)
sdc_->removeGraphAnnotations();
sdc_->clear();
+ clk_network_->clear();
}
void
@@ -3107,7 +3117,7 @@ Sta::findDelays(Level level)
void
Sta::delayCalcPreamble()
{
- ensureLevelized();
+ ensureClkNetwork();
}
void
@@ -3986,8 +3996,10 @@ Sta::connectPinAfter(Pin *pin)
EdgesThruHierPinIterator edge_iter(pin, network_, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
- if (edge->role()->isWire())
+ if (edge->role()->isWire()) {
connectDrvrPinAfter(edge->from(graph_));
+ connectLoadPinAfter(edge->to(graph_));
+ }
}
}
else {
@@ -4034,12 +4046,13 @@ Sta::connectDrvrPinAfter(Vertex *vertex)
search_->endpointInvalid(to_vertex);
sdc_->clkHpinDisablesChanged(to_vertex->pin());
}
- sdc_->clkHpinDisablesChanged(vertex->pin());
+ Pin *pin = vertex->pin();
+ sdc_->clkHpinDisablesChanged(pin);
graph_delay_calc_->delayInvalid(vertex);
search_->requiredInvalid(vertex);
search_->endpointInvalid(vertex);
- clkPinsConnectPinAfter(vertex);
levelize_->invalidFrom(vertex);
+ clk_network_->connectPinAfter(pin);
}
void
@@ -4054,12 +4067,13 @@ Sta::connectLoadPinAfter(Vertex *vertex)
search_->requiredInvalid(from_vertex);
sdc_->clkHpinDisablesChanged(from_vertex->pin());
}
- sdc_->clkHpinDisablesChanged(vertex->pin());
+ Pin *pin = vertex->pin();
+ sdc_->clkHpinDisablesChanged(pin);
graph_delay_calc_->delayInvalid(vertex);
levelize_->invalidFrom(vertex);
search_->arrivalInvalid(vertex);
search_->endpointInvalid(vertex);
- clkPinsConnectPinAfter(vertex);
+ clk_network_->connectPinAfter(pin);
}
void
@@ -4079,7 +4093,7 @@ Sta::disconnectPinBefore(Pin *pin)
if (edge->role()->isWire())
deleteEdge(edge);
}
- clkPinsDisconnectPinBefore(vertex);
+ clk_network_->disconnectPinBefore(pin);
}
}
if (network_->isLoad(pin)) {
@@ -4092,7 +4106,7 @@ Sta::disconnectPinBefore(Pin *pin)
if (edge->role()->isWire())
deleteEdge(edge);
}
- clkPinsDisconnectPinBefore(vertex);
+ clk_network_->disconnectPinBefore(pin);
}
}
if (network_->isHierarchical(pin)) {
@@ -4100,8 +4114,10 @@ Sta::disconnectPinBefore(Pin *pin)
EdgesThruHierPinIterator edge_iter(pin, network_, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
- if (edge->role()->isWire())
+ if (edge->role()->isWire()) {
deleteEdge(edge);
+ clk_network_->disconnectPinBefore(edge->from(graph_)->pin());
+ }
}
}
}
@@ -4229,6 +4245,7 @@ Sta::deletePinBefore(Pin *pin)
}
}
sim_->deletePinBefore(pin);
+ clk_network_->deletePinBefore(pin);
}
void
@@ -4926,7 +4943,7 @@ Sta::checkFanoutLimitPreamble()
{
if (check_fanout_limits_ == nullptr)
makeCheckFanoutLimits();
- ensureClkPins();
+ ensureClkNetwork();
}
Pin *
@@ -4991,7 +5008,7 @@ Sta::checkCapacitanceLimitPreamble()
{
if (check_capacitance_limits_ == nullptr)
makeCheckCapacitanceLimits();
- ensureClkPins();
+ ensureClkNetwork();
}
Pin *
@@ -5244,4 +5261,31 @@ Sta::power(const Instance *inst,
power_->power(inst, corner, result);
}
+////////////////////////////////////////////////////////////////
+
+void
+Sta::ensureClkNetwork()
+{
+ ensureLevelized();
+ clk_network_->ensureClkNetwork();
+}
+
+bool
+Sta::isClock(Pin *pin) const
+{
+ return clk_network_->isClock(pin);
+}
+
+bool
+Sta::isIdealClock(Pin *pin) const
+{
+ return clk_network_->isIdealClock(pin);
+}
+
+void
+Sta::clkPinsInvalid()
+{
+ clk_network_->clkPinsInvalid();
+}
+
} // namespace
diff --git a/search/StaState.cc b/search/StaState.cc
index fcc87f8d..699d5a0f 100644
--- a/search/StaState.cc
+++ b/search/StaState.cc
@@ -39,6 +39,7 @@ StaState::StaState() :
sim_(nullptr),
search_(nullptr),
latches_(nullptr),
+ clk_network_(nullptr),
thread_count_(1),
dispatch_queue_(nullptr),
pocv_enabled_(false),
@@ -63,6 +64,7 @@ StaState::StaState(const StaState *sta) :
sim_(sta->sim_),
search_(sta->search_),
latches_(sta->latches_),
+ clk_network_(sta->clk_network_),
thread_count_(sta->thread_count_),
dispatch_queue_(sta->dispatch_queue_),
pocv_enabled_(sta->pocv_enabled_),
@@ -89,6 +91,7 @@ StaState::copyState(const StaState *sta)
sim_ = sta->sim_;
search_ = sta->search_;
latches_ = sta->latches_;
+ clk_network_ = sta->clk_network_;
thread_count_ = sta->thread_count_;
dispatch_queue_ = sta->dispatch_queue_;
pocv_enabled_ = sta->pocv_enabled_;