diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index 5376e2f6..a71c09a7 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -116,12 +116,6 @@ GraphDelayCalc::ceff(Edge *, return 0.0; } -bool -GraphDelayCalc::isIdealClk(const Vertex *vertex) -{ - return false; -} - void GraphDelayCalc::minPulseWidth(const Pin *pin, const RiseFall *hi_low, diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index f4b0a20f..872b1a10 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -230,7 +230,6 @@ GraphDelayCalc1::~GraphDelayCalc1() delete clk_pred_; delete iter_; deleteMultiDrvrNets(); - clearIdealClkMap(); delete observer_; } @@ -293,7 +292,6 @@ GraphDelayCalc1::delaysInvalid() delays_seeded_ = false; incremental_ = false; iter_->clear(); - clearIdealClkMap(); // No need to keep track of incremental updates any more. invalid_delays_.clear(); invalid_checks_.clear(); @@ -360,7 +358,6 @@ public: virtual ~FindVertexDelays(); virtual void visit(Vertex *vertex); virtual VertexVisitor *copy(); - virtual void levelFinished(); protected: GraphDelayCalc1 *graph_delay_calc1_; @@ -398,24 +395,6 @@ FindVertexDelays::visit(Vertex *vertex) graph_delay_calc1_->findVertexDelay(vertex, arc_delay_calc_, true); } -void -FindVertexDelays::levelFinished() -{ - graph_delay_calc1_->mergeIdealClks(); -} - -void -GraphDelayCalc1::mergeIdealClks() -{ - for (auto vertex_clks : ideal_clks_map_next_) { - const Vertex *vertex = vertex_clks.first; - ClockSet *prev_clks = ideal_clks_map_.findKey(vertex); - delete prev_clks; - ideal_clks_map_[vertex] = vertex_clks.second; - } - ideal_clks_map_next_.clear(); -} - // The logical structure of incremental delay calculation closely // resembles the incremental search arrival time algorithm // (Search::findArrivals). @@ -437,7 +416,6 @@ GraphDelayCalc1::findDelays(Level level) if (incremental_) seedInvalidDelays(); - mergeIdealClks(); FindVertexDelays visitor(this, arc_delay_calc_, false); dcalc_count += iter_->visitParallel(level, &visitor); @@ -578,7 +556,6 @@ GraphDelayCalc1::seedRootSlews() while (root_iter.hasNext()) { Vertex *vertex = root_iter.next(); seedRootSlew(vertex, arc_delay_calc_); - findIdealClks(vertex); } } @@ -857,7 +834,6 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex, bool propagate) { const Pin *pin = vertex->pin(); - bool ideal_clks_changed = findIdealClks(vertex); // Don't clobber root slews. if (!vertex->isRoot()) { debugPrint2(debug_, "delay_calc", 2, "find delays %s (%s)\n", @@ -871,7 +847,7 @@ GraphDelayCalc1::findVertexDelay(Vertex *vertex, enqueueTimingChecksEdges(vertex); // Enqueue adjacent vertices even if the delays did not // change when non-incremental to stride past annotations. - if (delay_changed || ideal_clks_changed || !incremental_) + if (delay_changed || !incremental_) iter_->enqueueAdjacentVertices(vertex); } } @@ -1595,132 +1571,6 @@ GraphDelayCalc1::checkEdgeClkSlew(const Vertex *from_vertex, //////////////////////////////////////////////////////////////// -bool -GraphDelayCalc1::findIdealClks(Vertex *vertex) -{ - const Pin *pin = vertex->pin(); - ClockSet *ideal_clks = nullptr; - if (sdc_->isLeafPinClock(pin)) { - // Seed ideal clocks pins. - if (!sdc_->isPropagatedClock(pin)) { - ClockSet *clks = sdc_->findLeafPinClocks(pin); - ClockSet::ConstIterator clk_iter(clks); - while (clk_iter.hasNext()) { - Clock *clk = clk_iter.next(); - if (!clk->isPropagated()) { - if (ideal_clks == nullptr) { - ideal_clks = new ClockSet; - debugPrint1(debug_, "ideal_clks", 1, " %s\n", - vertex->name(sdc_network_)); - } - ideal_clks->insert(clk); - debugPrint1(debug_, "ideal_clks", 1, " %s\n", clk->name()); - } - } - } - } - else { - if (!sdc_->isPropagatedClock(pin)) { - VertexInEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (clk_pred_->searchThru(edge)) { - Vertex *from_vertex = edge->from(graph_); - ClockSet *from_clks = idealClks(from_vertex); - if (from_clks) { - ClockSet::ConstIterator from_clk_iter(from_clks); - while (from_clk_iter.hasNext()) { - Clock *from_clk = from_clk_iter.next(); - if (ideal_clks == nullptr) { - ideal_clks = new ClockSet; - debugPrint1(debug_, "ideal_clks", 1, " %s\n", - vertex->name(sdc_network_)); - } - ideal_clks->insert(from_clk); - debugPrint1(debug_, "ideal_clks", 1, " %s\n", from_clk->name()); - } - } - } - } - } - } - return setIdealClks(vertex, ideal_clks); -} - -void -GraphDelayCalc1::clearIdealClkMap() -{ - ideal_clks_map_.deleteContentsClear(); - ideal_clks_map_next_.deleteContentsClear(); -} - -bool -GraphDelayCalc1::setIdealClks(const Vertex *vertex, - ClockSet *clks) -{ - bool changed = false; - ClockSet *clks1 = ideal_clks_map_.findKey(vertex); - if (!ClockSet::equal(clks, clks1)) { - // Only lock for updates to vertex ideal clks. - // Finding ideal clks by level means only changes at the current - // delay calc level are changed. - UniqueLock lock(ideal_clks_map_next_lock_); - ideal_clks_map_next_[vertex] = clks; - changed = true; - } - else - delete clks; - return changed; -} - -ClockSet * -GraphDelayCalc1::idealClks(const Vertex *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); - bool ideal = clks != 0 - && clks->size() > 0; - if (ideal != clk_network_->isIdealClock(vertex->pin())) - printf("ideal missmatch\n"); - return ideal; -} - float GraphDelayCalc1::ceff(Edge *edge, TimingArc *arc, diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh index 3c10aed6..c6118979 100644 --- a/dcalc/GraphDelayCalc1.hh +++ b/dcalc/GraphDelayCalc1.hh @@ -142,7 +142,6 @@ protected: ArcDelayCalc *arc_delay_calc, bool propagate); void enqueueTimingChecksEdges(Vertex *vertex); - bool findIdealClks(Vertex *vertex); bool findArcDelay(LibertyCell *drvr_cell, const Pin *drvr_pin, Vertex *drvr_vertex, @@ -195,11 +194,6 @@ protected: const RiseFall *from_rf, const DcalcAnalysisPt *dcalc_ap); bool bidirectDrvrSlewFromLoad(const Vertex *vertex) const; - void clearIdealClkMap(); - bool setIdealClks(const Vertex *vertex, - ClockSet *clks); - ClockSet *idealClks(const Vertex *vertex); - virtual bool isIdealClk(const Vertex *vertex); Slew idealClkSlew(const Vertex *vertex, const RiseFall *rf, const MinMax *min_max); @@ -214,7 +208,6 @@ protected: Parasitic *drvr_parasitic, const RiseFall *rf, const DcalcAnalysisPt *dcalc_ap) const; - void mergeIdealClks(); // Observer for edge delay changes. DelayCalcObserver *observer_; @@ -235,9 +228,6 @@ protected: // Percentage (0.0:1.0) change in delay that causes downstream // delays to be recomputed during incremental delay calculation. float incremental_delay_tolerance_; - VertexIdealClksMap ideal_clks_map_; - VertexIdealClksMap ideal_clks_map_next_; - std::mutex ideal_clks_map_next_lock_; friend class FindVertexDelays; friend class MultiDrvrNet; diff --git a/include/sta/GraphDelayCalc.hh b/include/sta/GraphDelayCalc.hh index c7ad7e5e..d36ad3a5 100644 --- a/include/sta/GraphDelayCalc.hh +++ b/include/sta/GraphDelayCalc.hh @@ -100,7 +100,6 @@ public: virtual float ceff(Edge *edge, TimingArc *arc, const DcalcAnalysisPt *dcalc_ap); - virtual bool isIdealClk(const Vertex *vertex); // Precedence: // SDF annotation // Liberty library diff --git a/include/sta/StaState.hh b/include/sta/StaState.hh index 21c1c5f5..4b18a202 100644 --- a/include/sta/StaState.hh +++ b/include/sta/StaState.hh @@ -93,6 +93,8 @@ public: Search *search() const { return search_; } Latches *latches() { return latches_; } Latches *latches() const { return latches_; } + ClkNetwork *clkNetwork() { return clk_network_; } + ClkNetwork *clkNetwork() const { return clk_network_; } unsigned threadCount() const { return thread_count_; } bool pocvEnabled() const { return pocv_enabled_; } float sigmaFactor() const { return sigma_factor_; } diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index da181844..36ebe488 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -28,6 +28,7 @@ #include "PathVertex.hh" #include "PortDirection.hh" #include "Search.hh" +#include "ClkNetwork.hh" namespace sta { @@ -147,13 +148,14 @@ CheckSlewLimits::checkSlews1(Vertex *vertex, float &limit, float &slack) const { + const Pin *pin = vertex->pin(); if (!vertex->isDisabledConstraint() && !vertex->isConstant() - && !sta_->graphDelayCalc()->isIdealClk(vertex)) { + && !sta_->clkNetwork()->isIdealClock(pin)) { for (auto rf1 : RiseFall::range()) { float limit1; bool limit1_exists; - findLimit(vertex->pin(), vertex, rf1, min_max, check_clks, + findLimit(pin, vertex, rf1, min_max, check_clks, limit1, limit1_exists); if (limit1_exists) { checkSlew(vertex, corner1, rf1, min_max, limit1, @@ -186,7 +188,7 @@ CheckSlewLimits::findLimit(const Pin *pin, bool exists1; if (check_clks) { // Look for clock slew limits. - bool is_clk = sta_->search()->isClock(vertex); + bool is_clk = sta_->clkNetwork()->isIdealClock(pin); ClockSet clks; clockDomains(vertex, clks); ClockSet::Iterator clk_iter(clks); diff --git a/search/ClkNetwork.cc b/search/ClkNetwork.cc index c124e254..4c9a08a2 100644 --- a/search/ClkNetwork.cc +++ b/search/ClkNetwork.cc @@ -143,23 +143,13 @@ ClkNetwork::findClkPins(bool ideal_only, 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; + return pin_clks_map_.hasKey(pin); } 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; + return pin_ideal_clks_map_.hasKey(pin); } const ClockSet * diff --git a/search/Sta.cc b/search/Sta.cc index 3ce9849e..99ed8039 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4865,6 +4865,7 @@ Sta::checkSlewLimitPreamble() findDelays(); if (check_slew_limits_ == nullptr) makeCheckSlewLimits(); + ensureClkNetwork(); } Pin * diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 0e4c5f31..5c715729 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -3768,7 +3768,21 @@ update_generated_clks() } bool -pin_is_clock(const Pin *pin) +is_clock(Pin *pin) +{ + Sta *sta = Sta::sta(); + return sta->isClock(pin); +} + +bool +is_ideal_clock(Pin *pin) +{ + Sta *sta = Sta::sta(); + return sta->isIdealClock(pin); +} + +bool +is_clock_search(const Pin *pin) { Sta *sta = Sta::sta(); Graph *graph = sta->graph(); @@ -3779,7 +3793,7 @@ pin_is_clock(const Pin *pin) } bool -pin_is_genclk_src(const Pin *pin) +is_genclk_src(const Pin *pin) { Sta *sta = Sta::sta(); Graph *graph = sta->graph();