GraphDelayCalc::findVertexDelay bidir load->driver

Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
James Cherry 2026-07-12 08:37:35 -07:00
parent 87e837a8be
commit dd657bf250
3 changed files with 41 additions and 28 deletions

View File

@ -692,33 +692,31 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|| (vertex->isBidirectDriver() || (vertex->isBidirectDriver()
&& network_->isTopLevelPort(pin))) && network_->isTopLevelPort(pin)))
seedRootSlew(vertex, arc_delay_calc); seedRootSlew(vertex, arc_delay_calc);
else { else if (network_->isLeaf(pin)
if (network_->isLeaf(pin)) { && vertex->isDriver(network_)) {
if (vertex->isDriver(network_)) { LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex);
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex); DrvrLoadSlews load_slews_prev;
DrvrLoadSlews load_slews_prev; if (incremental_)
if (incremental_) load_slews_prev = loadSlews(load_pin_index_map);
load_slews_prev = loadSlews(load_pin_index_map); findDriverDelays(vertex, arc_delay_calc, load_pin_index_map);
findDriverDelays(vertex, arc_delay_calc, load_pin_index_map); if (propagate) {
if (propagate) { if (network_->direction(pin)->isInternal())
if (network_->direction(pin)->isInternal()) enqueueTimingChecksEdges(vertex);
enqueueTimingChecksEdges(vertex); // Enqueue adjacent vertices even if the load slews did not
// Enqueue adjacent vertices even if the load slews did not // change when non-incremental to stride past annotations.
// change when non-incremental to stride past annotations. if (!incremental_
if (!incremental_ || loadSlewsChanged(load_slews_prev, load_pin_index_map))
|| loadSlewsChanged(load_slews_prev, load_pin_index_map)) iter_->enqueueFanout(vertex);
iter_->enqueueFanout(vertex);
}
}
else {
// Load vertex.
enqueueTimingChecksEdges(vertex);
// Enqueue driver vertices from this input load.
if (propagate)
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 DrvrLoadSlews
@ -1295,9 +1293,6 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
} }
if (load_changed && observer_) if (load_changed && observer_)
observer_->delayChangedTo(load_vertex); observer_->delayChangedTo(load_vertex);
// Enqueue bidirect driver from load vertex.
if (bidirectDrvrSlewFromLoad(load_pin))
iter_->enqueue(graph_->pinDrvrVertex(load_pin));
changed |= load_changed; changed |= load_changed;
} }
} }

View File

@ -1115,6 +1115,23 @@ Vertex::isDriver(const Network *network) const
|| dir->isInternal()))); || 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 void
Vertex::setLevel(Level level) Vertex::setLevel(Level level)
{ {

View File

@ -255,6 +255,7 @@ public:
std::string name(const Network *network) const; std::string name(const Network *network) const;
[[nodiscard]] bool isBidirectDriver() const { return is_bidirect_drvr_; } [[nodiscard]] bool isBidirectDriver() const { return is_bidirect_drvr_; }
[[nodiscard]] bool isDriver(const Network *network) const; [[nodiscard]] bool isDriver(const Network *network) const;
[[nodiscard]] bool isLoad(const Network *network) const;
Level level() const { return level_; } Level level() const { return level_; }
void setLevel(Level level); void setLevel(Level level);
[[nodiscard]] bool visited() const { return visited1_; } [[nodiscard]] bool visited() const { return visited1_; }