diff --git a/graph/Graph.cc b/graph/Graph.cc index a9862ef6..8f69b0fe 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -343,11 +343,13 @@ Graph::makeWireEdge(Pin *from_pin, Vertex *from_vertex, *from_bidirect_drvr_vertex; pinVertices(from_pin, from_vertex, from_bidirect_drvr_vertex); Vertex *to_vertex = pinLoadVertex(to_pin); - // From and/or to can be bidirect, but edge is always from driver to load. - if (from_bidirect_drvr_vertex) - makeEdge(from_bidirect_drvr_vertex, to_vertex, arc_set); - else - makeEdge(from_vertex, to_vertex, arc_set); + if (from_vertex && to_vertex) { + // From and/or to can be bidirect, but edge is always from driver to load. + if (from_bidirect_drvr_vertex) + makeEdge(from_bidirect_drvr_vertex, to_vertex, arc_set); + else + makeEdge(from_vertex, to_vertex, arc_set); + } } //////////////////////////////////////////////////////////////// diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 7bc19a3b..9e9d1238 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -897,6 +897,8 @@ public: // loops until the arrivals converge. // If full=false update arrivals incrementally. // 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); // Invalidate all delay calculations. Arrivals also invalidated. void delaysInvalid(); diff --git a/network/Network.cc b/network/Network.cc index 05055103..1f525806 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -521,7 +521,9 @@ Network::isLoad(const Pin *pin) const const Instance *inst = instance(pin); return (isLeaf(inst) && dir->isAnyInput()) // isTopLevelPort(pin) - || (isTopInstance(inst) && dir->isAnyOutput()); + || (isTopInstance(inst) && dir->isAnyOutput()) + // Black box unknown ports are treated as loads. + || dir->isUnknown(); } bool diff --git a/search/Sta.cc b/search/Sta.cc index d89fc919..a8ca08fe 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4135,23 +4135,25 @@ Sta::connectPinAfter(Pin *pin) else { Vertex *vertex, *bidir_drvr_vertex; graph_->pinVertices(pin, vertex, bidir_drvr_vertex); - search_->arrivalInvalid(vertex); - search_->requiredInvalid(vertex); - if (bidir_drvr_vertex) { - search_->arrivalInvalid(bidir_drvr_vertex); - search_->requiredInvalid(bidir_drvr_vertex); - } + if (vertex) { + search_->arrivalInvalid(vertex); + search_->requiredInvalid(vertex); + if (bidir_drvr_vertex) { + search_->arrivalInvalid(bidir_drvr_vertex); + search_->requiredInvalid(bidir_drvr_vertex); + } - // Make interconnect edges from/to pin. - if (network_->isDriver(pin)) { - graph_->makeWireEdgesFromPin(pin); - connectDrvrPinAfter(bidir_drvr_vertex ? bidir_drvr_vertex : vertex); - } - // Note that a bidirect is both a driver and a load so this - // is NOT an else clause for the above "if". - if (network_->isLoad(pin)) { - graph_->makeWireEdgesToPin(pin); - connectLoadPinAfter(vertex); + // Make interconnect edges from/to pin. + if (network_->isDriver(pin)) { + graph_->makeWireEdgesFromPin(pin); + connectDrvrPinAfter(bidir_drvr_vertex ? bidir_drvr_vertex : vertex); + } + // Note that a bidirect is both a driver and a load so this + // is NOT an else clause for the above "if". + if (network_->isLoad(pin)) { + graph_->makeWireEdgesToPin(pin); + connectLoadPinAfter(vertex); + } } } } diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index 28026980..7c583913 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -2058,7 +2058,7 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell, Port *port = (size == 1) ? network_->makePort(cell, port_name) : network_->makeBusPort(cell, port_name, 0, size - 1); - network_->setDirection(port, PortDirection::bidirect()); + network_->setDirection(port, PortDirection::unknown()); } } @@ -2077,7 +2077,7 @@ VerilogReader::makeBlackBoxOrderedPorts(Cell *cell, ? network_->makePort(cell, port_name) : network_->makeBusPort(cell, port_name, size - 1, 0); stringDelete(port_name); - network_->setDirection(port, PortDirection::bidirect()); + network_->setDirection(port, PortDirection::unknown()); port_index++; } }