GraphDelayCalc::findVertexDelay incr

Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
James Cherry 2026-07-12 12:15:14 -07:00
parent dbb19a2687
commit affd539b3f
4 changed files with 54 additions and 38 deletions

View File

@ -698,19 +698,30 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
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 (network_->direction(pin)->isInternal()) if (network_->direction(pin)->isInternal())
enqueueTimingChecksEdges(vertex); enqueueCheckEdges(vertex);
// Enqueue adjacent vertices even if the load slews did not graph_->visitFanouts(vertex, search_non_latch_pred_,
// change when non-incremental to stride past annotations. [this, &load_slews_prev, &load_pin_index_map]
(Vertex *fanout) {
// Enqueue adjacent vertices even if the load slew
// did not change when non-incremental to stride
// past annotations.
if (!delays_exist_ if (!delays_exist_
|| loadSlewsChanged(load_slews_prev, load_pin_index_map)) || loadSlewChanged(fanout, load_slews_prev,
iter_->enqueueFanout(vertex); load_pin_index_map)) {
iter_->enqueue(fanout);
fanout->setBfsPredecessorChanged(true);
}
});
} }
else if (vertex->isLoad(network_)) { else if (vertex->isLoad(network_)) {
// Load vertex. // Load vertex.
// Includes top level bidirect load vertex with wire edge to bidirect driver. // Includes top level bidirect load vertex with wire edge to bidirect driver.
enqueueTimingChecksEdges(vertex); enqueueCheckEdges(vertex);
// Enqueue driver vertices from this input load. graph_->visitFanouts(vertex, search_non_latch_pred_,
iter_->enqueueFanout(vertex); [this] (Vertex *fanout) {
iter_->enqueue(fanout);
fanout->setBfsPredecessorChanged(true);
});
} }
} }
@ -730,24 +741,25 @@ GraphDelayCalc::loadSlews(LoadPinIndexMap &load_pin_index_map)
} }
bool bool
GraphDelayCalc::loadSlewsChanged(DrvrLoadSlews &load_slews_prev, GraphDelayCalc::loadSlewChanged(Vertex *load_vertex,
DrvrLoadSlews &load_slews_prev,
LoadPinIndexMap &load_pin_index_map) LoadPinIndexMap &load_pin_index_map)
{ {
size_t slew_count = graph_->slewCount(); if (load_slews_prev.empty())
for (auto const [pin, index] : load_pin_index_map) { return true;
Vertex *load_vertex = graph_->pinLoadVertex(pin); size_t index = load_pin_index_map[load_vertex->pin()];
SlewSeq &slews_prev = load_slews_prev[index];; SlewSeq &slews_prev = load_slews_prev[index];;
size_t slew_count = graph_->slewCount();
for (size_t i = 0; i < slew_count; i++) { for (size_t i = 0; i < slew_count; i++) {
const Slew slew = graph_->slew(load_vertex, i); const Slew slew = graph_->slew(load_vertex, i);
if (!delayEqual(slew, slews_prev[i], this)) if (!delayEqual(slew, slews_prev[i], this))
return true; return true;
} }
}
return false; return false;
} }
void void
GraphDelayCalc::enqueueTimingChecksEdges(Vertex *vertex) GraphDelayCalc::enqueueCheckEdges(Vertex *vertex)
{ {
if (vertex->hasChecks()) { if (vertex->hasChecks()) {
VertexInEdgeIterator edge_iter(vertex, graph_); VertexInEdgeIterator edge_iter(vertex, graph_);
@ -1173,7 +1185,7 @@ GraphDelayCalc::annotateDelaysSlews(Edge *edge,
dcalc_result.drvrSlew(), scene, min_max); dcalc_result.drvrSlew(), scene, min_max);
if (!edge->role()->isLatchDtoQ()) { if (!edge->role()->isLatchDtoQ()) {
Vertex *drvr_vertex = edge->to(graph_); Vertex *drvr_vertex = edge->to(graph_);
delay_changed |= annotateLoadDelays(drvr_vertex, arc->toEdge()->asRiseFall(), annotateLoadDelays(drvr_vertex, arc->toEdge()->asRiseFall(),
dcalc_result, dcalc_result,
load_pin_index_map, delay_zero, true, load_pin_index_map, delay_zero, true,
scene, min_max); scene, min_max);
@ -1231,7 +1243,7 @@ GraphDelayCalc::annotateDelaySlew(Edge *edge,
// Annotate wire arc delays and load pin slews. // Annotate wire arc delays and load pin slews.
// extra_delay is additional wire delay to add to delay returned // extra_delay is additional wire delay to add to delay returned
// by the delay calculator. // by the delay calculator.
bool void
GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex, GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
const RiseFall *drvr_rf, const RiseFall *drvr_rf,
ArcDcalcResult &dcalc_result, ArcDcalcResult &dcalc_result,
@ -1242,7 +1254,6 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
const MinMax *min_max) const MinMax *min_max)
{ {
DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max); DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max);
bool changed = false;
VertexOutEdgeIterator edge_iter(drvr_vertex, graph_); VertexOutEdgeIterator edge_iter(drvr_vertex, graph_);
while (edge_iter.hasNext()) { while (edge_iter.hasNext()) {
Edge *wire_edge = edge_iter.next(); Edge *wire_edge = edge_iter.next();
@ -1257,20 +1268,17 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
load_vertex->to_string(this), load_vertex->to_string(this),
delayAsString(wire_delay, this), delayAsString(wire_delay, this),
delayAsString(load_slew, this)); delayAsString(load_slew, this));
bool load_changed = false;
if (!load_vertex->slewAnnotated(drvr_rf, min_max)) { if (!load_vertex->slewAnnotated(drvr_rf, min_max)) {
if (drvr_vertex->slewAnnotated(drvr_rf, min_max)) { if (drvr_vertex->slewAnnotated(drvr_rf, min_max)) {
// Copy the driver slew to the load if it is annotated. // Copy the driver slew to the load if it is annotated.
const Slew drvr_slew = graph_->slew(drvr_vertex, drvr_rf, ap_index); const Slew drvr_slew = graph_->slew(drvr_vertex, drvr_rf, ap_index);
graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew); graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew);
load_changed = true;
} }
else { else {
const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index); const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index);
if (!merge if (!merge
|| delayGreater(load_slew, slew, min_max, this)) { || delayGreater(load_slew, slew, min_max, this)) {
graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew); graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew);
load_changed = true;
} }
} }
} }
@ -1283,15 +1291,12 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
if (!merge if (!merge
|| delayGreater(wire_delay_extra, delay, min_max, this)) { || delayGreater(wire_delay_extra, delay, min_max, this)) {
graph_->setWireArcDelay(wire_edge, drvr_rf, ap_index, wire_delay_extra); graph_->setWireArcDelay(wire_edge, drvr_rf, ap_index, wire_delay_extra);
load_changed = true; if (observer_)
}
}
if (load_changed && observer_)
observer_->delayChangedTo(load_vertex); observer_->delayChangedTo(load_vertex);
changed |= load_changed;
} }
} }
return changed; }
}
} }
LoadPinIndexMap LoadPinIndexMap

