From 6ac93c8c7d9180075bb957c700378974f9fcb235 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 25 Oct 2019 08:51:59 -0700 Subject: [PATCH] vertex_pin -> leaf_pin --- README.md | 4 +- dcalc/GraphDelayCalc1.cc | 6 +- network/ConcreteNetwork.cc | 2 +- network/MakeConcreteNetwork.hh | 4 +- sdc/Clock.cc | 52 +++--- sdc/Clock.hh | 35 ++-- sdc/PortDelay.cc | 18 +- sdc/PortDelay.hh | 40 ++--- sdc/Sdc.cc | 310 +++++++++------------------------ sdc/Sdc.hh | 112 +++--------- sdc/WriteSdc.cc | 251 ++++++++++++++++---------- sdc/WriteSdc.hh | 5 +- sdc/WriteSdcPvt.hh | 23 ++- search/FindRegister.cc | 4 +- search/Genclks.cc | 32 ++-- search/Power.cc | 2 +- search/Property.cc | 2 +- search/ReportPath.cc | 3 +- search/Search.cc | 54 +++--- search/Sta.cc | 10 +- search/Sta.hh | 3 + search/StaState.cc | 12 ++ search/StaState.hh | 2 + search/VisitPathEnds.cc | 2 +- tcl/Sdc.tcl | 9 +- tcl/StaTcl.i | 38 ++-- util/Set.hh | 11 ++ 27 files changed, 445 insertions(+), 601 deletions(-) diff --git a/README.md b/README.md index f7be2eb3..ac4f6c9b 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,9 @@ netlist data structures without duplicating them. * Query based incremental update of delays, arrival and required times * Simulator to propagate constants from constraints and netlist tie high/low -See doc/OpenSTA.pdf for complete documentiaton. +See doc/OpenSTA.pdf for command documentiaton. +See doc/StaApi.txt for timing engine API documentiaton. +See doc/ChangeLog.txt for changes to commands. ## Getting Started diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 3e606e63..8e9c66da 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -700,7 +700,7 @@ GraphDelayCalc1::seedLoadSlew(Vertex *vertex) const Pin *pin = vertex->pin(); debugPrint1(debug_, "delay_calc", 2, "seed load slew %s\n", vertex->name(sdc_network_)); - ClockSet *clks = sdc_->findVertexPinClocks(pin); + ClockSet *clks = sdc_->findLeafPinClocks(pin); initSlew(vertex); for (auto tr : TransRiseFall::range()) { for (auto dcalc_ap : corners_->dcalcAnalysisPts()) { @@ -1594,10 +1594,10 @@ GraphDelayCalc1::findIdealClks(Vertex *vertex) { const Pin *pin = vertex->pin(); ClockSet *ideal_clks = nullptr; - if (sdc_->isVertexPinClock(pin)) { + if (sdc_->isLeafPinClock(pin)) { // Seed ideal clocks pins. if (!sdc_->isPropagatedClock(pin)) { - ClockSet *clks = sdc_->findVertexPinClocks(pin); + ClockSet *clks = sdc_->findLeafPinClocks(pin); ClockSet::ConstIterator clk_iter(clks); while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index a681f967..75f3cec8 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -40,7 +40,7 @@ makeClonePins(Instance *proto, ConcreteBindingTbl *parent_bindings, NetworkReader *network); -Network * +NetworkReader * makeConcreteNetwork() { return new ConcreteNetwork; diff --git a/network/MakeConcreteNetwork.hh b/network/MakeConcreteNetwork.hh index eb970173..b4234f16 100644 --- a/network/MakeConcreteNetwork.hh +++ b/network/MakeConcreteNetwork.hh @@ -19,9 +19,9 @@ namespace sta { -class Network; +class NetworkReader; -Network * +NetworkReader * makeConcreteNetwork(); } // namespace diff --git a/sdc/Clock.cc b/sdc/Clock.cc index a8ff6ade..b3a7420a 100644 --- a/sdc/Clock.cc +++ b/sdc/Clock.cc @@ -34,9 +34,7 @@ isPowerOfTwo(int i); Clock::Clock(const char *name, int index) : name_(stringCopy(name)), - pins_(nullptr), add_to_pins_(false), - vertex_pins_(nullptr), pll_out_(nullptr), pll_fdbk_(nullptr), period_(0.0), @@ -83,31 +81,26 @@ Clock::initClk(PinSet *pins, bool Clock::isVirtual() const { - return pins_ == nullptr || pins_->empty(); + return pins_.empty(); } void Clock::setPins(PinSet *pins, const Network *network) { - delete pins_; - pins_ = pins; - makeVertexPins(network); + if (pins) + pins_ = *pins; + makeLeafPins(network); } void -Clock::makeVertexPins(const Network *network) +Clock::makeLeafPins(const Network *network) { - if (pins_) { - if (vertex_pins_) - vertex_pins_->clear(); - else - vertex_pins_ = new PinSet; - PinSet::Iterator pin_iter(pins_); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); - findVertexDriverPins(pin, network, vertex_pins_); - } + leaf_pins_.clear(); + PinSet::Iterator pin_iter(pins_); + while (pin_iter.hasNext()) { + Pin *pin = pin_iter.next(); + findLeafDriverPins(pin, network, &leaf_pins_); } } @@ -130,8 +123,6 @@ Clock::makeClkEdges() Clock::~Clock() { stringDelete(name_); - delete pins_; - delete vertex_pins_; if (clk_edges_) { delete clk_edges_[TransRiseFall::riseIndex()]; delete clk_edges_[TransRiseFall::fallIndex()]; @@ -146,18 +137,14 @@ Clock::~Clock() void Clock::addPin(Pin *pin) { - if (pins_ == nullptr) - pins_ = new PinSet; - pins_->insert(pin); - if (vertex_pins_ == nullptr) - vertex_pins_ = new PinSet; - vertex_pins_->insert(pin); + pins_.insert(pin); + leaf_pins_.insert(pin); } void Clock::deletePin(Pin *pin) { - pins_->erase(pin); + pins_.erase(pin); } void @@ -183,7 +170,7 @@ Clock::setClkEdgeTime(const TransRiseFall *tr) Pin * Clock::defaultPin() const { - PinSet::Iterator pin_iter(vertex_pins_); + PinSet::ConstIterator pin_iter(leaf_pins_); if (pin_iter.hasNext()) return pin_iter.next(); else @@ -510,9 +497,9 @@ Clock::srcPinVertices(VertexSet &src_vertices, { if (network->isHierarchical(src_pin_)) { // Use the clocks on a non-hierarchical pin on the same net. - PinSet vertex_pins; - findVertexDriverPins(src_pin_, network, &vertex_pins); - PinSet::Iterator pin_iter(vertex_pins); + PinSet leaf_pins; + findLeafDriverPins(src_pin_, network, &leaf_pins); + PinSet::Iterator pin_iter(leaf_pins); while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); Vertex *vertex, *bidirect_drvr_vertex; @@ -710,4 +697,9 @@ sortClockSet(ClockSet *set, sort(clks, ClockNameLess()); } +ClockPinIterator::ClockPinIterator(Clock *clk) : + PinSet::Iterator(clk->pins()) +{ +} + } // namespace diff --git a/sdc/Clock.hh b/sdc/Clock.hh index f66cc25e..ebbff6dd 100644 --- a/sdc/Clock.hh +++ b/sdc/Clock.hh @@ -36,8 +36,14 @@ public: float period() const { return period_; } // Virtual clocks have no pins. bool isVirtual() const; - PinSet *pins() const { return pins_; } - PinSet *vertexPins() const { return vertex_pins_; } + PinSet &pins() { return pins_; } + const PinSet &pins() const { return pins_; } + // The clock source pin's leaf pins. + // If the source pin is hierarchical, the leaf pins are: + // hierarchical input - load pins inside the hierarchical instance + // hierarchical output - load pins outside the hierarchical instance + PinSet &leafPins() { return leaf_pins_; } + const PinSet &leafPins() const { return leaf_pins_; } // Clock pin used by input/output delay for propagated generated // clock insertion delay. Pin *defaultPin() const; @@ -92,7 +98,7 @@ public: void addPin(Pin *pin); void deletePin(Pin *pin); - void makeVertexPins(const Network *network); + void makeLeafPins(const Network *network); bool isGenerated() const; bool isGeneratedWithPropagatedMaster() const; @@ -157,10 +163,10 @@ protected: void generateEdgesClk(const Clock *src_clk); const char *name_; - PinSet *pins_; + PinSet pins_; bool add_to_pins_; // Hierarchical pins in pins_ become driver pins through the pin. - PinSet *vertex_pins_; + PinSet leaf_pins_; Pin *pll_out_; Pin *pll_fdbk_; float period_; @@ -293,23 +299,8 @@ sortClockSet(ClockSet * set, class ClockPinIterator : public PinSet::Iterator { public: - ClockPinIterator(Clock *clk) : - PinSet::Iterator(clk->pins()) - { - } -}; - -// The clock source pin's graph vertex pins. -// If the source pin is hierarchical, the vertex pins are: -// hierarchical input - load pins inside the hierarchical instance -// hierarchical output - load pins outside the hierarchical instance -class ClockVertexPinIterator : public PinSet::Iterator -{ -public: - ClockVertexPinIterator(Clock *clk) : - PinSet::Iterator(clk->vertexPins()) - { - } + // Use range iterator on Clock::pins(). + ClockPinIterator(Clock *clk) __attribute__ ((deprecated)); }; } // namespace diff --git a/sdc/PortDelay.cc b/sdc/PortDelay.cc index 14cc3cfa..9d7e25e9 100644 --- a/sdc/PortDelay.cc +++ b/sdc/PortDelay.cc @@ -85,7 +85,7 @@ InputDelay::InputDelay(Pin *pin, next_(nullptr), index_(index) { - findVertexLoadPins(pin, network, &vertex_pins_); + findLeafLoadPins(pin, network, &leaf_pins_); } void @@ -102,7 +102,7 @@ OutputDelay::OutputDelay(Pin *pin, next_(nullptr) { if (network) - findVertexDriverPins(pin, network, &vertex_pins_); + findLeafDriverPins(pin, network, &leaf_pins_); } void @@ -113,6 +113,8 @@ OutputDelay::setNext(OutputDelay *next) //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// + PinInputDelayIterator::PinInputDelayIterator(const Pin *pin, const Sdc *sdc) { @@ -134,11 +136,11 @@ PinInputDelayIterator::next() return next; } -VertexPinInputDelayIterator::VertexPinInputDelayIterator(const Pin *vertex_pin, - const Sdc *sdc) : +LeafPinInputDelayIterator::LeafPinInputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc) : PinInputDelayIterator() { - next_ = sdc->input_delay_vertex_map_.findKey(vertex_pin); + next_ = sdc->input_delay_leaf_pin_map_.findKey(vertex_pin); } //////////////////////////////////////////////////////////////// @@ -164,11 +166,11 @@ PinOutputDelayIterator::next() return next; } -VertexPinOutputDelayIterator::VertexPinOutputDelayIterator(const Pin *vertex_pin, - const Sdc *sdc) : +LeafPinOutputDelayIterator::LeafPinOutputDelayIterator(const Pin *vertex_pin, + const Sdc *sdc) : PinOutputDelayIterator() { - next_ = sdc->output_delay_vertex_map_.findKey(vertex_pin); + next_ = sdc->output_delay_leaf_pin_map_.findKey(vertex_pin); } //////////////////////////////////////////////////////////////// diff --git a/sdc/PortDelay.hh b/sdc/PortDelay.hh index bbd0fd5c..d2e5912c 100644 --- a/sdc/PortDelay.hh +++ b/sdc/PortDelay.hh @@ -33,7 +33,7 @@ class PortDelay public: RiseFallMinMax *delays() { return &delays_; } Pin *pin() const { return pin_; } - PinSet &vertexPins() { return vertex_pins_; } + PinSet &leafPins() { return leaf_pins_; } Clock *clock() const; ClockEdge *clkEdge() const { return clk_edge_; } bool sourceLatencyIncluded() const; @@ -44,7 +44,9 @@ public: TransRiseFall *refTransition() const; protected: - PortDelay(Pin *pin, ClockEdge *clk_edge, Pin *ref_pin); + PortDelay(Pin *pin, + ClockEdge *clk_edge, + Pin *ref_pin); Pin *pin_; ClockEdge *clk_edge_; @@ -52,7 +54,7 @@ protected: bool network_latency_included_; Pin *ref_pin_; RiseFallMinMax delays_; - PinSet vertex_pins_; + PinSet leaf_pins_; private: DISALLOW_COPY_AND_ASSIGN(PortDelay); @@ -85,15 +87,6 @@ private: friend class InputDelayIterator; }; -class InputDelayVertexPinIterator : public PinSet::Iterator -{ -public: - InputDelayVertexPinIterator(InputDelay *input_delay) : - PinSet::Iterator(input_delay->vertexPins()) - { - } -}; - class OutputDelay : public PortDelay { public: @@ -117,15 +110,6 @@ private: friend class OutputDelayIterator; }; -class OutputDelayVertexPinIterator : public PinSet::Iterator -{ -public: - OutputDelayVertexPinIterator(OutputDelay *output_delay) : - PinSet::Iterator(output_delay->vertexPins()) - { - } -}; - class PinInputDelayIterator : public Iterator { public: @@ -142,14 +126,14 @@ protected: DISALLOW_COPY_AND_ASSIGN(PinInputDelayIterator); }; -class VertexPinInputDelayIterator : public PinInputDelayIterator +class LeafPinInputDelayIterator : public PinInputDelayIterator { public: - VertexPinInputDelayIterator(const Pin *vertex_pin, + LeafPinInputDelayIterator(const Pin *pin, const Sdc *sdc); private: - DISALLOW_COPY_AND_ASSIGN(VertexPinInputDelayIterator); + DISALLOW_COPY_AND_ASSIGN(LeafPinInputDelayIterator); }; class PinOutputDelayIterator : public Iterator @@ -168,14 +152,14 @@ protected: DISALLOW_COPY_AND_ASSIGN(PinOutputDelayIterator); }; -class VertexPinOutputDelayIterator : public PinOutputDelayIterator +class LeafPinOutputDelayIterator : public PinOutputDelayIterator { public: - VertexPinOutputDelayIterator(const Pin *vertex_pin, - const Sdc *sdc); + LeafPinOutputDelayIterator(const Pin *pin, + const Sdc *sdc); private: - DISALLOW_COPY_AND_ASSIGN(VertexPinOutputDelayIterator); + DISALLOW_COPY_AND_ASSIGN(LeafPinOutputDelayIterator); }; // Prediate used to sort port delays. diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index e6f297a3..70a1f83d 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -148,7 +148,7 @@ Sdc::clear() clocks_.clear(); clock_name_map_.clear(); clock_pin_map_.clear(); - clock_vertex_pin_map_.clear(); + clock_leaf_pin_map_.clear(); clk_latencies_.clear(); edge_clk_latency_.clear(); if (clk_insertions_) @@ -166,13 +166,14 @@ Sdc::clear() data_checks_from_map_.clear(); data_checks_to_map_.clear(); + input_delays_.clear(); input_delay_map_.clear(); input_delay_index_ = 0; input_delay_ref_pin_map_.clear(); - input_delay_vertex_map_.clear(); + input_delay_leaf_pin_map_.clear(); input_delay_internal_pin_map_.clear(); output_delay_map_.clear(); - output_delay_vertex_map_.clear(); + output_delay_leaf_pin_map_.clear(); port_slew_limit_map_.clear(); cell_slew_limit_map_.clear(); @@ -244,7 +245,7 @@ Sdc::deleteConstraints() clocks_.deleteContents(); delete default_arrival_clk_; clock_pin_map_.deleteContents(); - clock_vertex_pin_map_.deleteContents(); + clock_leaf_pin_map_.deleteContents(); clk_latencies_.deleteContents(); if (clk_insertions_) { clk_insertions_->deleteContents(); @@ -1126,10 +1127,10 @@ Sdc::deletePinClocks(Clock *defining_clk, clk->deletePin(pin); } if (clk != defining_clk) { - if (clk->pins()->empty()) + if (clk->pins().empty()) removeClock(clk); else { - clk->makeVertexPins(network_); + clk->makeLeafPins(network_); // One of the remaining clock pins may use a vertex pin that // was deleted above. makeClkPinMappings(clk); @@ -1141,9 +1142,7 @@ Sdc::deletePinClocks(Clock *defining_clk, void Sdc::deleteClkPinMappings(Clock *clk) { - ClockPinIterator pin_iter1(clk); - while (pin_iter1.hasNext()) { - Pin *pin = pin_iter1.next(); + for (Pin *pin : clk->pins()) { ClockSet *pin_clks = clock_pin_map_.findKey(pin); if (pin_clks) { pin_clks->erase(clk); @@ -1154,14 +1153,12 @@ Sdc::deleteClkPinMappings(Clock *clk) } } - ClockVertexPinIterator pin_iter2(clk); - while (pin_iter2.hasNext()) { - Pin *pin = pin_iter2.next(); - ClockSet *pin_clks = clock_vertex_pin_map_.findKey(pin); + for (const Pin *pin : clk->leafPins()) { + ClockSet *pin_clks = clock_leaf_pin_map_.findKey(pin); if (pin_clks) { pin_clks->erase(clk); if (pin_clks->empty()) { - clock_vertex_pin_map_.erase(pin); + clock_leaf_pin_map_.erase(pin); delete pin_clks; } } @@ -1171,9 +1168,7 @@ Sdc::deleteClkPinMappings(Clock *clk) void Sdc::makeClkPinMappings(Clock *clk) { - ClockPinIterator pin_iter1(clk); - while (pin_iter1.hasNext()) { - Pin *pin = pin_iter1.next(); + for (Pin *pin : clk->pins()) { ClockSet *pin_clks = clock_pin_map_.findKey(pin); if (pin_clks == nullptr) { pin_clks = new ClockSet; @@ -1182,13 +1177,11 @@ Sdc::makeClkPinMappings(Clock *clk) pin_clks->insert(clk); } - ClockVertexPinIterator pin_iter2(clk); - while (pin_iter2.hasNext()) { - Pin *pin = pin_iter2.next(); - ClockSet *pin_clks = clock_vertex_pin_map_.findKey(pin); + for (const Pin *pin : clk->leafPins()) { + ClockSet *pin_clks = clock_leaf_pin_map_.findKey(pin); if (pin_clks == nullptr) { pin_clks = new ClockSet; - clock_vertex_pin_map_.insert(pin, pin_clks); + clock_leaf_pin_map_.insert(pin, pin_clks); } pin_clks->insert(clk); } @@ -1236,7 +1229,7 @@ Sdc::clockDeletePin(Clock *clk, if (pin_clks->empty()) clock_pin_map_.erase(pin); clk->deletePin(pin); - clk->makeVertexPins(network_); + clk->makeLeafPins(network_); makeClkPinMappings(clk); } @@ -1254,16 +1247,16 @@ Sdc::isClock(const Pin *pin) const } bool -Sdc::isVertexPinClock(const Pin *pin) const +Sdc::isLeafPinClock(const Pin *pin) const { - ClockSet *clks = findVertexPinClocks(pin); + ClockSet *clks = findLeafPinClocks(pin); return clks && !clks->empty(); } bool -Sdc::isVertexPinNonGeneratedClock(const Pin *pin) const +Sdc::isLeafPinNonGeneratedClock(const Pin *pin) const { - ClockSet *clks = findVertexPinClocks(pin); + ClockSet *clks = findLeafPinClocks(pin); if (clks) { ClockSet::Iterator clk_iter(clks); while (clk_iter.hasNext()) { @@ -1278,9 +1271,9 @@ Sdc::isVertexPinNonGeneratedClock(const Pin *pin) const } ClockSet * -Sdc::findVertexPinClocks(const Pin *pin) const +Sdc::findLeafPinClocks(const Pin *pin) const { - return clock_vertex_pin_map_.findKey(pin); + return clock_leaf_pin_map_.findKey(pin); } ClockSet * @@ -1468,21 +1461,15 @@ Sdc::ensureClkHpinDisables() if (!clk_hpin_disables_valid_) { clk_hpin_disables_.deleteContentsClear(); for (auto clk : clocks_) { - PinSet *srcs = clk->pins(); - PinSet::Iterator src_iter(srcs); - while (src_iter.hasNext()) { - Pin *src = src_iter.next(); + for (Pin *src : clk->pins()) { if (network_->isHierarchical(src)) { FindClkHpinDisables visitor(clk, network_, this); visitHpinDrvrLoads(src, network_, &visitor); // Disable fanouts from the src driver pins that do // not go thru the hierarchical src pin. - PinSet *vpins = clk->vertexPins(); - PinSet::Iterator vpin_iter(vpins); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); + for (Pin *lpin : clk->leafPins()) { Vertex *vertex, *bidirect_drvr_vertex; - graph_->pinVertices(vpin, vertex, bidirect_drvr_vertex); + graph_->pinVertices(lpin, vertex, bidirect_drvr_vertex); makeVertexClkHpinDisables(clk, vertex, visitor); if (bidirect_drvr_vertex) makeVertexClkHpinDisables(clk, bidirect_drvr_vertex, visitor); @@ -1516,7 +1503,7 @@ Sdc::clkHpinDisablesInvalid() { clk_hpin_disables_valid_ = false; for (auto clk : clocks_) - clk->makeVertexPins(network_); + clk->makeLeafPins(network_); } // Check that driver/load edge goes thru clock hpin. @@ -1526,8 +1513,7 @@ Sdc::clkDisabledByHpinThru(const Clock *clk, const Pin *from_pin, const Pin *to_pin) { - if (clk->vertexPins() - && clk->vertexPins()->hasKey(const_cast(from_pin))) { + if (clk->leafPins().hasKey(const_cast(from_pin))) { ClkHpinDisable probe(clk, from_pin, to_pin); return clk_hpin_disables_.hasKey(&probe); } @@ -2807,6 +2793,7 @@ Sdc::ensureInputDelay(Pin *pin, if (input_delay == nullptr) { input_delay = new InputDelay(pin, clk_edge, ref_pin, input_delay_index_++, network_); + input_delays_.insert(input_delay); input_delay->setNext(input_delay_map_[pin]); input_delay_map_[pin] = input_delay; if (ref_pin) { @@ -2817,10 +2804,8 @@ Sdc::ensureInputDelay(Pin *pin, } ref_inputs->insert(input_delay); } - InputDelayVertexPinIterator vpin_iter(input_delay); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); - input_delay_vertex_map_[vpin] = input_delay; + for (Pin *vpin : input_delay->leafPins()) { + input_delay_leaf_pin_map_[vpin] = input_delay; if (!network_->isTopLevelPort(vpin)) { InputDelaySet *input_set = input_delay_internal_pin_map_[vpin]; if (input_set == nullptr) { @@ -2875,15 +2860,16 @@ Sdc::deleteInputDelays(Pin *pin, InputDelay *next = input_delay->next(); if (input_delay == except) input_delay->setNext(nullptr); - else + else { delete input_delay; + input_delays_.erase(input_delay); + } input_delay = next; } input_delay_map_[pin] = except; - InputDelayVertexPinIterator vpin_iter(except); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); - input_delay_vertex_map_[vpin] = except; + + for (Pin *vpin : except->leafPins()) { + input_delay_leaf_pin_map_[vpin] = except; InputDelaySet *input_delays = input_delay_internal_pin_map_.findKey(vpin); if (input_delays) { @@ -2899,35 +2885,16 @@ Sdc::refPinInputDelays(const Pin *ref_pin) const return input_delay_ref_pin_map_.findKey(ref_pin); } -InputDelayIterator * -Sdc::inputDelayIterator() -{ - return new InputDelayIterator(input_delay_map_); -} - -InputDelayVertexPinsIterator * -Sdc::inputDelayVertexPinsIterator() -{ - return new InputDelayVertexPinsIterator(input_delay_vertex_map_); -} - PinInputDelayIterator * Sdc::inputDelayIterator(const Pin *pin) const { - return new PinInputDelayIterator(pin, this); } -PinInputDelayIterator * -Sdc::inputDelayVertexIterator(const Pin *vertex_pin) const -{ - return new VertexPinInputDelayIterator(vertex_pin, this); -} - bool -Sdc::hasInputDelay(const Pin *vertex_pin) const +Sdc::hasInputDelay(const Pin *leaf_pin) const { - return input_delay_vertex_map_.findKey(vertex_pin) != nullptr; + return input_delay_leaf_pin_map_.findKey(leaf_pin) != nullptr; } bool @@ -2943,17 +2910,19 @@ Sdc::isInputDelayInternal(const Pin *pin) const void Sdc::deleteInputDelaysReferencing(Clock *clk) { - InputDelayIterator input_iter(input_delay_map_); - while (input_iter.hasNext()) { - InputDelay *input_delay = input_iter.next(); + Vector refs; + for (InputDelay *input_delay : input_delays_) { if (input_delay->clock() == clk) - deleteInputDelay(input_delay); + refs.push_back(input_delay); } + for (InputDelay *input_delay : refs) + deleteInputDelay(input_delay); } void Sdc::deleteInputDelay(InputDelay *input_delay) { + input_delays_.erase(input_delay); Pin *pin = input_delay->pin(); InputDelay *head = input_delay_map_.findKey(pin); if (head == input_delay) { @@ -2975,13 +2944,11 @@ Sdc::deleteInputDelay(InputDelay *input_delay) } } - InputDelayVertexPinIterator vpin_iter(input_delay); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); + for (Pin *vpin : input_delay->leafPins()) { if (head) - input_delay_vertex_map_[vpin] = head; + input_delay_leaf_pin_map_[vpin] = head; else - input_delay_vertex_map_.erase(vpin); + input_delay_leaf_pin_map_.erase(vpin); } delete input_delay; @@ -3022,12 +2989,11 @@ Sdc::ensureOutputDelay(Pin *pin, OutputDelay *output_delay = findOutputDelay(pin, clk_edge, ref_pin); if (output_delay == nullptr) { output_delay = new OutputDelay(pin, clk_edge, ref_pin, network_); + output_delays_.insert(output_delay); output_delay->setNext(output_delay_map_[pin]); output_delay_map_[pin] = output_delay; - OutputDelayVertexPinIterator vpin_iter(output_delay); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); - output_delay_vertex_map_[vpin] = output_delay; + for (Pin *vpin : output_delay->leafPins()) { + output_delay_leaf_pin_map_[vpin] = output_delay; if (graph_) annotateGraphConstrained(vpin, true); } @@ -3079,17 +3045,8 @@ Sdc::deleteOutputDelays(Pin *pin, output_delay = next; } output_delay_map_[pin] = except; - OutputDelayVertexPinIterator vpin_iter(except); - while (vpin_iter. hasNext()) { - Pin *vpin = vpin_iter.next(); - output_delay_vertex_map_[vpin] = except; - } -} - -OutputDelayIterator * -Sdc::outputDelayIterator() -{ - return new OutputDelayIterator(output_delay_map_); + for (Pin *vpin : except->leafPins()) + output_delay_leaf_pin_map_[vpin] = except; } PinOutputDelayIterator * @@ -3098,33 +3055,29 @@ Sdc::outputDelayIterator(const Pin *pin) const return new PinOutputDelayIterator(pin, this); } -PinOutputDelayIterator * -Sdc::outputDelayVertexIterator(const Pin *vertex_pin) const -{ - return new VertexPinOutputDelayIterator(vertex_pin, this); -} - bool -Sdc::hasOutputDelay(const Pin *vertex_pin) const +Sdc::hasOutputDelay(const Pin *leaf_pin) const { - return output_delay_vertex_map_.hasKey(vertex_pin); + return output_delay_leaf_pin_map_.hasKey(leaf_pin); } void Sdc::deleteOutputDelaysReferencing(Clock *clk) { - OutputDelayIterator output_iter(output_delay_map_); - while (output_iter.hasNext()) { - OutputDelay *output_delay = output_iter.next(); + Vector refs; + for (OutputDelay *output_delay : output_delays_) { if (output_delay->clock() == clk) - deleteOutputDelay(output_delay); + refs.push_back(output_delay); } + for (OutputDelay *output_delay : refs) + deleteOutputDelay(output_delay); } void Sdc::deleteOutputDelay(OutputDelay *output_delay) { Pin *pin = output_delay->pin(); + output_delays_.erase(output_delay); OutputDelay *head = output_delay_map_.findKey(pin); if (head == output_delay) { OutputDelay *next = output_delay->next(); @@ -3145,13 +3098,11 @@ Sdc::deleteOutputDelay(OutputDelay *output_delay) } } - OutputDelayVertexPinIterator vpin_iter(output_delay); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); + for (Pin *vpin : output_delay->leafPins()) { if (head) - output_delay_vertex_map_[vpin] = head; + output_delay_leaf_pin_map_[vpin] = head; else - output_delay_vertex_map_.erase(vpin); + output_delay_leaf_pin_map_.erase(vpin); } delete output_delay; @@ -6167,7 +6118,7 @@ Sdc::disconnectPinBefore(Pin *pin) void Sdc::clkHpinDisablesChanged(Pin *pin) { - if (isVertexPinClock(pin)) + if (isLeafPinClock(pin)) clkHpinDisablesInvalid(); } @@ -6398,11 +6349,8 @@ Sdc::annotateGraphOutputDelays(bool annotate) while (output_iter.hasNext()) { OutputDelay *output_delay = output_iter.next(); while (output_delay) { - OutputDelayVertexPinIterator vpin_iter(output_delay); - while (vpin_iter.hasNext()) { - Pin *vpin = vpin_iter.next(); + for (Pin *vpin : output_delay->leafPins()) annotateGraphConstrained(vpin, annotate); - } output_delay = output_delay->next(); } } @@ -6534,40 +6482,14 @@ Sdc::clockLatency(Edge *edge, //////////////////////////////////////////////////////////////// -InputDelayVertexPinsIterator::InputDelayVertexPinsIterator(Sdc *sdc) : - InputDelayVertexPinsIterator(sdc->input_delay_map_) -{ -} - -InputDelayVertexPinsIterator::InputDelayVertexPinsIterator(InputDelayMap - &input_delay_map) : - input_iter_(input_delay_map) -{ -} - -bool -InputDelayVertexPinsIterator::hasNext() -{ - return input_iter_.hasNext(); -} - -const Pin * -InputDelayVertexPinsIterator::next() -{ - const Pin *pin; - InputDelay *input_delay; - input_iter_.next(pin, input_delay); - return pin; -} - -//////////////////////////////////////////////////////////////// - -// Find the graph vertex pins corresponding to pin. -// If the pin is hierarchical, the vertex pins are: +// Find the leaf load pins corresponding to pin. +// If the pin is hierarchical, the leaf pins are: // hierarchical input - load pins inside the hierarchical instance // hierarchical output - load pins outside the hierarchical instance void -findVertexLoadPins(Pin *pin, const Network *network, PinSet *vertex_pins) +findLeafLoadPins(Pin *pin, + const Network *network, + PinSet *leaf_pins) { if (network->isHierarchical(pin)) { PortDirection *dir = network->direction(pin); @@ -6581,22 +6503,22 @@ findVertexLoadPins(Pin *pin, const Network *network, PinSet *vertex_pins) if (((is_input && is_inside) || (is_output && !is_inside)) && network->isLoad(pin1)) - vertex_pins->insert(pin1); + leaf_pins->insert(pin1); } delete pin_iter; } else - vertex_pins->insert(pin); + leaf_pins->insert(pin); } -// Find the graph vertex pins corresponding to pin. -// If the pin is hierarchical, the vertex pins are: +// Find the leaf driver pins corresponding to pin. +// If the pin is hierarchical, the leaf pins are: // hierarchical input - driver pins outside the hierarchical instance // hierarchical output - driver pins inside the hierarchical instance void -findVertexDriverPins(Pin *pin, - const Network *network, - PinSet *vertex_pins) +findLeafDriverPins(Pin *pin, + const Network *network, + PinSet *leaf_pins) { if (network->isHierarchical(pin)) { PortDirection *dir = network->direction(pin); @@ -6610,86 +6532,12 @@ findVertexDriverPins(Pin *pin, if (((is_input && !is_inside) || (is_output && is_inside)) && network->isDriver(pin1)) - vertex_pins->insert(pin1); + leaf_pins->insert(pin1); } delete pin_iter; } else - vertex_pins->insert(pin); -} - -//////////////////////////////////////////////////////////////// - -InputDelayIterator::InputDelayIterator(Sdc *sdc) : - InputDelayIterator(sdc->input_delay_map_) -{ -} - -InputDelayIterator::InputDelayIterator(InputDelayMap &input_delay_map) : - input_iter_(input_delay_map), - next_(NULL) -{ - findNext(); -} - -bool -InputDelayIterator::hasNext() -{ - return next_ != NULL; -} - -InputDelay * -InputDelayIterator::next() -{ - InputDelay *next = next_; - findNext(); - return next; -} - -void -InputDelayIterator::findNext() -{ - if (next_) - next_ = next_->next(); - if (next_ == NULL && input_iter_.hasNext()) - next_ = input_iter_.next(); -} - -//////////////////////////////////////////////////////////////// - -OutputDelayIterator::OutputDelayIterator(Sdc *sdc) : - OutputDelayIterator(sdc->output_delay_map_) -{ -} - -OutputDelayIterator::OutputDelayIterator(OutputDelayMap &output_delay_map) : - output_iter_(output_delay_map), - next_(NULL) -{ - findNext(); -} - -bool -OutputDelayIterator::hasNext() -{ - return next_ != NULL; -} - -OutputDelay * -OutputDelayIterator::next() -{ - OutputDelay *next = next_; - findNext(); - return next; -} - -void -OutputDelayIterator::findNext() -{ - if (next_) - next_ = next_->next(); - if (next_ == NULL && output_iter_.hasNext()) - next_ = output_iter_.next(); + leaf_pins->insert(pin); } //////////////////////////////////////////////////////////////// diff --git a/sdc/Sdc.hh b/sdc/Sdc.hh index 873b0df1..9eac9f83 100644 --- a/sdc/Sdc.hh +++ b/sdc/Sdc.hh @@ -39,14 +39,11 @@ namespace sta { class OperatingConditions; class PinInputDelayIterator; -class InputDelayVertexPinsIterator; class PinOutputDelayIterator; class PortExtCap; class ClockGatingCheck; class InputDriveCell; class DisabledPorts; -class InputDelayIterator; -class OutputDelayIterator; class GraphLoop; class DeratingFactors; class DeratingFactorsGlobal; @@ -59,7 +56,6 @@ class FindClkHpinDisables; class Corner; class ClockGroupIterator; class GroupPathIterator; -class ClockVertexPinIterator; class ClockPinIterator; class ClockIterator; @@ -109,10 +105,12 @@ public: typedef Map ClockNameMap; typedef UnorderedMap ClockPinMap; +typedef Set InputDelaySet; typedef Map InputDelayMap; typedef Set InputDelaySet; typedef Map InputDelayRefPinMap; typedef Map InputDelayInternalPinMap; +typedef Set OutputDelaySet; typedef Map OutputDelayMap; // Use HashSet so no read lock is required. typedef HashSet CycleAcctingSet; @@ -169,13 +167,13 @@ typedef Map GroupPathMap; typedef Set ClockPairSet; void -findVertexLoadPins(Pin *pin, const - Network *network, - PinSet *vertex_pins); +findLeafLoadPins(Pin *pin, + const Network *network, + PinSet *leaf_pins); void -findVertexDriverPins(Pin *pin, - const Network *network, - PinSet *vertex_pins); +findLeafDriverPins(Pin *pin, + const Network *network, + PinSet *leaf_pins); class Sdc : public StaState { @@ -840,12 +838,12 @@ public: // True if pin is defined as a clock source (pin may be hierarchical). bool isClock(const Pin *pin) const; // True if pin is a clock source vertex. - bool isVertexPinClock(const Pin *pin) const; + bool isLeafPinClock(const Pin *pin) const; // True if pin is a non-generated clock source vertex. - bool isVertexPinNonGeneratedClock(const Pin *pin) const; + bool isLeafPinNonGeneratedClock(const Pin *pin) const; // Find the clocks defined for pin. ClockSet *findClocks(const Pin *pin) const; - ClockSet *findVertexPinClocks(const Pin *pin) const; + ClockSet *findLeafPinClocks(const Pin *pin) const; ClockIterator *clockIterator(); void sortedClocks(ClockSeq &clks); ClockSeq *clocks() { return &clocks_; } @@ -894,28 +892,18 @@ public: const ClockEdge *tgt); // Report clock to clock relationships that exceed max_cycle_count. void reportClkToClkMaxCycleWarnings(); - InputDelayIterator *inputDelayIterator(); - // Iterate over the graph vertex pins that have input arrivals. - // If the pin is hierarchical, the vertex pins are: - // hierarchical input - load pins inside the hierarchical instance. - // hierarchical output - load pins outside the hierarchical instance. - InputDelayVertexPinsIterator *inputDelayVertexPinsIterator(); + const InputDelaySet &inputDelays() const { return input_delays_; } + // Pin -> input delays. + const InputDelayMap &inputDelayMap() const { return input_delay_map_; } // Iterate over the input delays on pin (which may be hierarchical). PinInputDelayIterator *inputDelayIterator(const Pin *pin) const; - // Iterate over the input delays on vertex_pin. - PinInputDelayIterator *inputDelayVertexIterator(const Pin *vertex_pin) const; - bool hasInputDelay(const Pin *vertex_pin) const; + bool hasInputDelay(const Pin *leaf_pin) const; // Pin is internal (not top level port) and has an input arrival. bool isInputDelayInternal(const Pin *pin) const; - OutputDelayIterator *outputDelayIterator(); + const OutputDelaySet &outputDelays() const { return output_delays_; } // Iterate over the output delays on pin (which may be hierarchical). PinOutputDelayIterator *outputDelayIterator(const Pin *pin) const; - // Iterate over the output delays on vertex_pin. - // If the pin is hierarchical, the vertex pins are: - // hierarchical input - driver pins outside the hierarchical instance. - // hierarchical output - driver pins inside the hierarchical instance. - PinOutputDelayIterator *outputDelayVertexIterator(const Pin *vertex_pin) const; - bool hasOutputDelay(const Pin *vertex_pin) const; + bool hasOutputDelay(const Pin *leaf_pin) const; PortExtCap *portExtCap(Port *port) const; bool hasPortExtCap(Port *port) const; void portExtCap(Port *port, @@ -1302,7 +1290,7 @@ protected: ClockNameMap clock_name_map_; ClockPinMap clock_pin_map_; // Clocks on hierarchical pins are indexed by the load pins. - ClockPinMap clock_vertex_pin_map_; + ClockPinMap clock_leaf_pin_map_; ClkHpinDisables clk_hpin_disables_; bool clk_hpin_disables_valid_; PinSet propagated_clk_pins_; @@ -1325,15 +1313,17 @@ protected: std::mutex cycle_acctings_lock_; DataChecksMap data_checks_from_map_; DataChecksMap data_checks_to_map_; + InputDelaySet input_delays_; InputDelayMap input_delay_map_; int input_delay_index_; InputDelayRefPinMap input_delay_ref_pin_map_; // Input delays on hierarchical pins are indexed by the load pins. - InputDelayMap input_delay_vertex_map_; + InputDelayMap input_delay_leaf_pin_map_; InputDelayInternalPinMap input_delay_internal_pin_map_; + OutputDelaySet output_delays_; OutputDelayMap output_delay_map_; // Output delays on hierarchical pins are indexed by the load pins. - OutputDelayMap output_delay_vertex_map_; + OutputDelayMap output_delay_leaf_pin_map_; PortSlewLimitMap port_slew_limit_map_; PinSlewLimitMap pin_slew_limit_map_; CellSlewLimitMap cell_slew_limit_map_; @@ -1427,67 +1417,13 @@ private: DISALLOW_COPY_AND_ASSIGN(Sdc); friend class WriteSdc; - friend class InputDelayIterator; - friend class OutputDelayIterator; friend class FindNetCaps; friend class ClockGroupIterator; friend class GroupPathIterator; - friend class InputDelayVertexPinsIterator; friend class PinInputDelayIterator; - friend class VertexPinInputDelayIterator; + friend class LeafPinInputDelayIterator; friend class PinOutputDelayIterator; - friend class VertexPinOutputDelayIterator; -}; - -class InputDelayVertexPinsIterator : public Iterator -{ -public: - InputDelayVertexPinsIterator(Sdc *sdc); - virtual bool hasNext(); - virtual const Pin *next(); - -private: - InputDelayVertexPinsIterator(InputDelayMap &input_delay_map); - InputDelayMap::ConstIterator input_iter_; - - friend class Sdc; - DISALLOW_COPY_AND_ASSIGN(InputDelayVertexPinsIterator); -}; - -class InputDelayIterator : public Iterator -{ -public: - InputDelayIterator(Sdc *sdc); - virtual bool hasNext(); - virtual InputDelay *next(); - -private: - InputDelayIterator(InputDelayMap &input_delay_map); - void findNext(); - - InputDelayMap::Iterator input_iter_; - InputDelay *next_; - - friend class Sdc; - DISALLOW_COPY_AND_ASSIGN(InputDelayIterator); -}; - -class OutputDelayIterator : public OutputDelayMap::Iterator -{ -public: - OutputDelayIterator(Sdc *sdc); - virtual bool hasNext(); - virtual OutputDelay *next(); - -private: - OutputDelayIterator(OutputDelayMap &output_delay_map); - void findNext(); - - OutputDelayMap::Iterator output_iter_; - OutputDelay *next_; - - friend class Sdc; - DISALLOW_COPY_AND_ASSIGN(OutputDelayIterator); + friend class LeafPinOutputDelayIterator; }; class ClockIterator : public ClockSeq::Iterator diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc index 7a0ee207..27fa640f 100644 --- a/sdc/WriteSdc.cc +++ b/sdc/WriteSdc.cc @@ -110,6 +110,7 @@ class WriteGetPinAndClkKey : public WriteSdcObject { public: WriteGetPinAndClkKey(const Pin *pin, + bool map_hpin_to_drvr, const Clock *clk, const WriteSdc *writer); virtual void write() const; @@ -118,14 +119,17 @@ private: DISALLOW_COPY_AND_ASSIGN(WriteGetPinAndClkKey); const Pin *pin_; + bool map_hpin_to_drvr_; const Clock *clk_; const WriteSdc *writer_; }; WriteGetPinAndClkKey::WriteGetPinAndClkKey(const Pin *pin, + bool map_hpin_to_drvr, const Clock *clk, const WriteSdc *writer) : pin_(pin), + map_hpin_to_drvr_(map_hpin_to_drvr), clk_(clk), writer_(writer) { @@ -136,13 +140,14 @@ WriteGetPinAndClkKey::write() const { writer_->writeClockKey(clk_); fprintf(writer_->stream(), " "); - writer_->writeGetPin(pin_); + writer_->writeGetPin(pin_, map_hpin_to_drvr_); } class WriteGetPin : public WriteSdcObject { public: WriteGetPin(const Pin *pin, + bool map_hpin_to_drvr, const WriteSdc *writer); virtual void write() const; @@ -150,12 +155,15 @@ private: DISALLOW_COPY_AND_ASSIGN(WriteGetPin); const Pin *pin_; + bool map_hpin_to_drvr_; const WriteSdc *writer_; }; WriteGetPin::WriteGetPin(const Pin *pin, + bool map_hpin_to_drvr, const WriteSdc *writer) : pin_(pin), + map_hpin_to_drvr_(map_hpin_to_drvr), writer_(writer) { } @@ -163,7 +171,7 @@ WriteGetPin::WriteGetPin(const Pin *pin, void WriteGetPin::write() const { - writer_->writeGetPin(pin_); + writer_->writeGetPin(pin_, map_hpin_to_drvr_); } class WriteGetNet : public WriteSdcObject @@ -280,20 +288,22 @@ void writeSdc(Instance *instance, const char *filename, const char *creator, - bool compatible, + bool map_hpins, + bool native, bool no_timestamp, int digits, Sdc *sdc) { - WriteSdc writer(instance, filename, creator, compatible, digits, - no_timestamp, sdc); + WriteSdc writer(instance, filename, creator, map_hpins, native, + digits, no_timestamp, sdc); writer.write(); } WriteSdc::WriteSdc(Instance *instance, const char *filename, const char *creator, - bool compatible, + bool map_hpins, + bool native, int digits, bool no_timestamp, Sdc *sdc) : @@ -301,7 +311,8 @@ WriteSdc::WriteSdc(Instance *instance, instance_(instance), filename_(filename), creator_(creator), - compatible_(compatible), + map_hpins_(map_hpins), + native_(native), digits_(digits), no_timestamp_(no_timestamp), top_instance_(instance == sdc_network_->topInstance()), @@ -430,7 +441,7 @@ WriteSdc::writeGeneratedClock(Clock *clk) const if (clk->addToPins()) fprintf(stream_, " -add"); fprintf(stream_, " -source "); - writeGetPin(clk->srcPin()); + writeGetPin(clk->srcPin(), true); Clock *master = clk->masterClk(); if (master && !clk->masterClkInfered()) { fprintf(stream_, " -master_clock "); @@ -439,12 +450,12 @@ WriteSdc::writeGeneratedClock(Clock *clk) const Pin *pll_out = clk->pllOut(); if (pll_out) { fprintf(stream_, " -pll_out "); - writeGetPin(pll_out); + writeGetPin(pll_out, true); } Pin *pll_fdbk = clk->pllFdbk(); if (pll_fdbk) { fprintf(stream_, " -pll_feedback "); - writeGetPin(pll_fdbk); + writeGetPin(pll_fdbk, false); } if (clk->combinational()) fprintf(stream_, " -combinational"); @@ -481,16 +492,11 @@ void WriteSdc::writeClockPins(Clock *clk) const { // Sort pins. - PinSeq pins; - ClockPinIterator pin_iter(clk); - while (pin_iter.hasNext()) - pins.push_back(pin_iter.next()); - + PinSet &pins = clk->pins(); if (!pins.empty()) { - sort(pins, PinPathNameLess(sdc_network_)); if (pins.size() > 1) fprintf(stream_, "\\\n "); - writeGetPins(&pins); + writeGetPins(&pins, true); } } @@ -572,7 +578,7 @@ WriteSdc::writeClockUncertaintyPin(const Pin *pin, fprintf(stream_, "set_clock_uncertainty %s", setup_hold); writeTime(value); fprintf(stream_, " "); - writeGetPin(pin); + writeGetPin(pin, true); fprintf(stream_, "\n"); } @@ -585,12 +591,12 @@ WriteSdc::writeClockLatencies() const const Pin *pin = latency->pin(); const Clock *clk = latency->clock(); if (pin && clk) { - WriteGetPinAndClkKey write_pin(pin, clk, this); + WriteGetPinAndClkKey write_pin(pin, true, clk, this); writeRiseFallMinMaxTimeCmd("set_clock_latency", latency->delays(), write_pin); } else if (pin) { - WriteGetPin write_pin(pin, this); + WriteGetPin write_pin(pin, true, this); writeRiseFallMinMaxTimeCmd("set_clock_latency", latency->delays(), write_pin); } @@ -611,11 +617,11 @@ WriteSdc::writeClockInsertions() const const Pin *pin = insert->pin(); const Clock *clk = insert->clock(); if (pin && clk) { - WriteGetPinAndClkKey write_pin_clk(pin, clk, this); + WriteGetPinAndClkKey write_pin_clk(pin, true, clk, this); writeClockInsertion(insert, write_pin_clk); } else if (pin) { - WriteGetPin write_pin(pin, this); + WriteGetPin write_pin(pin, true, this); writeClockInsertion(insert, write_pin); } else if (clk) { @@ -649,7 +655,7 @@ WriteSdc::writePropagatedClkPins() const while (pin_iter.hasNext()) { const Pin *pin = pin_iter.next(); fprintf(stream_, "set_propagated_clock "); - writeGetPin(pin); + writeGetPin(pin, true); fprintf(stream_, "\n"); } } @@ -717,11 +723,8 @@ WriteSdc::writeInputDelays() const { // Sort arrivals by pin and clock name. PortDelaySeq delays; - InputDelayIterator input_iter(sdc_); - while (input_iter.hasNext()) { - InputDelay *input_delay = input_iter.next(); + for (InputDelay *input_delay : sdc_->inputDelays()) delays.push_back(input_delay); - } PortDelayLess port_delay_less(sdc_network_); sort(delays, port_delay_less); @@ -729,7 +732,7 @@ WriteSdc::writeInputDelays() const PortDelaySeq::Iterator delay_iter(delays); while (delay_iter.hasNext()) { PortDelay *input_delay = delay_iter.next(); - writePortDelay(input_delay, "set_input_delay"); + writePortDelay(input_delay, true, "set_input_delay"); } } @@ -738,11 +741,8 @@ WriteSdc::writeOutputDelays() const { // Sort departures by pin and clock name. PortDelaySeq delays; - OutputDelayIterator output_iter(sdc_); - while (output_iter.hasNext()) { - OutputDelay *output_delay = output_iter.next(); + for (OutputDelay *output_delay : sdc_->outputDelays()) delays.push_back(output_delay); - } PortDelayLess port_delay_less(sdc_network_); sort(delays, port_delay_less); @@ -750,12 +750,13 @@ WriteSdc::writeOutputDelays() const PortDelaySeq::Iterator delay_iter(delays); while (delay_iter.hasNext()) { PortDelay *output_delay = delay_iter.next(); - writePortDelay(output_delay, "set_output_delay"); + writePortDelay(output_delay, false, "set_output_delay"); } } void WriteSdc::writePortDelay(PortDelay *port_delay, + bool is_input_delay, const char *sdc_cmd) const { RiseFallMinMax *delays = port_delay->delays(); @@ -777,7 +778,7 @@ WriteSdc::writePortDelay(PortDelay *port_delay, && rise_max == rise_min && fall_min == rise_min && fall_max == rise_min) - writePortDelay(port_delay, rise_min, + writePortDelay(port_delay, is_input_delay, rise_min, TransRiseFallBoth::riseFall(), MinMaxAll::all(), sdc_cmd); else if (rise_min_exists && rise_max_exists @@ -785,9 +786,9 @@ WriteSdc::writePortDelay(PortDelay *port_delay, && fall_min_exists && fall_max_exists && fall_min == fall_max) { - writePortDelay(port_delay, rise_min, + writePortDelay(port_delay, is_input_delay, rise_min, TransRiseFallBoth::rise(), MinMaxAll::all(), sdc_cmd); - writePortDelay(port_delay, fall_min, + writePortDelay(port_delay, is_input_delay, fall_min, TransRiseFallBoth::fall(), MinMaxAll::all(), sdc_cmd); } else if (rise_min_exists @@ -796,29 +797,30 @@ WriteSdc::writePortDelay(PortDelay *port_delay, && rise_max_exists && fall_max_exists && rise_max == fall_max) { - writePortDelay(port_delay, rise_min, + writePortDelay(port_delay, is_input_delay, rise_min, TransRiseFallBoth::riseFall(), MinMaxAll::min(), sdc_cmd); - writePortDelay(port_delay, rise_max, + writePortDelay(port_delay, is_input_delay, rise_max, TransRiseFallBoth::riseFall(), MinMaxAll::max(), sdc_cmd); } else { if (rise_min_exists) - writePortDelay(port_delay, rise_min, + writePortDelay(port_delay, is_input_delay, rise_min, TransRiseFallBoth::rise(), MinMaxAll::min(), sdc_cmd); if (rise_max_exists) - writePortDelay(port_delay, rise_max, + writePortDelay(port_delay, is_input_delay, rise_max, TransRiseFallBoth::rise(), MinMaxAll::max(), sdc_cmd); if (fall_min_exists) - writePortDelay(port_delay, fall_min, + writePortDelay(port_delay, is_input_delay, fall_min, TransRiseFallBoth::fall(), MinMaxAll::min(), sdc_cmd); if (fall_max_exists) - writePortDelay(port_delay, fall_max, + writePortDelay(port_delay, is_input_delay, fall_max, TransRiseFallBoth::fall(), MinMaxAll::max(), sdc_cmd); } } void WriteSdc::writePortDelay(PortDelay *port_delay, + bool is_input_delay, float delay, const TransRiseFallBoth *tr, const MinMaxAll *min_max, @@ -838,16 +840,10 @@ WriteSdc::writePortDelay(PortDelay *port_delay, Pin *ref_pin = port_delay->refPin(); if (ref_pin) { fprintf(stream_, "-reference_pin "); - writeGetPin(ref_pin); + writeGetPin(ref_pin, true); fprintf(stream_, " "); } - Pin *pin = port_delay->pin(); - if (sdc_network_->instance(pin) == instance_) { - Port *port = sdc_network_->port(pin); - writeGetPort(port); - } - else - writeGetPin(pin); + writeGetPin(port_delay->pin(), is_input_delay); fprintf(stream_, "\n"); } @@ -919,7 +915,7 @@ WriteSdc::writeClockSense(PinClockPair &pin_clk, writeGetClock(clk); fprintf(stream_, " "); } - writeGetPin(pin_clk.first); + writeGetPin(pin_clk.first, true); fprintf(stream_, "\n"); } @@ -1184,7 +1180,7 @@ WriteSdc::writeDisabledPins() const while (pin_iter.hasNext()) { Pin *pin = pin_iter.next(); fprintf(stream_, "set_disable_timing "); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } } @@ -1350,7 +1346,7 @@ WriteSdc::writeExceptionValue(ExceptionPath *exception) const void WriteSdc::writeExceptionFrom(ExceptionFrom *from) const { - writeExceptionFromTo(from, "from"); + writeExceptionFromTo(from, "from", true); } void @@ -1360,12 +1356,13 @@ WriteSdc::writeExceptionTo(ExceptionTo *to) const if (end_tr != TransRiseFallBoth::riseFall()) fprintf(stream_, "%s ", transRiseFallFlag(end_tr)); if (to->hasObjects()) - writeExceptionFromTo(to, "to"); + writeExceptionFromTo(to, "to", false); } void WriteSdc::writeExceptionFromTo(ExceptionFromTo *from_to, - const char *from_to_key) const + const char *from_to_key, + bool map_hpin_to_drvr) const { const TransRiseFallBoth *tr = from_to->transition(); const char *tr_prefix = "-"; @@ -1389,7 +1386,7 @@ WriteSdc::writeExceptionFromTo(ExceptionFromTo *from_to, Pin *pin = pin_iter.next(); if (multi_objs && !first) fprintf(stream_, "\\\n "); - writeGetPin(pin); + writeGetPin(pin, map_hpin_to_drvr); first = false; } } @@ -1421,25 +1418,25 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const else if (tr == TransRiseFallBoth::fall()) tr_prefix = "-fall_"; fprintf(stream_, "\\\n %sthrough ", tr_prefix); + PinSeq pins; + mapThruHpins(thru, pins); bool multi_objs = - ((thru->pins() ? thru->pins()->size() : 0) + (pins.size() + (thru->nets() ? thru->nets()->size() : 0) - + (thru->instances() ? thru->instances()->size() : 0)) > 1; + + (thru->instances() ? thru->instances()->size() : 0)) > 1; if (multi_objs) fprintf(stream_, "[list "); bool first = true; - if (thru->pins()) { - PinSeq pins; - sortPinSet(thru->pins(), sdc_network_, pins); - PinSeq::Iterator pin_iter(pins); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); - if (multi_objs && !first) - fprintf(stream_, "\\\n "); - writeGetPin(pin); - first = false; - } + sort(pins, PinPathNameLess(network_)); + PinSeq::Iterator pin_iter(pins); + while (pin_iter.hasNext()) { + Pin *pin = pin_iter.next(); + if (multi_objs && !first) + fprintf(stream_, "\\\n "); + writeGetPin(pin); + first = false; } + if (thru->nets()) { NetSeq nets; sortNetSet(thru->nets(), sdc_network_, nets); @@ -1468,6 +1465,33 @@ WriteSdc::writeExceptionThru(ExceptionThru *thru) const fprintf(stream_, "]"); } +void +WriteSdc::mapThruHpins(ExceptionThru *thru, + PinSeq &pins) const +{ + if (thru->pins()) { + for (Pin *pin : *thru->pins()) { + // Map hierarical pins to load pins outside of outputs or inside of inputs. + if (network_->isHierarchical(pin)) { + Instance *hinst = network_->instance(pin); + bool hpin_is_output = network_->direction(pin)->isAnyOutput(); + PinConnectedPinIterator *cpin_iter = network_->connectedPinIterator(pin); + while (cpin_iter->hasNext()) { + Pin *cpin = cpin_iter->next(); + if (network_->isLoad(cpin) + && ((hpin_is_output + && !network_->isInside(network_->instance(cpin), hinst)) + || (!hpin_is_output + && network_->isInside(network_->instance(cpin), hinst)))) + pins.push_back(cpin); + } + } + else + pins.push_back(pin); + } + } +} + //////////////////////////////////////////////////////////////// void @@ -1530,14 +1554,14 @@ WriteSdc::writeDataCheck(DataCheck *check, else if (from_tr == TransRiseFallBoth::fall()) from_key = "-fall_from"; fprintf(stream_, "set_data_check %s ", from_key); - writeGetPin(check->from()); + writeGetPin(check->from(), true); const char *to_key = "-to"; if (to_tr == TransRiseFallBoth::rise()) to_key = "-rise_to"; else if (to_tr == TransRiseFallBoth::fall()) to_key = "-fall_to"; fprintf(stream_, " %s ", to_key); - writeGetPin(check->to()); + writeGetPin(check->to(), false); fprintf(stream_, "%s ", setupHoldFlag(setup_hold)); writeTime(margin); @@ -1816,7 +1840,7 @@ WriteSdc::writeConstant(Pin *pin) const { const char *cmd = setConstantCmd(pin); fprintf(stream_, "%s ", cmd); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } @@ -1858,7 +1882,7 @@ WriteSdc::writeCaseAnalysis(Pin *pin) const { const char *value_str = caseAnalysisValueStr(pin); fprintf(stream_, "set_case_analysis %s ", value_str); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } @@ -2087,7 +2111,7 @@ WriteSdc::writeMinPulseWidths() const const Pin *pin; RiseFallValues *min_widths; pin_iter.next(pin, min_widths); - WriteGetPin write_obj(pin, this); + WriteGetPin write_obj(pin, false, this); writeMinPulseWidths(min_widths, write_obj); } InstMinPulseWidthMap::Iterator @@ -2155,7 +2179,7 @@ WriteSdc::writeLatchBorowLimits() const fprintf(stream_, "set_max_time_borrow "); writeTime(limit); fprintf(stream_, " "); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } InstLatchBorrowLimitMap::Iterator @@ -2226,7 +2250,7 @@ WriteSdc::writeSlewLimits() const fprintf(stream_, "set_max_transition "); writeTime(slew); fprintf(stream_, " "); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } } @@ -2345,7 +2369,7 @@ WriteSdc::writeCapLimits(const MinMax *min_max, fprintf(stream_, "%s ", cmd); writeCapacitance(cap); fprintf(stream_, " "); - writeGetPin(pin); + writeGetPin(pin, false); fprintf(stream_, "\n"); } } @@ -2404,16 +2428,16 @@ void WriteSdc::writeVariables() const { if (sdc_->propagateAllClocks()) { - if (compatible_) - fprintf(stream_, "set timing_all_clocks_propagated true\n"); - else + if (native_) fprintf(stream_, "set sta_propagate_all_clocks 1\n"); + else + fprintf(stream_, "set timing_all_clocks_propagated true\n"); } if (sdc_->presetClrArcsEnabled()) { - if (compatible_) - fprintf(stream_, "set timing_enable_preset_clear_arcs true\n"); - else + if (native_) fprintf(stream_, "set sta_preset_clear_arcs_enabled 1\n"); + else + fprintf(stream_, "set timing_enable_preset_clear_arcs true\n"); } } @@ -2439,10 +2463,10 @@ WriteSdc::writeGetTimingArcs(Edge *edge, { fprintf(stream_, "[%s -from ", getTimingArcsCmd()); Vertex *from_vertex = edge->from(graph_); - writeGetPin(from_vertex->pin()); + writeGetPin(from_vertex->pin(), true); fprintf(stream_, " -to "); Vertex *to_vertex = edge->to(graph_); - writeGetPin(to_vertex->pin()); + writeGetPin(to_vertex->pin(), false); if (filter) fprintf(stream_, " -filter {%s}", filter); fprintf(stream_, "]"); @@ -2451,7 +2475,7 @@ WriteSdc::writeGetTimingArcs(Edge *edge, const char * WriteSdc::getTimingArcsCmd() const { - return compatible_ ? "get_timing_arcs" : "get_timing_edges"; + return native_ ? "get_timing_edges" : "get_timing_arcs"; } //////////////////////////////////////////////////////////////// @@ -2518,15 +2542,17 @@ WriteSdc::writeGetPort(const Port *port) const } void -WriteSdc::writeGetPins(PinSet *pins) const +WriteSdc::writeGetPins(PinSet *pins, + bool map_hpin_to_drvr) const { PinSeq pins1; sortPinSet(pins, sdc_network_, pins1); - writeGetPins(&pins1); + writeGetPins(&pins1, map_hpin_to_drvr); } void -WriteSdc::writeGetPins(PinSeq *pins) const +WriteSdc::writeGetPins(PinSeq *pins, + bool map_hpin_to_drvr) const { bool multiple = pins->size() > 1; if (multiple) @@ -2537,7 +2563,7 @@ WriteSdc::writeGetPins(PinSeq *pins) const Pin *pin = pin_iter.next(); if (multiple && !first) fprintf(stream_, "\\\n "); - writeGetPin(pin); + writeGetPin(pin, map_hpin_to_drvr); first = false; } if (multiple) @@ -2553,6 +2579,51 @@ WriteSdc::writeGetPin(const Pin *pin) const fprintf(stream_, "[get_pins {%s}]", pathName(pin)); } +void +WriteSdc::writeGetPin(const Pin *pin, + bool map_hpin_to_drvr) const +{ + if (map_hpins_ && map_hpin_to_drvr) + pin = leafDrvrPin(pin); + else if (map_hpins_ && !map_hpin_to_drvr) + pin = leafLoadPin(pin); + + if (sdc_network_->instance(pin) == instance_) + fprintf(stream_, "[get_ports {%s}]", sdc_network_->portName(pin)); + else + fprintf(stream_, "[get_pins {%s}]", pathName(pin)); +} + +const Pin * +WriteSdc::leafDrvrPin(const Pin *pin) const +{ + PinSet leaf_pins; + findLeafDriverPins(const_cast(pin), network_, &leaf_pins); + PinSet::Iterator pin_iter(leaf_pins); + if (pin_iter.hasNext()) + return pin_iter.next(); + else { + report_->warn("No leaf driver pin found for hierarchical pin %s\n", + sdc_network_->pathName(pin)); + return pin; + } +} + +const Pin * +WriteSdc::leafLoadPin(const Pin *pin) const +{ + PinSet leaf_pins; + findLeafLoadPins(const_cast(pin), network_, &leaf_pins); + PinSet::Iterator pin_iter(leaf_pins); + if (pin_iter.hasNext()) + return pin_iter.next(); + else { + report_->warn("No leaf load pin found for hierarchical pin %s\n", + sdc_network_->pathName(pin)); + return pin; + } +} + void WriteSdc::writeGetNet(const Net *net) const { diff --git a/sdc/WriteSdc.hh b/sdc/WriteSdc.hh index 776e204d..06c88f6d 100644 --- a/sdc/WriteSdc.hh +++ b/sdc/WriteSdc.hh @@ -28,7 +28,10 @@ void writeSdc(Instance *instance, const char *filename, const char *creator, - bool compatible, + // Map hierarchical pins and instances to leaf pins and instances. + bool map_hpins, + // Replace non-sdc get functions with OpenSTA equivalents. + bool native, bool no_timestamp, int digits, Sdc *sdc); diff --git a/sdc/WriteSdcPvt.hh b/sdc/WriteSdcPvt.hh index b719aa15..b2c2a378 100644 --- a/sdc/WriteSdcPvt.hh +++ b/sdc/WriteSdcPvt.hh @@ -29,7 +29,8 @@ public: WriteSdc(Instance *instance, const char *filename, const char *creator, - bool compatible, + bool map_hpins, + bool native, int digits, bool no_timestamp, Sdc *sdc); @@ -82,8 +83,10 @@ public: void writeInputDelays() const; void writeOutputDelays() const; void writePortDelay(PortDelay *port_delay, + bool is_input_delay, const char *sdc_cmd) const; void writePortDelay(PortDelay *port_delay, + bool is_input_delay, float delay, const TransRiseFallBoth *tr, const MinMaxAll *min_max, @@ -100,8 +103,11 @@ public: void writeExceptionFrom(ExceptionFrom *from) const; void writeExceptionTo(ExceptionTo *to) const; void writeExceptionFromTo(ExceptionFromTo *from_to, - const char *from_to_key) const; + const char *from_to_key, + bool map_hpin_to_drvr) const; void writeExceptionThru(ExceptionThru *thru) const; + void mapThruHpins(ExceptionThru *thru, + PinSeq &pins) const; void writeDataChecks() const; void writeDataCheck(DataCheck *check) const; void writeDataCheck(DataCheck *check, @@ -179,10 +185,14 @@ public: bool &first) const; virtual void writeGetPort(const Port *port) const; virtual void writeGetPin(const Pin *pin) const; + void writeGetPin(const Pin *pin, + bool map_hpin_to_drvr) const; virtual void writeGetNet(const Net *net) const; virtual void writeGetInstance(const Instance *inst) const; - void writeGetPins(PinSet *pins) const; - void writeGetPins(PinSeq *pins) const; + void writeGetPins(PinSet *pins, + bool map_hpin_to_drvr) const; + void writeGetPins(PinSeq *pins, + bool map_hpin_to_drvr) const; void writeClockKey(const Clock *clk) const; float scaleTime(float time) const; float scaleCapacitance(float cap) const; @@ -232,6 +242,8 @@ public: void writeSetupHoldFlag(const MinMaxAll *min_max) const; void writeVariables() const; void writeCmdComment(SdcCmdComment *cmd) const; + const Pin *leafDrvrPin(const Pin *pin) const; + const Pin *leafLoadPin(const Pin *pin) const; FILE *stream() const { return stream_; } @@ -239,7 +251,8 @@ protected: Instance *instance_; const char *filename_; const char *creator_; - bool compatible_; + bool map_hpins_; + bool native_; int digits_; bool no_timestamp_; bool top_instance_; diff --git a/search/FindRegister.cc b/search/FindRegister.cc index cf73b83a..c5ad4db0 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -144,9 +144,7 @@ FindRegVisitor::visitRegs(ClockSet *clks, Clock *clk = clk_iter.next(); FindRegClkPred clk_pred(clk, this); VertexSet visited_vertices; - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : clk->leafPins()) { Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); visitFanoutRegs(vertex, TimingSense::positive_unate, diff --git a/search/Genclks.cc b/search/Genclks.cc index 8161d700..ee603c78 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -154,9 +154,7 @@ Level Genclks::clkPinMaxLevel(Clock *clk) const { Level max_level = 0; - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : clk->leafPins()) { Vertex *vertex = srcPathVertex(pin); max_level = max(max_level, vertex->level()); } @@ -305,8 +303,8 @@ Genclks::ensureMaster(Clock *gclk) while (iter.hasNext()) { Vertex *vertex = iter.next(); Pin *pin = vertex->pin(); - if (sdc_->isVertexPinClock(pin)) { - ClockSet *master_clks = sdc_->findVertexPinClocks(pin); + if (sdc_->isLeafPinClock(pin)) { + ClockSet *master_clks = sdc_->findLeafPinClocks(pin); if (master_clks) { ClockSet::Iterator master_iter(master_clks); while (master_iter.hasNext()) { @@ -357,8 +355,8 @@ Genclks::ensureMaster(Clock *gclk) while (iter.hasNext()) { Vertex *vertex = iter.next(); Pin *pin = vertex->pin(); - if (sdc_->isVertexPinClock(pin)) { - ClockSet *master_clks = sdc_->findVertexPinClocks(pin); + if (sdc_->isLeafPinClock(pin)) { + ClockSet *master_clks = sdc_->findLeafPinClocks(pin); if (master_clks) { ClockSet::Iterator master_iter(master_clks); if (master_iter.hasNext()) { @@ -474,9 +472,7 @@ Genclks::seedClkVertices(Clock *clk, BfsBkwdIterator &iter, VertexSet *fanins) { - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : clk->leafPins()) { Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); fanins->insert(vertex); @@ -543,7 +539,7 @@ GenClkInsertionSearchPred::searchTo(const Vertex *to_vertex) return SearchPred0::searchTo(to_vertex) // Propagate through other generated clock roots but not regular // clock roots. - && !(!gclk_->vertexPins()->hasKey(to_pin) + && !(!gclk_->leafPins().hasKey(to_pin) && isNonGeneratedClkPin(to_pin)) && genclk_info_->fanins()->hasKey(const_cast(to_vertex)); } @@ -552,7 +548,7 @@ bool GenClkInsertionSearchPred::isNonGeneratedClkPin(const Pin *pin) const { const Sdc *sdc = sta_->sdc(); - ClockSet *clks = sdc->findVertexPinClocks(pin); + ClockSet *clks = sdc->findLeafPinClocks(pin); if (clks) { ClockSet::Iterator clk_iter(clks); while (clk_iter.hasNext()) { @@ -643,9 +639,7 @@ Genclks::findLatchFdbkEdges(const Clock *gclk, { Level gclk_level = genclk_info->gclkLevel(); EdgeSet *fdbk_edges = nullptr; - ClockVertexPinIterator pin_iter(gclk->masterClk()); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : gclk->masterClk()->leafPins()) { Vertex *vertex = graph_->pinDrvrVertex(pin); VertexSet path_vertices; VertexSet visited_vertices; @@ -717,9 +711,7 @@ Genclks::seedSrcPins(Clock *gclk, BfsFwdIterator &insert_iter) { Clock *master_clk = gclk->masterClk(); - ClockVertexPinIterator master_pin_iter(master_clk); - while (master_pin_iter.hasNext()) { - Pin *master_pin = master_pin_iter.next(); + for (Pin *master_pin : master_clk->leafPins()) { Vertex *vertex = graph_->pinDrvrVertex(master_pin); debugPrint1(debug_, "genclk", 2, " seed src pin %s\n", network_->pathName(master_pin)); @@ -950,9 +942,7 @@ Genclks::recordSrcPaths(Clock *gclk) bool invert = gclk->invert(); bool has_edges = gclk->edges() != nullptr; - ClockVertexPinIterator gclk_pin_iter(gclk); - while (gclk_pin_iter.hasNext()) { - Pin *gclk_pin = gclk_pin_iter.next(); + for (Pin *gclk_pin : gclk->leafPins()) { PathVertexRep *src_paths = new PathVertexRep[path_count]; genclk_src_paths_.insert(ClockPinPair(gclk, gclk_pin), src_paths); diff --git a/search/Power.cc b/search/Power.cc index 74d63a7a..deb7577a 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -422,7 +422,7 @@ Power::seedActivities(BfsFwdIterator &bfs) for (auto vertex : levelize_->roots()) { const Pin *pin = vertex->pin(); // Clock activities are baked in. - if (!sdc_->isVertexPinClock(pin) + if (!sdc_->isLeafPinClock(pin) && network_->direction(pin) != PortDirection::internal()) { debugPrint1(debug_, "power_activity", 3, "seed %s\n", vertex->name(network_)); diff --git a/search/Property.cc b/search/Property.cc index 00c53c6b..b263bc19 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -911,7 +911,7 @@ getProperty(Clock *clk, else if (stringEqual(property, "period")) return PropertyValue(sta->units()->timeUnit()->asString(clk->period(), 6)); else if (stringEqual(property, "sources")) - return PropertyValue(clk->pins()); + return PropertyValue(&clk->pins()); else if (stringEqual(property, "propagated")) return PropertyValue(clk->isPropagated() ? "1" : "0"); else diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 2655589d..5bdc0afd 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -1720,8 +1720,7 @@ ReportPath::pathFromClkPin(const Path *path, { Clock *clk = path->clock(search_); return clk - && clk->vertexPins() - && clk->vertexPins()->hasKey(const_cast(start_pin)); + && clk->leafPins().hasKey(const_cast(start_pin)); } void diff --git a/search/Search.cc b/search/Search.cc index 1afb22da..b032b98e 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -104,7 +104,7 @@ EvalPred::searchTo(const Vertex *to_vertex) const Sdc *sdc = sta_->sdc(); const Pin *pin = to_vertex->pin(); return SearchPred0::searchTo(to_vertex) - && !(sdc->isVertexPinClock(pin) + && !(sdc->isLeafPinClock(pin) && !sdc->isPathDelayInternalEndpoint(pin)); } @@ -868,9 +868,8 @@ Search::visitStartpoints(VertexVisitor *visitor) } delete pin_iter; - InputDelayVertexPinsIterator arrival_iter(sdc_); - while (arrival_iter.hasNext()) { - const Pin *pin = arrival_iter.next(); + for (auto iter : sdc_->inputDelayMap()) { + const Pin *pin = iter.first; // Already hit these. if (!network_->isTopLevelPort(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); @@ -879,10 +878,8 @@ Search::visitStartpoints(VertexVisitor *visitor) } } - for (auto clk : sdc_->clks()) { - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Clock *clk : sdc_->clks()) { + for (Pin *pin : clk->leafPins()) { // Already hit these. if (!network_->isTopLevelPort(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); @@ -1080,7 +1077,7 @@ ArrivalVisitor::visit(Vertex *vertex) vertex->name(sdc_network)); Pin *pin = vertex->pin(); // Don't clobber clock sources. - if (!sdc->isVertexPinClock(pin) + if (!sdc->isLeafPinClock(pin) // Unless it is an internal path delay endpoint. || sdc->isPathDelayInternalEndpoint(pin)) { tag_bldr_->init(vertex); @@ -1105,7 +1102,7 @@ ArrivalVisitor::visit(Vertex *vertex) // set_min/max_delay on internal pin. search->makeUnclkedPaths(vertex, true, tag_bldr_); if (sdc->isPathDelayInternalEndpoint(pin) - && sdc->isVertexPinClock(pin)) + && sdc->isLeafPinClock(pin)) // set_min/max_delay on internal pin also a clock src. Bizzaroland. // Re-seed the clock arrivals on top of the propagated paths. search->seedClkArrivals(pin, vertex, tag_bldr_); @@ -1392,9 +1389,7 @@ void Search::findClockVertices(VertexSet &vertices) { for (auto clk : sdc_->clks()) { - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : clk->leafPins()) { Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); vertices.insert(vertex); @@ -1416,7 +1411,7 @@ void Search::seedArrival(Vertex *vertex) { const Pin *pin = vertex->pin(); - if (sdc_->isVertexPinClock(pin)) { + if (sdc_->isLeafPinClock(pin)) { TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); genclks_->copyGenClkSrcPaths(vertex, &tag_bldr); @@ -1462,14 +1457,12 @@ Search::seedArrival(Vertex *vertex) } } -// Find all of the clock vertex pins. +// Find all of the clock leaf pins. void Search::findClkVertexPins(PinSet &clk_pins) { for (auto clk : sdc_->clks()) { - ClockVertexPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); + for (Pin *pin : clk->leafPins()) { clk_pins.insert(pin); } } @@ -1480,7 +1473,7 @@ Search::seedClkArrivals(const Pin *pin, Vertex *vertex, TagGroupBldr *tag_bldr) { - for (auto clk : *sdc_->findVertexPinClocks(pin)) { + for (auto clk : *sdc_->findLeafPinClocks(pin)) { debugPrint2(debug_, "search", 2, "arrival seed clk %s pin %s\n", clk->name(), network_->pathName(pin)); for (auto path_ap : corners_->pathAnalysisPts()) { @@ -1622,7 +1615,7 @@ Search::findRootVertices(VertexSet &vertices) { for (auto vertex : levelize_->roots()) { const Pin *pin = vertex->pin(); - if (!sdc_->isVertexPinClock(pin) + if (!sdc_->isLeafPinClock(pin) && !sdc_->hasInputDelay(pin) && !vertex->isConstant()) { vertices.insert(vertex); @@ -1648,7 +1641,7 @@ Search::isSegmentStart(const Pin *pin) { return (sdc_->isPathDelayInternalStartpoint(pin) || sdc_->isInputDelayInternal(pin)) - && !sdc_->isVertexPinClock(pin); + && !sdc_->isLeafPinClock(pin); } bool @@ -1668,10 +1661,9 @@ Search::seedInputArrivals(ClockSet *clks) { // Input arrivals can be on internal pins, so iterate over the pins // that have input arrivals rather than the top level input pins. - InputDelayVertexPinsIterator arrival_iter(sdc_); - while (arrival_iter.hasNext()) { - const Pin *pin = arrival_iter.next(); - if (!sdc_->isVertexPinClock(pin)) { + for (auto iter : sdc_->inputDelayMap()) { + const Pin *pin = iter.first; + if (!sdc_->isLeafPinClock(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); seedInputArrival(pin, vertex, clks); } @@ -1685,13 +1677,13 @@ Search::seedInputArrival(const Pin *pin, { bool has_arrival = false; // There can be multiple arrivals for a pin with wrt different clocks. - VertexPinInputDelayIterator arrival_iter(pin, sdc_); + LeafPinInputDelayIterator arrival_iter(pin, sdc_); TagGroupBldr tag_bldr(true, this); tag_bldr.init(vertex); while (arrival_iter.hasNext()) { InputDelay *input_delay = arrival_iter.next(); Clock *input_clk = input_delay->clock(); - ClockSet *pin_clks = sdc_->findVertexPinClocks(pin); + ClockSet *pin_clks = sdc_->findLeafPinClocks(pin); if (input_clk && wrt_clks->hasKey(input_clk) // Input arrivals wrt a clock source pin is the insertion // delay (source latency), but arrivals wrt other clocks @@ -1713,7 +1705,7 @@ Search::seedInputArrival(const Pin *pin, { if (sdc_->hasInputDelay(pin)) seedInputArrival1(pin, vertex, false, tag_bldr); - else if (!sdc_->isVertexPinClock(pin)) + else if (!sdc_->isLeafPinClock(pin)) // Seed inputs without set_input_delays. seedInputDelayArrival(pin, vertex, nullptr, false, tag_bldr); } @@ -1733,11 +1725,11 @@ Search::seedInputArrival1(const Pin *pin, TagGroupBldr *tag_bldr) { // There can be multiple arrivals for a pin with wrt different clocks. - VertexPinInputDelayIterator arrival_iter(pin, sdc_); + LeafPinInputDelayIterator arrival_iter(pin, sdc_); while (arrival_iter.hasNext()) { InputDelay *input_delay = arrival_iter.next(); Clock *input_clk = input_delay->clock(); - ClockSet *pin_clks = sdc_->findVertexPinClocks(pin); + ClockSet *pin_clks = sdc_->findLeafPinClocks(pin); // Input arrival wrt a clock source pin is the clock insertion // delay (source latency), but arrivals wrt other clocks // propagate. @@ -2088,7 +2080,7 @@ Search::pathPropagatedToClkSrc(const Pin *pin, // Clock source can have input arrivals from unrelated clock. && tag->inputDelay() == nullptr && sdc_->isPathDelayInternalEndpoint(pin)) { - ClockSet *clks = sdc_->findVertexPinClocks(pin); + ClockSet *clks = sdc_->findLeafPinClocks(pin); return clks && !clks->hasKey(tag->clock()); } diff --git a/search/Sta.cc b/search/Sta.cc index 49de3b4d..11c7906e 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -1154,11 +1154,8 @@ Sta::removeClockSlew(Clock *clk) void Sta::clockSlewChanged(Clock *clk) { - ClockPinIterator pin_iter(clk); - while (pin_iter.hasNext()) { - const Pin *pin = pin_iter.next(); + for (Pin *pin : clk->pins()) graph_delay_calc_->delayInvalid(pin); - } search_->arrivalsInvalid(); } @@ -2068,12 +2065,13 @@ Sta::constraintsChanged() void Sta::writeSdc(const char *filename, - bool compatible, + bool leaf, + bool native, bool no_timestamp, int digits) { sta::writeSdc(network_->topInstance(), filename, "write_sdc", - compatible, no_timestamp, digits, sdc_); + leaf, native, no_timestamp, digits, sdc_); } //////////////////////////////////////////////////////////////// diff --git a/search/Sta.hh b/search/Sta.hh index 1a0f8f1e..37eca39a 100644 --- a/search/Sta.hh +++ b/search/Sta.hh @@ -911,6 +911,9 @@ public: const MinMax *min_max, int digits); void writeSdc(const char *filename, + // Map hierarchical pins and instances to leaf pins and instances. + bool leaf, + // Replace non-sdc get functions with OpenSTA equivalents. bool native, bool no_timestamp, int digits); diff --git a/search/StaState.cc b/search/StaState.cc index e4cbaedc..80de7fa7 100644 --- a/search/StaState.cc +++ b/search/StaState.cc @@ -113,4 +113,16 @@ StaState::networkReader() const return dynamic_cast(network_); } +void +StaState::setReport(Report *report) +{ + report_ = report; +} + +void +StaState::setDebug(Debug *debug) +{ + debug_ = debug; +} + } // namespace diff --git a/search/StaState.hh b/search/StaState.hh index d74cdde5..75c02bb1 100644 --- a/search/StaState.hh +++ b/search/StaState.hh @@ -54,8 +54,10 @@ public: virtual ~StaState() {} Report *report() { return report_; } Report *report() const { return report_; } + void setReport(Report *report); Debug *debug() { return debug_; } Debug *debug() const { return debug_; } + void setDebug(Debug *debug); Units *units() { return units_; } Units *units() const { return units_; } Network *network() { return network_; } diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index df821857..5ce033c7 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -299,7 +299,7 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, bool &is_constrained) { const MinMax *min_max = path_ap->pathMinMax(); - VertexPinOutputDelayIterator delay_iter(pin, sdc_); + LeafPinOutputDelayIterator delay_iter(pin, sdc_); while (delay_iter.hasNext()) { OutputDelay *output_delay = delay_iter.next(); float margin; diff --git a/tcl/Sdc.tcl b/tcl/Sdc.tcl index 44e62491..56ccea29 100644 --- a/tcl/Sdc.tcl +++ b/tcl/Sdc.tcl @@ -123,11 +123,11 @@ proc source_ { filename echo verbose } { ################################################################ define_cmd_args "write_sdc" \ - {[-no_timestamp] [-digits digits] filename} + {[-map_hpins] [-no_timestamp] [-digits digits] filename} proc write_sdc { args } { parse_key_args "write_sdc" args keys {-digits -significant_digits} \ - flags {-compatible -no_timestamp} + flags {-map_hpins -compatible -no_timestamp} check_argc_eq1 "write_sdc" $args set digits 4 @@ -141,8 +141,9 @@ proc write_sdc { args } { set filename [file nativename [lindex $args 0]] set no_timestamp [info exists flags(-no_timestamp)] - set compatible [info exists flags(-native)] - write_sdc_cmd $filename $compatible $no_timestamp $digits + set map_hpins [info exists flags(-map_hpins)] + set native [expr ![info exists flags(-compatible)]] + write_sdc_cmd $filename $map_hpins $native $no_timestamp $digits } ################################################################ diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 079c0202..3d9afa8a 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -820,11 +820,6 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } -%typemap(out) ClockPinIterator* { - Tcl_Obj *obj = SWIG_NewInstanceObj($1,$1_descriptor, false); - Tcl_SetObjResult(interp, obj); -} - %typemap(out) ClockEdge* { Tcl_Obj *obj = SWIG_NewInstanceObj($1,$1_descriptor, false); Tcl_SetObjResult(interp, obj); @@ -1100,6 +1095,20 @@ using namespace sta; Tcl_SetObjResult(interp, list); } +%typemap(out) PinSet& { + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); + const PinSet *pins = $1; + if (pins) { + PinSet::ConstIterator pin_iter(pins); + while (pin_iter.hasNext()) { + Pin *pin = pin_iter.next(); + Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false); + Tcl_ListObjAppendElement(interp, list, obj); + } + } + Tcl_SetObjResult(interp, list); +} + %typemap(in) ClockSet* { $1 = tclListSet($input, SWIGTYPE_p_Clock, interp); } @@ -1753,13 +1762,6 @@ private: ~ClockIterator(); }; -class ClockPinIterator -{ -private: - ClockPinIterator(); - ~ClockPinIterator(); -}; - class ClockEdge { private: @@ -4712,12 +4714,13 @@ disabled_edges_sorted() void write_sdc_cmd(const char *filename, + bool leaf, bool compatible, bool no_timestamp, int digits) { cmdLinkedNetwork(); - Sta::sta()->writeSdc(filename, compatible, no_timestamp, digits); + Sta::sta()->writeSdc(filename, leaf, compatible, no_timestamp, digits); } void @@ -5661,12 +5664,11 @@ void finish() { delete self; } float period() { return self->period(); } FloatSeq *waveform() { return self->waveform(); } float time(TransRiseFall *tr) { return self->edge(tr)->time(); } -ClockPinIterator *pin_iterator() { return new ClockPinIterator(self); } bool is_generated() { return self->isGenerated(); } bool waveform_valid() { return self->waveformValid(); } bool is_virtual() { return self->isVirtual(); } bool is_propagated() { return self->isPropagated(); } -PinSet *sources() { return self->pins(); } +PinSet &sources() { return self->pins(); } float slew(const TransRiseFall *tr, @@ -5689,12 +5691,6 @@ Clock *next() { return self->next(); } void finish() { delete self; } } -%extend ClockPinIterator { -bool has_next() { return self->hasNext(); } -Pin *next() { return self->next(); } -void finish() { delete self; } -} - %extend Vertex { Pin *pin() { return self->pin(); } bool is_bidirect_driver() { return self->isBidirectDriver(); } diff --git a/util/Set.hh b/util/Set.hh index d0736f49..74fe3db8 100644 --- a/util/Set.hh +++ b/util/Set.hh @@ -71,6 +71,9 @@ public: this->clear(); } + static bool + intersects(std::set &set1, + std::set &set2); static bool intersects(std::set *set1, std::set *set2); @@ -170,6 +173,14 @@ Set::isSubset(const std::set *set2) } } +template +bool +Set::intersects(std::set &set1, + std::set &set2) +{ + return intersects(&set1, &set2); +} + template bool Set::intersects(std::set *set1,