bulletproofing against incremental updates with missing liberty

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2021-09-16 21:35:52 -07:00
parent 5a765a7606
commit 41706e0db6
3 changed files with 27 additions and 21 deletions

View File

@ -344,11 +344,13 @@ Graph::makeWireEdge(Pin *from_pin,
Vertex *from_vertex, *from_bidirect_drvr_vertex; Vertex *from_vertex, *from_bidirect_drvr_vertex;
pinVertices(from_pin, from_vertex, from_bidirect_drvr_vertex); pinVertices(from_pin, from_vertex, from_bidirect_drvr_vertex);
Vertex *to_vertex = pinLoadVertex(to_pin); Vertex *to_vertex = pinLoadVertex(to_pin);
// From and/or to can be bidirect, but edge is always from driver to load. if (from_vertex && to_vertex) {
if (from_bidirect_drvr_vertex) // From and/or to can be bidirect, but edge is always from driver to load.
makeEdge(from_bidirect_drvr_vertex, to_vertex, arc_set); if (from_bidirect_drvr_vertex)
else makeEdge(from_bidirect_drvr_vertex, to_vertex, arc_set);
makeEdge(from_vertex, to_vertex, arc_set); else
makeEdge(from_vertex, to_vertex, arc_set);
}
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////

View File

@ -897,6 +897,8 @@ public:
// loops until the arrivals converge. // loops until the arrivals converge.
// If full=false update arrivals incrementally. // If full=false update arrivals incrementally.
// If full=true update all arrivals from scratch. // If full=true update all arrivals from scratch.
// There is rarely any reason to call updateTiming directly because
// arrival/required/slack functions implicitly update timing incrementally.
void updateTiming(bool full); void updateTiming(bool full);
// Invalidate all delay calculations. Arrivals also invalidated. // Invalidate all delay calculations. Arrivals also invalidated.
void delaysInvalid(); void delaysInvalid();

View File

@ -4122,23 +4122,25 @@ Sta::connectPinAfter(Pin *pin)
else { else {
Vertex *vertex, *bidir_drvr_vertex; Vertex *vertex, *bidir_drvr_vertex;
graph_->pinVertices(pin, vertex, bidir_drvr_vertex); graph_->pinVertices(pin, vertex, bidir_drvr_vertex);
search_->arrivalInvalid(vertex); if (vertex) {
search_->requiredInvalid(vertex); search_->arrivalInvalid(vertex);
if (bidir_drvr_vertex) { search_->requiredInvalid(vertex);
search_->arrivalInvalid(bidir_drvr_vertex); if (bidir_drvr_vertex) {
search_->requiredInvalid(bidir_drvr_vertex); search_->arrivalInvalid(bidir_drvr_vertex);
} search_->requiredInvalid(bidir_drvr_vertex);
}
// Make interconnect edges from/to pin. // Make interconnect edges from/to pin.
if (network_->isDriver(pin)) { if (network_->isDriver(pin)) {
graph_->makeWireEdgesFromPin(pin); graph_->makeWireEdgesFromPin(pin);
connectDrvrPinAfter(bidir_drvr_vertex ? bidir_drvr_vertex : vertex); connectDrvrPinAfter(bidir_drvr_vertex ? bidir_drvr_vertex : vertex);
} }
// Note that a bidirect is both a driver and a load so this // Note that a bidirect is both a driver and a load so this
// is NOT an else clause for the above "if". // is NOT an else clause for the above "if".
if (network_->isLoad(pin)) { if (network_->isLoad(pin)) {
graph_->makeWireEdgesToPin(pin); graph_->makeWireEdgesToPin(pin);
connectLoadPinAfter(vertex); connectLoadPinAfter(vertex);
}
} }
} }
} }