View File

@ -1053,6 +1053,7 @@ Vertex::init(Pin *pin,
has_downstream_clk_pin_ = false; has_downstream_clk_pin_ = false;
visited1_ = false; visited1_ = false;
visited2_ = false; visited2_ = false;
bfs_predecessor_changed_ = false;
has_sim_value_ = false; has_sim_value_ = false;
level_ = 0; level_ = 0;
slew_annotated_ = false; slew_annotated_ = false;
@ -1281,6 +1282,12 @@ Vertex::setBfsInQueue(BfsIndex index,
bfs_in_queue_ &= ~(1 << static_cast<unsigned>(index)); bfs_in_queue_ &= ~(1 << static_cast<unsigned>(index));
} }
void
Vertex::setBfsPredecessorChanged(bool changed)
{
bfs_predecessor_changed_ = changed;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
// Edge // Edge

View File

@ -289,6 +289,8 @@ public:
void setHasDownstreamClkPin(bool has_clk_pin); void setHasDownstreamClkPin(bool has_clk_pin);
[[nodiscard]] bool bfsInQueue(BfsIndex index) const; [[nodiscard]] bool bfsInQueue(BfsIndex index) const;
void setBfsInQueue(BfsIndex index, bool value); void setBfsInQueue(BfsIndex index, bool value);
bool bfsPredecessorChanged() const { return bfs_predecessor_changed_; }
void setBfsPredecessorChanged(bool changed);
[[nodiscard]] bool isRegClk() const { return is_reg_clk_; } [[nodiscard]] bool isRegClk() const { return is_reg_clk_; }
// Has sim value in some mode. // Has sim value in some mode.
[[nodiscard]] bool hasSimValue() const { return has_sim_value_; } [[nodiscard]] bool hasSimValue() const { return has_sim_value_; }
@ -336,6 +338,7 @@ protected:
unsigned int has_downstream_clk_pin_:1; unsigned int has_downstream_clk_pin_:1;
unsigned int visited1_:1; unsigned int visited1_:1;
unsigned int visited2_:1; unsigned int visited2_:1;
unsigned int bfs_predecessor_changed_:1;
unsigned int has_sim_value_:1; unsigned int has_sim_value_:1;
int level_:Graph::vertex_level_bits; // 24 int level_:Graph::vertex_level_bits; // 24
unsigned int slew_annotated_:slew_annotated_bits; // 4 unsigned int slew_annotated_:slew_annotated_bits; // 4

View File

@ -234,9 +234,10 @@ protected:
void findVertexDelay(Vertex *vertex, void findVertexDelay(Vertex *vertex,
ArcDelayCalc *arc_delay_calc); ArcDelayCalc *arc_delay_calc);
DrvrLoadSlews loadSlews(LoadPinIndexMap &load_pin_index_map); DrvrLoadSlews loadSlews(LoadPinIndexMap &load_pin_index_map);
bool loadSlewsChanged(DrvrLoadSlews &load_slews_prev, void enqueueCheckEdges(Vertex *vertex);
bool loadSlewChanged(Vertex *load_vertex,
DrvrLoadSlews &load_slews_prev,
LoadPinIndexMap &load_pin_index_map); LoadPinIndexMap &load_pin_index_map);
void enqueueTimingChecksEdges(Vertex *vertex);
bool annotateDelaysSlews(Edge *edge, bool annotateDelaysSlews(Edge *edge,
const TimingArc *arc, const TimingArc *arc,
ArcDcalcResult &dcalc_result, ArcDcalcResult &dcalc_result,
@ -250,7 +251,7 @@ protected:
const Slew &gate_slew, const Slew &gate_slew,
const Scene *scene, const Scene *scene,
const MinMax *min_max); const MinMax *min_max);
bool annotateLoadDelays(Vertex *drvr_vertex, void annotateLoadDelays(Vertex *drvr_vertex,
const RiseFall *drvr_rf, const RiseFall *drvr_rf,
ArcDcalcResult &dcalc_result, ArcDcalcResult &dcalc_result,
LoadPinIndexMap &load_pin_index_map, LoadPinIndexMap &load_pin_index_map,