diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index 8dbcfe47..2a6ad5e2 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -692,33 +692,31 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex, || (vertex->isBidirectDriver() && network_->isTopLevelPort(pin))) seedRootSlew(vertex, arc_delay_calc); - else { - if (network_->isLeaf(pin)) { - if (vertex->isDriver(network_)) { - LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex); - DrvrLoadSlews load_slews_prev; - if (incremental_) - load_slews_prev = loadSlews(load_pin_index_map); - findDriverDelays(vertex, arc_delay_calc, load_pin_index_map); - if (propagate) { - if (network_->direction(pin)->isInternal()) - enqueueTimingChecksEdges(vertex); - // Enqueue adjacent vertices even if the load slews did not - // change when non-incremental to stride past annotations. - if (!incremental_ - || loadSlewsChanged(load_slews_prev, load_pin_index_map)) - iter_->enqueueFanout(vertex); - } - } - else { - // Load vertex. - enqueueTimingChecksEdges(vertex); - // Enqueue driver vertices from this input load. - if (propagate) - iter_->enqueueFanout(vertex); - } + else if (network_->isLeaf(pin) + && vertex->isDriver(network_)) { + LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex); + DrvrLoadSlews load_slews_prev; + if (incremental_) + load_slews_prev = loadSlews(load_pin_index_map); + findDriverDelays(vertex, arc_delay_calc, load_pin_index_map); + if (propagate) { + if (network_->direction(pin)->isInternal()) + enqueueTimingChecksEdges(vertex); + // Enqueue adjacent vertices even if the load slews did not + // change when non-incremental to stride past annotations. + if (!incremental_ + || loadSlewsChanged(load_slews_prev, load_pin_index_map)) + iter_->enqueueFanout(vertex); } } + else if (vertex->isLoad(network_)) { + // Load vertex. + // Includes top level bidirect load vertex with wire edge to bidirect driver. + enqueueTimingChecksEdges(vertex); + // Enqueue driver vertices from this input load. + if (propagate) + iter_->enqueueFanout(vertex); + } } DrvrLoadSlews @@ -1295,9 +1293,6 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex, } if (load_changed && observer_) observer_->delayChangedTo(load_vertex); - // Enqueue bidirect driver from load vertex. - if (bidirectDrvrSlewFromLoad(load_pin)) - iter_->enqueue(graph_->pinDrvrVertex(load_pin)); changed |= load_changed; } } diff --git a/graph/Graph.cc b/graph/Graph.cc index b1f40d4c..93f52be1 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -1115,6 +1115,23 @@ Vertex::isDriver(const Network *network) const || dir->isInternal()))); } +bool +Vertex::isLoad(const Network *network) const +{ + PortDirection *dir = network->direction(pin_); + bool top_level_port = network->isTopLevelPort(pin_); + return ((top_level_port + && (dir->isOutput() + || (dir->isBidirect() + && !is_bidirect_drvr_))) + || (!top_level_port + && (dir->isInput() + || dir->isTristate() + || (dir->isBidirect() + && !is_bidirect_drvr_) + || dir->isInternal()))); +} + void Vertex::setLevel(Level level) { diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index e4a1be0a..ed96f633 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -255,6 +255,7 @@ public: std::string name(const Network *network) const; [[nodiscard]] bool isBidirectDriver() const { return is_bidirect_drvr_; } [[nodiscard]] bool isDriver(const Network *network) const; + [[nodiscard]] bool isLoad(const Network *network) const; Level level() const { return level_; } void setLevel(Level level); [[nodiscard]] bool visited() const { return visited1_; }