diff --git a/.gitignore b/.gitignore index 97cf494c..c6eddea7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ TAGS *~ \#*# +.#* .~lock.*# .DS_Store Makefile diff --git a/sdc/Clock.cc b/sdc/Clock.cc index b3a7420a..4c7ffc14 100644 --- a/sdc/Clock.cc +++ b/sdc/Clock.cc @@ -90,6 +90,7 @@ Clock::setPins(PinSet *pins, { if (pins) pins_ = *pins; + delete pins; makeLeafPins(network); } diff --git a/sdc/PortDelay.cc b/sdc/PortDelay.cc index 9d7e25e9..f3393c1f 100644 --- a/sdc/PortDelay.cc +++ b/sdc/PortDelay.cc @@ -82,97 +82,21 @@ InputDelay::InputDelay(Pin *pin, int index, Network *network) : PortDelay(pin, clk_edge, ref_pin), - next_(nullptr), index_(index) { findLeafLoadPins(pin, network, &leaf_pins_); } -void -InputDelay::setNext(InputDelay *next) -{ - next_ = next; -} - OutputDelay::OutputDelay(Pin *pin, ClockEdge *clk_edge, Pin *ref_pin, Network *network) : - PortDelay(pin, clk_edge, ref_pin), - next_(nullptr) + PortDelay(pin, clk_edge, ref_pin) { if (network) findLeafDriverPins(pin, network, &leaf_pins_); } -void -OutputDelay::setNext(OutputDelay *next) -{ - next_ = next; -} - -//////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////// - -PinInputDelayIterator::PinInputDelayIterator(const Pin *pin, - const Sdc *sdc) -{ - next_ = sdc->input_delay_map_.findKey(pin); -} - -bool -PinInputDelayIterator::hasNext() -{ - return next_ != nullptr; -} - -InputDelay * -PinInputDelayIterator::next() -{ - InputDelay *next = next_; - if (next) - next_ = next_->next(); - return next; -} - -LeafPinInputDelayIterator::LeafPinInputDelayIterator(const Pin *vertex_pin, - const Sdc *sdc) : - PinInputDelayIterator() -{ - next_ = sdc->input_delay_leaf_pin_map_.findKey(vertex_pin); -} - -//////////////////////////////////////////////////////////////// - -PinOutputDelayIterator::PinOutputDelayIterator(const Pin *pin, - const Sdc *sdc) -{ - next_ = sdc->output_delay_map_.findKey(pin); -} - -bool -PinOutputDelayIterator::hasNext() -{ - return next_ != nullptr; -} - -OutputDelay * -PinOutputDelayIterator::next() -{ - OutputDelay *next = next_; - if (next) - next_ = next_->next(); - return next; -} - -LeafPinOutputDelayIterator::LeafPinOutputDelayIterator(const Pin *vertex_pin, - const Sdc *sdc) : - PinOutputDelayIterator() -{ - next_ = sdc->output_delay_leaf_pin_map_.findKey(vertex_pin); -} - //////////////////////////////////////////////////////////////// PortDelayLess::PortDelayLess(const Network *network) : diff --git a/sdc/PortDelay.hh b/sdc/PortDelay.hh index d2e5912c..18ae11a7 100644 --- a/sdc/PortDelay.hh +++ b/sdc/PortDelay.hh @@ -71,11 +71,6 @@ protected: Pin *ref_pin, int index, Network *network); - InputDelay *next() { return next_; } - - // Linked list of port delays on the same pin wrt different clocks. - InputDelay *next_; - void setNext(InputDelay *next); private: DISALLOW_COPY_AND_ASSIGN(InputDelay); @@ -83,8 +78,6 @@ private: int index_; friend class Sdc; - friend class PinInputDelayIterator; - friend class InputDelayIterator; }; class OutputDelay : public PortDelay @@ -96,70 +89,11 @@ protected: ClockEdge *clk_edge, Pin *ref_pin, Network *network); - OutputDelay *next() { return next_; } - void setNext(OutputDelay *next); - - // Linked list of port delays on the same port wrt different clocks. - OutputDelay *next_; private: DISALLOW_COPY_AND_ASSIGN(OutputDelay); friend class Sdc; - friend class PinOutputDelayIterator; - friend class OutputDelayIterator; -}; - -class PinInputDelayIterator : public Iterator -{ -public: - PinInputDelayIterator(const Pin *pin, - const Sdc *sdc); - virtual bool hasNext(); - virtual InputDelay *next(); - -protected: - PinInputDelayIterator() {} - - InputDelay *next_; - - DISALLOW_COPY_AND_ASSIGN(PinInputDelayIterator); -}; - -class LeafPinInputDelayIterator : public PinInputDelayIterator -{ -public: - LeafPinInputDelayIterator(const Pin *pin, - const Sdc *sdc); - -private: - DISALLOW_COPY_AND_ASSIGN(LeafPinInputDelayIterator); -}; - -class PinOutputDelayIterator : public Iterator -{ -public: - PinOutputDelayIterator(const Pin *pin, - const Sdc *sdc); - virtual bool hasNext(); - virtual OutputDelay *next(); - -protected: - PinOutputDelayIterator() {} - - OutputDelay *next_; - - DISALLOW_COPY_AND_ASSIGN(PinOutputDelayIterator); -}; - -class LeafPinOutputDelayIterator : public PinOutputDelayIterator -{ -public: - LeafPinOutputDelayIterator(const Pin *pin, - const Sdc *sdc); - -private: - DISALLOW_COPY_AND_ASSIGN(LeafPinOutputDelayIterator); }; // Prediate used to sort port delays. diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 70a1f83d..8c2dd03d 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -167,12 +167,14 @@ Sdc::clear() data_checks_to_map_.clear(); input_delays_.clear(); - input_delay_map_.clear(); + input_delay_pin_map_.clear(); input_delay_index_ = 0; input_delay_ref_pin_map_.clear(); input_delay_leaf_pin_map_.clear(); input_delay_internal_pin_map_.clear(); - output_delay_map_.clear(); + + output_delays_.clear(); + output_delay_pin_map_.clear(); output_delay_leaf_pin_map_.clear(); port_slew_limit_map_.clear(); @@ -283,32 +285,18 @@ Sdc::deleteConstraints() delete checks; } - InputDelayMap::Iterator input_iter(input_delay_map_); - while (input_iter.hasNext()) { - InputDelay *input_delay = input_iter.next(); - while (input_delay) { - InputDelay *next = input_delay->next(); - delete input_delay; - input_delay = next; - } - } + for (auto input_delay : input_delays_) + delete input_delay; + input_delay_pin_map_.deleteContents(); + input_delay_leaf_pin_map_.deleteContents(); + input_delay_internal_pin_map_.deleteContents(); - InputDelayRefPinMap::Iterator input_set_iter(input_delay_ref_pin_map_); - while (input_set_iter.hasNext()) { - InputDelaySet *input_delays = input_set_iter.next(); - delete input_delays; - } - input_delay_internal_pin_map_.deleteContents(); + for (auto output_delay : output_delays_) + delete output_delay; + output_delay_pin_map_.deleteContents(); + output_delay_ref_pin_map_.deleteContents(); + output_delay_leaf_pin_map_.deleteContents(); - OutputDelayMap::Iterator output_iter(output_delay_map_); - while (output_iter.hasNext()) { - OutputDelay *output_delay = output_iter.next(); - while (output_delay) { - OutputDelay *next = output_delay->next(); - delete output_delay; - output_delay = next; - } - } clk_hpin_disables_.deleteContentsClear(); clk_hpin_disables_valid_ = false; @@ -442,8 +430,8 @@ Sdc::isConstrained(const Pin *pin) const || pin_clk_gating_check_map_.hasKey(pin) || data_checks_from_map_.hasKey(pin) || data_checks_to_map_.hasKey(pin) - || input_delay_map_.hasKey(pin) - || output_delay_map_.hasKey(pin) + || input_delay_pin_map_.hasKey(pin) + || output_delay_pin_map_.hasKey(pin) || port_slew_limit_map_.hasKey(port) || pin_cap_limit_map_.hasKey(pin1) || port_cap_limit_map_.hasKey(port) @@ -2772,12 +2760,16 @@ Sdc::setInputDelay(Pin *pin, float delay) { ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; - InputDelay *input_delay = ensureInputDelay(pin, clk_edge, ref_pin); - RiseFallMinMax *delays = input_delay->delays(); - if (add) + InputDelay *input_delay = findInputDelay(pin, clk_edge, ref_pin); + if (input_delay == nullptr) + input_delay = makeInputDelay(pin, clk_edge, ref_pin); + if (add) { + RiseFallMinMax *delays = input_delay->delays(); delays->mergeValue(tr, min_max, delay); + } else { deleteInputDelays(pin, input_delay); + RiseFallMinMax *delays = input_delay->delays(); delays->setValue(tr, min_max, delay); } input_delay->setSourceLatencyIncluded(source_latency_included); @@ -2785,35 +2777,45 @@ Sdc::setInputDelay(Pin *pin, } InputDelay * -Sdc::ensureInputDelay(Pin *pin, - ClockEdge *clk_edge, - Pin *ref_pin) +Sdc::makeInputDelay(Pin *pin, + ClockEdge *clk_edge, + Pin *ref_pin) { - InputDelay *input_delay = findInputDelay(pin, clk_edge, ref_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) { - InputDelaySet *ref_inputs = input_delay_ref_pin_map_.findKey(ref_pin); - if (ref_inputs == nullptr) { - ref_inputs = new InputDelaySet; - input_delay_ref_pin_map_[ref_pin] = ref_inputs; - } - ref_inputs->insert(input_delay); + InputDelay *input_delay = new InputDelay(pin, clk_edge, ref_pin, + input_delay_index_++, + network_); + input_delays_.insert(input_delay); + InputDelaySet *inputs = input_delay_pin_map_.findKey(pin); + if (inputs == nullptr) { + inputs = new InputDelaySet; + input_delay_pin_map_[pin] = inputs; + } + inputs->insert(input_delay); + + if (ref_pin) { + InputDelaySet *ref_inputs = input_delay_ref_pin_map_.findKey(ref_pin); + if (ref_inputs == nullptr) { + ref_inputs = new InputDelaySet; + input_delay_ref_pin_map_[ref_pin] = ref_inputs; } - 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) { - input_set = new InputDelaySet; - input_delay_internal_pin_map_[vpin] = input_set; - } - input_set->insert(input_delay); + ref_inputs->insert(input_delay); + } + + for (Pin *lpin : input_delay->leafPins()) { + InputDelaySet *leaf_inputs = input_delay_leaf_pin_map_[lpin]; + if (leaf_inputs == nullptr) { + leaf_inputs = new InputDelaySet; + input_delay_leaf_pin_map_[lpin] = leaf_inputs; + } + leaf_inputs->insert(input_delay); + + if (!network_->isTopLevelPort(lpin)) { + InputDelaySet *internal_inputs = input_delay_internal_pin_map_[lpin]; + if (internal_inputs == nullptr) { + internal_inputs = new InputDelaySet; + input_delay_internal_pin_map_[pin] = internal_inputs; } + internal_inputs->insert(input_delay); } } return input_delay; @@ -2824,12 +2826,13 @@ Sdc::findInputDelay(const Pin *pin, ClockEdge *clk_edge, Pin *ref_pin) { - for (InputDelay *input_delay = input_delay_map_.findKey(pin); - input_delay; - input_delay = input_delay->next()) { - if (input_delay->clkEdge() == clk_edge - && input_delay->refPin() == ref_pin) - return input_delay; + InputDelaySet *inputs = input_delay_pin_map_.findKey(pin); + if (inputs) { + for (InputDelay *input_delay : *inputs) { + if (input_delay->clkEdge() == clk_edge + && input_delay->refPin() == ref_pin) + return input_delay; + } } return nullptr; } @@ -2855,27 +2858,12 @@ void Sdc::deleteInputDelays(Pin *pin, InputDelay *except) { - InputDelay *input_delay = input_delay_map_.findKey(pin); - while (input_delay) { - InputDelay *next = input_delay->next(); - if (input_delay == except) - input_delay->setNext(nullptr); - else { - delete input_delay; - input_delays_.erase(input_delay); - } - input_delay = next; - } - input_delay_map_[pin] = 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) { - input_delays->clear(); - input_delays->insert(except); - } + InputDelaySet *input_delays = input_delay_pin_map_[pin]; + InputDelaySet::Iterator iter(input_delays); + while (iter.hasNext()) { + InputDelay *input_delay = iter.next(); + if (input_delay != except) + deleteInputDelay(input_delay); } } @@ -2885,70 +2873,48 @@ Sdc::refPinInputDelays(const Pin *ref_pin) const return input_delay_ref_pin_map_.findKey(ref_pin); } -PinInputDelayIterator * -Sdc::inputDelayIterator(const Pin *pin) const +InputDelaySet * +Sdc::inputDelaysLeafPin(const Pin *leaf_pin) { - return new PinInputDelayIterator(pin, this); + return input_delay_leaf_pin_map_.findKey(leaf_pin); } bool Sdc::hasInputDelay(const Pin *leaf_pin) const { - return input_delay_leaf_pin_map_.findKey(leaf_pin) != nullptr; + InputDelaySet *input_delays = input_delay_leaf_pin_map_.findKey(leaf_pin); + return input_delays && !input_delays->empty(); } bool Sdc::isInputDelayInternal(const Pin *pin) const { - InputDelaySet *input_delays = - input_delay_internal_pin_map_.findKey(pin); - return input_delays && !input_delays->empty(); + return input_delay_internal_pin_map_.hasKey(pin); } - - void Sdc::deleteInputDelaysReferencing(Clock *clk) { - Vector refs; - for (InputDelay *input_delay : input_delays_) { + InputDelaySet::Iterator iter(input_delays_); + while (iter.hasNext()) { + InputDelay *input_delay = iter.next(); if (input_delay->clock() == clk) - 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) { - InputDelay *next = input_delay->next(); - if (next) - input_delay_map_[pin] = next; - else - input_delay_map_.erase(pin); - head = next; - } - else { - for (InputDelay *delay = head; delay; ) { - InputDelay *next = delay->next(); - if (next == input_delay) { - delay->setNext(input_delay->next()); - break; - } - delay = next; - } - } - for (Pin *vpin : input_delay->leafPins()) { - if (head) - input_delay_leaf_pin_map_[vpin] = head; - else - input_delay_leaf_pin_map_.erase(vpin); + Pin *pin = input_delay->pin(); + InputDelaySet *inputs = input_delay_pin_map_[pin]; + inputs->erase(input_delay); + + for (Pin *lpin : input_delay->leafPins()) { + InputDelaySet *inputs = input_delay_leaf_pin_map_[lpin]; + inputs->erase(input_delay); } delete input_delay; @@ -2969,53 +2935,75 @@ Sdc::setOutputDelay(Pin *pin, float delay) { ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; - OutputDelay *output_delay = ensureOutputDelay(pin, clk_edge, ref_pin); - RiseFallMinMax *delays = output_delay->delays(); - if (add) + OutputDelay *output_delay = findOutputDelay(pin, clk_edge, ref_pin); + if (output_delay == nullptr) + output_delay = makeOutputDelay(pin, clk_edge, ref_pin); + if (add) { + RiseFallMinMax *delays = output_delay->delays(); delays->mergeValue(tr, min_max, delay); + } else { deleteOutputDelays(pin, output_delay); + RiseFallMinMax *delays = output_delay->delays(); delays->setValue(tr, min_max, delay); } output_delay->setSourceLatencyIncluded(source_latency_included); output_delay->setNetworkLatencyIncluded(network_latency_included); } -OutputDelay * -Sdc::ensureOutputDelay(Pin *pin, - ClockEdge *clk_edge, - Pin *ref_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; - for (Pin *vpin : output_delay->leafPins()) { - output_delay_leaf_pin_map_[vpin] = output_delay; - if (graph_) - annotateGraphConstrained(vpin, true); - } - } - return output_delay; -} - OutputDelay * Sdc::findOutputDelay(const Pin *pin, ClockEdge *clk_edge, Pin *ref_pin) { - for (OutputDelay *output_delay = output_delay_map_.findKey(pin); - output_delay; - output_delay = output_delay->next()) { - if (output_delay->clkEdge() == clk_edge - && output_delay->refPin() == ref_pin) - return output_delay; + OutputDelaySet *outputs = output_delay_pin_map_.findKey(pin); + if (outputs) { + for (OutputDelay *output_delay : *outputs) { + if (output_delay->clkEdge() == clk_edge + && output_delay->refPin() == ref_pin) + return output_delay; + } } return nullptr; } +OutputDelay * +Sdc::makeOutputDelay(Pin *pin, + ClockEdge *clk_edge, + Pin *ref_pin) +{ + OutputDelay *output_delay = new OutputDelay(pin, clk_edge, ref_pin, + network_); + output_delays_.insert(output_delay); + OutputDelaySet *outputs = output_delay_pin_map_.findKey(pin); + if (outputs == nullptr) { + outputs = new OutputDelaySet; + output_delay_pin_map_[pin] = outputs; + } + outputs->insert(output_delay); + + if (ref_pin) { + OutputDelaySet *ref_outputs = output_delay_ref_pin_map_.findKey(ref_pin); + if (ref_outputs == nullptr) { + ref_outputs = new OutputDelaySet; + output_delay_ref_pin_map_[ref_pin] = ref_outputs; + } + ref_outputs->insert(output_delay); + } + + for (Pin *lpin : output_delay->leafPins()) { + OutputDelaySet *leaf_outputs = output_delay_leaf_pin_map_[lpin]; + if (leaf_outputs == nullptr) { + leaf_outputs = new OutputDelaySet; + output_delay_leaf_pin_map_[lpin] = leaf_outputs; + } + leaf_outputs->insert(output_delay); + if (graph_) + annotateGraphConstrained(lpin, true); + } + return output_delay; +} + void Sdc::removeOutputDelay(Pin *pin, TransRiseFallBoth *tr, @@ -3024,9 +3012,9 @@ Sdc::removeOutputDelay(Pin *pin, MinMaxAll *min_max) { ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr; - InputDelay *input_delay = findInputDelay(pin, clk_edge, nullptr); - if (input_delay) { - RiseFallMinMax *delays = input_delay->delays(); + OutputDelay *output_delay = findOutputDelay(pin, clk_edge, nullptr); + if (output_delay) { + RiseFallMinMax *delays = output_delay->delays(); delays->removeValue(tr, min_max); } } @@ -3035,24 +3023,19 @@ void Sdc::deleteOutputDelays(Pin *pin, OutputDelay *except) { - OutputDelay *output_delay = output_delay_map_.findKey(pin); - while (output_delay) { - OutputDelay *next = output_delay->next(); - if (output_delay == except) - output_delay->setNext(nullptr); - else - delete output_delay; - output_delay = next; + OutputDelaySet *output_delays = output_delay_pin_map_[pin]; + OutputDelaySet::Iterator iter(output_delays); + while (iter.hasNext()) { + OutputDelay *output_delay = iter.next(); + if (output_delay != except) + deleteOutputDelay(output_delay); } - output_delay_map_[pin] = except; - for (Pin *vpin : except->leafPins()) - output_delay_leaf_pin_map_[vpin] = except; } -PinOutputDelayIterator * -Sdc::outputDelayIterator(const Pin *pin) const +OutputDelaySet * +Sdc::outputDelaysLeafPin(const Pin *leaf_pin) { - return new PinOutputDelayIterator(pin, this); + return output_delay_leaf_pin_map_.findKey(leaf_pin); } bool @@ -3064,45 +3047,26 @@ Sdc::hasOutputDelay(const Pin *leaf_pin) const void Sdc::deleteOutputDelaysReferencing(Clock *clk) { - Vector refs; - for (OutputDelay *output_delay : output_delays_) { + OutputDelaySet::Iterator iter(output_delays_); + while (iter.hasNext()) { + OutputDelay *output_delay = iter.next(); if (output_delay->clock() == clk) - refs.push_back(output_delay); + deleteOutputDelay(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(); - if (next) - output_delay_map_[pin] = next; - else - output_delay_map_.erase(pin); - head = next; - } - else { - for (OutputDelay *delay = head; delay; ) { - OutputDelay *next = delay->next(); - if (next == output_delay) { - delay->setNext(output_delay->next()); - break; - } - delay = next; - } - } - for (Pin *vpin : output_delay->leafPins()) { - if (head) - output_delay_leaf_pin_map_[vpin] = head; - else - output_delay_leaf_pin_map_.erase(vpin); + Pin *pin = output_delay->pin(); + OutputDelaySet *outputs = output_delay_pin_map_[pin]; + outputs->erase(output_delay); + + for (Pin *lpin : output_delay->leafPins()) { + OutputDelaySet *outputs = output_delay_leaf_pin_map_[lpin]; + outputs->erase(output_delay); } delete output_delay; @@ -6345,14 +6309,9 @@ Sdc::setEdgeDisabledInstFrom(Pin *from_pin, void Sdc::annotateGraphOutputDelays(bool annotate) { - OutputDelayMap::Iterator output_iter(output_delay_map_); - while (output_iter.hasNext()) { - OutputDelay *output_delay = output_iter.next(); - while (output_delay) { - for (Pin *vpin : output_delay->leafPins()) - annotateGraphConstrained(vpin, annotate); - output_delay = output_delay->next(); - } + for (OutputDelay *output_delay : output_delays_) { + for (Pin *lpin : output_delay->leafPins()) + annotateGraphConstrained(lpin, annotate); } } diff --git a/sdc/Sdc.hh b/sdc/Sdc.hh index 9eac9f83..6369994c 100644 --- a/sdc/Sdc.hh +++ b/sdc/Sdc.hh @@ -38,8 +38,6 @@ namespace sta { class OperatingConditions; -class PinInputDelayIterator; -class PinOutputDelayIterator; class PortExtCap; class ClockGatingCheck; class InputDriveCell; @@ -106,12 +104,9 @@ public: typedef Map ClockNameMap; typedef UnorderedMap ClockPinMap; typedef Set InputDelaySet; -typedef Map InputDelayMap; -typedef Set InputDelaySet; -typedef Map InputDelayRefPinMap; -typedef Map InputDelayInternalPinMap; +typedef Map InputDelaysPinMap; typedef Set OutputDelaySet; -typedef Map OutputDelayMap; +typedef Map OutputDelaysPinMap; // Use HashSet so no read lock is required. typedef HashSet CycleAcctingSet; typedef Set InstanceSet; @@ -817,13 +812,7 @@ public: void setUseDefaultArrivalClock(bool enable); // STA interface. - InputDelay *ensureInputDelay(Pin *pin, - ClockEdge *clk_edge, - Pin *ref_pin); InputDelaySet *refPinInputDelays(const Pin *ref_pin) const; - OutputDelay *ensureOutputDelay(Pin *pin, - ClockEdge *clk_edge, - Pin *ref_pin); LogicValueMap *logicValues() { return &logic_value_map_; } LogicValueMap *caseLogicValues() { return &case_value_map_; } // Returns nullptr if set_operating_conditions has not been called. @@ -892,18 +881,23 @@ public: const ClockEdge *tgt); // Report clock to clock relationships that exceed max_cycle_count. void reportClkToClkMaxCycleWarnings(); + 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; + const InputDelaysPinMap &inputDelayPinMap() const { return input_delay_pin_map_; } + // Input delays on leaf_pin. + InputDelaySet *inputDelaysLeafPin(const Pin *leaf_pin); 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; + const OutputDelaySet &outputDelays() const { return output_delays_; } - // Iterate over the output delays on pin (which may be hierarchical). - PinOutputDelayIterator *outputDelayIterator(const Pin *pin) const; + // Pin -> output delays. + const OutputDelaysPinMap &outputDelayPinMap() const { return output_delay_pin_map_; } + // Output delays on leaf_pin. + OutputDelaySet *outputDelaysLeafPin(const Pin *leaf_pin); bool hasOutputDelay(const Pin *leaf_pin) const; + PortExtCap *portExtCap(Port *port) const; bool hasPortExtCap(Port *port) const; void portExtCap(Port *port, @@ -1168,6 +1162,9 @@ protected: InputDelay *findInputDelay(const Pin *pin, ClockEdge *clk_edge, Pin *ref_pin); + InputDelay *makeInputDelay(Pin *pin, + ClockEdge *clk_edge, + Pin *ref_pin); void deleteInputDelays(Pin *pin, InputDelay *except); void deleteInputDelaysReferencing(Clock *clk); @@ -1175,6 +1172,9 @@ protected: OutputDelay *findOutputDelay(const Pin *pin, ClockEdge *clk_edge, Pin *ref_pin); + OutputDelay *makeOutputDelay(Pin *pin, + ClockEdge *clk_edge, + Pin *ref_pin); void deleteOutputDelays(Pin *pin, OutputDelay *except); void deleteOutputDelaysReferencing(Clock *clk); void deleteOutputDelay(OutputDelay *output_delay); @@ -1313,17 +1313,21 @@ protected: std::mutex cycle_acctings_lock_; DataChecksMap data_checks_from_map_; DataChecksMap data_checks_to_map_; + InputDelaySet input_delays_; - InputDelayMap input_delay_map_; + InputDelaysPinMap input_delay_pin_map_; int input_delay_index_; - InputDelayRefPinMap input_delay_ref_pin_map_; + InputDelaysPinMap input_delay_ref_pin_map_; // Input delays on hierarchical pins are indexed by the load pins. - InputDelayMap input_delay_leaf_pin_map_; - InputDelayInternalPinMap input_delay_internal_pin_map_; + InputDelaysPinMap input_delay_leaf_pin_map_; + InputDelaysPinMap input_delay_internal_pin_map_; + OutputDelaySet output_delays_; - OutputDelayMap output_delay_map_; + OutputDelaysPinMap output_delay_pin_map_; + OutputDelaysPinMap output_delay_ref_pin_map_; // Output delays on hierarchical pins are indexed by the load pins. - OutputDelayMap output_delay_leaf_pin_map_; + OutputDelaysPinMap output_delay_leaf_pin_map_; + PortSlewLimitMap port_slew_limit_map_; PinSlewLimitMap pin_slew_limit_map_; CellSlewLimitMap cell_slew_limit_map_; @@ -1420,10 +1424,6 @@ private: friend class FindNetCaps; friend class ClockGroupIterator; friend class GroupPathIterator; - friend class PinInputDelayIterator; - friend class LeafPinInputDelayIterator; - friend class PinOutputDelayIterator; - friend class LeafPinOutputDelayIterator; }; class ClockIterator : public ClockSeq::Iterator diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index 8bf8a8b1..172bd305 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -247,11 +247,12 @@ CheckTiming::checkUnconstraintedOutputs(PinSet &unconstrained_ends) bool CheckTiming::hasClkedDepature(Pin *pin) { - PinOutputDelayIterator delay_iter(pin, sdc_); - while (delay_iter.hasNext()) { - OutputDelay *output_delay = delay_iter.next(); - if (output_delay->clkEdge() != nullptr) - return true; + OutputDelaySet *output_delays = sdc_->outputDelaysLeafPin(pin); + if (output_delays) { + for (OutputDelay *output_delay : *output_delays) { + if (output_delay->clkEdge() != nullptr) + return true; + } } return false; } diff --git a/search/Search.cc b/search/Search.cc index b032b98e..880491f7 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -868,7 +868,7 @@ Search::visitStartpoints(VertexVisitor *visitor) } delete pin_iter; - for (auto iter : sdc_->inputDelayMap()) { + for (auto iter : sdc_->inputDelayPinMap()) { const Pin *pin = iter.first; // Already hit these. if (!network_->isTopLevelPort(pin)) { @@ -1332,7 +1332,7 @@ ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin) InputDelaySet *input_delays = sdc->refPinInputDelays(ref_pin); if (input_delays) { const Graph *graph = sta_->graph(); - for (auto input_delay : *input_delays) { + for (InputDelay *input_delay : *input_delays) { const Pin *pin = input_delay->pin(); Vertex *vertex, *bidirect_drvr_vertex; graph->pinVertices(pin, vertex, bidirect_drvr_vertex); @@ -1661,7 +1661,7 @@ 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. - for (auto iter : sdc_->inputDelayMap()) { + for (auto iter : sdc_->inputDelayPinMap()) { const Pin *pin = iter.first; if (!sdc_->isLeafPinClock(pin)) { Vertex *vertex = graph_->pinDrvrVertex(pin); @@ -1677,25 +1677,26 @@ Search::seedInputArrival(const Pin *pin, { bool has_arrival = false; // There can be multiple arrivals for a pin with wrt different clocks. - 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_->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 - // propagate. - && (pin_clks == nullptr - || !pin_clks->hasKey(input_clk))) { - seedInputDelayArrival(pin, vertex, input_delay, false, &tag_bldr); - has_arrival = true; + InputDelaySet *input_delays = sdc_->inputDelaysLeafPin(pin); + if (input_delays) { + for (InputDelay *input_delay : *input_delays) { + Clock *input_clk = input_delay->clock(); + 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 + // propagate. + && (pin_clks == nullptr + || !pin_clks->hasKey(input_clk))) { + seedInputDelayArrival(pin, vertex, input_delay, false, &tag_bldr); + has_arrival = true; + } } + if (has_arrival) + setVertexArrivals(vertex, &tag_bldr); } - if (has_arrival) - setVertexArrivals(vertex, &tag_bldr); } void @@ -1725,18 +1726,19 @@ Search::seedInputArrival1(const Pin *pin, TagGroupBldr *tag_bldr) { // There can be multiple arrivals for a pin with wrt different clocks. - 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_->findLeafPinClocks(pin); - // Input arrival wrt a clock source pin is the clock insertion - // delay (source latency), but arrivals wrt other clocks - // propagate. - if (pin_clks == nullptr - || !pin_clks->hasKey(input_clk)) - seedInputDelayArrival(pin, vertex, input_delay, is_segment_start, - tag_bldr); + InputDelaySet *input_delays = sdc_->inputDelaysLeafPin(pin); + if (input_delays) { + for (InputDelay *input_delay : *input_delays) { + Clock *input_clk = input_delay->clock(); + 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. + if (pin_clks == nullptr + || !pin_clks->hasKey(input_clk)) + seedInputDelayArrival(pin, vertex, input_delay, is_segment_start, + tag_bldr); + } } } diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index 5ce033c7..f598f637 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -299,36 +299,37 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin, bool &is_constrained) { const MinMax *min_max = path_ap->pathMinMax(); - LeafPinOutputDelayIterator delay_iter(pin, sdc_); - while (delay_iter.hasNext()) { - OutputDelay *output_delay = delay_iter.next(); - float margin; - bool exists; - output_delay->delays()->value(end_tr, min_max, margin, exists); - if (exists) { - const Pin *ref_pin = output_delay->refPin(); - ClockEdge *tgt_clk_edge = output_delay->clkEdge(); - if (!filtered - || search_->matchesFilter(path, tgt_clk_edge)) { - if (ref_pin) { - Clock *tgt_clk = output_delay->clock(); - Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin); - TransRiseFall *ref_tr = output_delay->refTransition(); - VertexPathIterator ref_path_iter(ref_vertex,ref_tr,path_ap,this); - while (ref_path_iter.hasNext()) { - PathVertex *ref_path = ref_path_iter.next(); - if (ref_path->isClock(this) - && (tgt_clk == nullptr - || ref_path->clock(this) == tgt_clk)) - visitOutputDelayEnd1(output_delay, pin, path, end_tr, - ref_path->clkEdge(this), ref_path, min_max, - visitor, is_constrained); + OutputDelaySet *output_delays = sdc_->outputDelaysLeafPin(pin); + if (output_delays) { + for (OutputDelay *output_delay : *output_delays) { + float margin; + bool exists; + output_delay->delays()->value(end_tr, min_max, margin, exists); + if (exists) { + const Pin *ref_pin = output_delay->refPin(); + ClockEdge *tgt_clk_edge = output_delay->clkEdge(); + if (!filtered + || search_->matchesFilter(path, tgt_clk_edge)) { + if (ref_pin) { + Clock *tgt_clk = output_delay->clock(); + Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin); + TransRiseFall *ref_tr = output_delay->refTransition(); + VertexPathIterator ref_path_iter(ref_vertex,ref_tr,path_ap,this); + while (ref_path_iter.hasNext()) { + PathVertex *ref_path = ref_path_iter.next(); + if (ref_path->isClock(this) + && (tgt_clk == nullptr + || ref_path->clock(this) == tgt_clk)) + visitOutputDelayEnd1(output_delay, pin, path, end_tr, + ref_path->clkEdge(this), ref_path, min_max, + visitor, is_constrained); + } } + else + visitOutputDelayEnd1(output_delay, pin, path, end_tr, + tgt_clk_edge, nullptr, min_max, + visitor, is_constrained); } - else - visitOutputDelayEnd1(output_delay, pin, path, end_tr, - tgt_clk_edge, nullptr, min_max, - visitor, is_constrained); } } }