Files
OpenSTA/include/sta/Network.hh
T

676 lines
29 KiB
C++
Raw Normal View History

2018-09-28 08:54:21 -07:00
// OpenSTA, Static Timing Analyzer
2026-03-10 13:21:17 -07:00
// Copyright (c) 2026, Parallax Software, Inc.
2018-09-28 08:54:21 -07:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2022-01-04 10:17:08 -07:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2018-09-28 08:54:21 -07:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2022-01-04 10:17:08 -07:00
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2025-01-21 18:54:33 -07:00
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
2018-09-28 08:54:21 -07:00
2020-02-15 17:13:16 -07:00
#pragma once
2018-09-28 08:54:21 -07:00
2021-08-12 19:52:50 -07:00
#include <functional>
2026-01-03 16:59:35 -08:00
#include <map>
2026-03-28 19:13:35 -07:00
#include <string>
#include <string_view>
2021-08-12 19:52:50 -07:00
2020-04-05 14:53:44 -07:00
#include "LibertyClass.hh"
#include "NetworkClass.hh"
#include "StaState.hh"
2026-04-15 09:38:10 -07:00
#include "StringUtil.hh"
#include "VertexId.hh"
2018-09-28 08:54:21 -07:00
namespace sta {
class Report;
class PatternMatch;
class PinVisitor;
2026-03-28 19:13:35 -07:00
using LibertyLibraryMap = std::map<std::string, LibertyLibrary*, std::less<>>;
2018-09-28 08:54:21 -07:00
// Link network function returns top level instance.
2019-03-12 17:25:53 -07:00
// Return nullptr if link fails.
2026-03-28 19:13:35 -07:00
using LinkNetworkFunc = std::function<Instance* (std::string_view top_cell_name,
bool make_black_boxes)>;
2026-01-03 16:59:35 -08:00
using NetDrvrPinsMap = std::map<const Net*, PinSet*>;
2018-09-28 08:54:21 -07:00
// The Network class defines the network API used by sta.
// The interface to a network implementation is constructed by
// deriving a class from it. This interface class is known as a
// ADAPTER/DELEGATE. An instance of the adapter is used to
// translate calls in the sta to a target network implementation.
// Network data types:
// Libraries are collections of cells.
// Cells are masters (ala verilog module or liberty cell).
// Ports define the connections to a cell.
// There are four different sub-classes of ports:
// Simple non-bus ports such as "enable".
// Bundles of simple or single bit ports, such as D bundling D0, D1.
// Buses such as D[3:0]
// Bus bit ports, which are one bit of a bus port such as D[0].
// Bus bit ports are always members of a bus.
// Instances are calls of cells in the design hierarchy
2021-10-13 22:36:44 -07:00
// Hierarchical and leaf instances are in the network.
2018-09-28 08:54:21 -07:00
// At the top of the hierarchy is a top level instance that
// has instances for the top level netlist.
// Pins are a connection between an instance and a net corresponding
// to a port. Ports on the top level instance also have pins in
// the network.
// Terminals are a connection between a net and a pin on the parent
// instance.
// Nets connect pins at a level of hierarchy. Both hierarchical
// instance pins and leaf instance pins are connected by net.
//
// The network API only contains pointers/handles to these data types.
// The adapter casts these handles to its native data types and calls
// the appropriate code to implement the member functions of the Network
// class.
//
// Pattern arguments used by lookup find*Matching functions
// use a simple unix shell or tcl "string match" style pattern matching:
// '*' matches zero or more characters
// '?' matches any character
//
// Note that some of the network member functions are not virtual because
// they can be implemented in terms of the other functions.
// Only the pure virtual functions MUST be implemented by a derived class.
class Network : public StaState
{
public:
2026-04-15 09:38:10 -07:00
Network() = default;
2026-04-13 14:58:16 -07:00
~Network() override;
2018-09-28 08:54:21 -07:00
virtual void clear();
// Linking the hierarchy creates the instance/pin/net network hierarchy.
// Most network functions are only useful after the hierarchy
// has been linked. When the network interfaces to an external database,
// linking is not necessary because the network has already been expanded.
// Return true if successful.
2026-03-28 19:13:35 -07:00
virtual bool linkNetwork(std::string_view top_cell_name,
2026-01-03 16:59:35 -08:00
bool make_black_boxes,
Report *report) = 0;
2018-09-28 08:54:21 -07:00
virtual bool isLinked() const;
virtual bool isEditable() const { return false; }
////////////////////////////////////////////////////////////////
// Library functions.
2026-03-28 19:13:35 -07:00
virtual std::string name(const Library *library) const = 0;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Library *library) const = 0;
2018-09-28 08:54:21 -07:00
virtual LibraryIterator *libraryIterator() const = 0;
virtual LibertyLibraryIterator *libertyLibraryIterator() const = 0;
2026-03-28 19:13:35 -07:00
virtual Library *findLibrary(std::string_view name) = 0;
virtual LibertyLibrary *findLiberty(std::string_view name) = 0;
2022-02-03 16:49:39 -07:00
// Find liberty library by filename.
2026-03-28 19:13:35 -07:00
virtual LibertyLibrary *findLibertyFilename(std::string_view filename);
2018-09-28 08:54:21 -07:00
virtual Cell *findCell(const Library *library,
2026-03-28 19:13:35 -07:00
std::string_view name) const = 0;
2018-09-28 08:54:21 -07:00
// Search the design (non-liberty) libraries for cells matching pattern.
2023-01-19 11:23:45 -07:00
virtual CellSeq findCellsMatching(const Library *library,
const PatternMatch *pattern) const = 0;
2018-09-28 08:54:21 -07:00
// Search liberty libraries for cell name.
2026-03-28 19:13:35 -07:00
virtual LibertyCell *findLibertyCell(std::string_view name) const;
virtual LibertyLibrary *makeLibertyLibrary(std::string_view name,
std::string_view filename) = 0;
2018-09-28 08:54:21 -07:00
// Hook for network after reading liberty library.
virtual void readLibertyAfter(LibertyLibrary *library);
// First liberty library read is used to look up defaults.
// This corresponds to a link_path of '*'.
virtual LibertyLibrary *defaultLibertyLibrary() const;
2018-09-28 08:54:21 -07:00
void setDefaultLibertyLibrary(LibertyLibrary *library);
2022-10-04 20:50:27 -07:00
// Check liberty cells used by the network to make sure they exist
2026-01-03 16:59:35 -08:00
// for all the defined scenes.
void checkNetworkLibertyScenes();
// Check liberty cells to make sure they exist for all the defined scenes.
void checkLibertyScenes();
2018-09-28 08:54:21 -07:00
////////////////////////////////////////////////////////////////
// Cell functions.
2026-03-28 19:13:35 -07:00
virtual std::string name(const Cell *cell) const = 0;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Cell *cell) const = 0;
2018-09-28 08:54:21 -07:00
virtual Library *library(const Cell *cell) const = 0;
2019-06-24 08:35:04 -07:00
virtual LibertyLibrary *libertyLibrary(const Cell *cell) const;
2018-09-28 08:54:21 -07:00
// Find the corresponding liberty cell.
2019-06-24 08:35:04 -07:00
virtual const LibertyCell *libertyCell(const Cell *cell) const = 0;
2018-09-28 08:54:21 -07:00
virtual LibertyCell *libertyCell(Cell *cell) const = 0;
2019-06-24 08:35:04 -07:00
virtual const Cell *cell(const LibertyCell *cell) const = 0;
2019-06-14 12:05:34 -07:00
virtual Cell *cell(LibertyCell *cell) const = 0;
2018-09-28 08:54:21 -07:00
// Filename may return null.
2026-03-28 19:13:35 -07:00
virtual std::string_view filename(const Cell *cell) const = 0;
2025-04-11 16:59:48 -07:00
virtual std::string getAttribute(const Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view key) const = 0;
2025-05-18 09:37:10 -07:00
virtual const AttributeMap &attributeMap(const Cell *cell) const = 0;
2018-09-28 08:54:21 -07:00
// Name can be a simple, bundle, bus, or bus bit name.
virtual Port *findPort(const Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name) const = 0;
2023-01-19 11:23:45 -07:00
virtual PortSeq findPortsMatching(const Cell *cell,
2023-06-04 09:34:29 -07:00
const PatternMatch *pattern) const;
2018-09-28 08:54:21 -07:00
virtual bool isLeaf(const Cell *cell) const = 0;
virtual CellPortIterator *portIterator(const Cell *cell) const = 0;
// Iterate over port bits (expanded buses).
virtual CellPortBitIterator *portBitIterator(const Cell *cell) const = 0;
// Port bit count (expanded buses).
virtual int portBitCount(const Cell *cell) const = 0;
////////////////////////////////////////////////////////////////
// Port functions
2026-03-28 19:13:35 -07:00
virtual std::string name(const Port *port) const = 0;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Port *port) const = 0;
2018-09-28 08:54:21 -07:00
virtual Cell *cell(const Port *port) const = 0;
2019-07-02 07:07:34 -07:00
virtual LibertyPort *libertyPort(const Port *port) const = 0;
2018-09-28 08:54:21 -07:00
virtual PortDirection *direction(const Port *port) const = 0;
// Bus port functions.
virtual bool isBus(const Port *port) const = 0;
virtual bool isBundle(const Port *port) const = 0;
// Size is the bus/bundle member count (1 for non-bus/bundle ports).
virtual int size(const Port *port) const = 0;
// Bus range bus[from:to].
2026-03-28 19:13:35 -07:00
virtual std::string busName(const Port *port) const = 0;
2018-09-28 08:54:21 -07:00
// Bus member, bus[subscript].
virtual Port *findBusBit(const Port *port,
2026-01-03 16:59:35 -08:00
int index) const = 0;
2018-09-28 08:54:21 -07:00
virtual int fromIndex(const Port *port) const = 0;
virtual int toIndex(const Port *port) const = 0;
2022-06-09 19:08:37 -07:00
// Predicate to determine if index is within bus range.
// (toIndex > fromIndex) && fromIndex <= index <= toIndex
// || (fromIndex > toIndex) && fromIndex >= index >= toIndex
2018-09-28 08:54:21 -07:00
bool busIndexInRange(const Port *port,
2026-01-03 16:59:35 -08:00
int index);
2018-09-28 08:54:21 -07:00
// Find Bundle/bus member by index.
virtual Port *findMember(const Port *port,
2026-01-03 16:59:35 -08:00
int index) const = 0;
2018-09-28 08:54:21 -07:00
// Iterate over the bits of a bus port or members of a bundle.
2019-07-02 16:33:31 -07:00
// from_index -> to_index
2018-09-28 08:54:21 -07:00
virtual PortMemberIterator *memberIterator(const Port *port) const = 0;
// A port has members if it is a bundle or bus.
virtual bool hasMembers(const Port *port) const;
////////////////////////////////////////////////////////////////
// Instance functions
2023-01-19 11:23:45 -07:00
// Name local to containing cell/instance.
2026-03-28 19:13:35 -07:00
virtual std::string name(const Instance *instance) const = 0;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Instance *instance) const = 0;
2018-09-28 08:54:21 -07:00
// Top level instance of the design (defined after link).
virtual Instance *topInstance() const = 0;
virtual bool isTopInstance(const Instance *inst) const;
2026-03-28 19:13:35 -07:00
virtual Instance *findInstance(std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
// Find instance relative to hierarchical instance.
2025-02-10 17:32:50 -07:00
virtual Instance *findInstanceRelative(const Instance *inst,
2026-03-28 19:13:35 -07:00
std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
// Default implementation uses linear search.
2023-01-19 11:23:45 -07:00
virtual InstanceSeq findInstancesMatching(const Instance *context,
const PatternMatch *pattern) const;
virtual InstanceSeq findInstancesHierMatching(const Instance *instance,
const PatternMatch *pattern) const;
2025-04-11 16:59:48 -07:00
virtual std::string getAttribute(const Instance *inst,
2026-03-28 19:13:35 -07:00
std::string_view key) const = 0;
2025-05-18 09:37:10 -07:00
virtual const AttributeMap &attributeMap(const Instance *inst) const = 0;
2018-09-28 08:54:21 -07:00
// Hierarchical path name.
2026-03-28 19:13:35 -07:00
virtual std::string pathName(const Instance *instance) const;
2018-09-28 08:54:21 -07:00
bool pathNameLess(const Instance *inst1,
2026-01-03 16:59:35 -08:00
const Instance *inst2) const;
2018-09-28 08:54:21 -07:00
int pathNameCmp(const Instance *inst1,
2026-01-03 16:59:35 -08:00
const Instance *inst2) const;
2018-09-28 08:54:21 -07:00
// Path from instance up to top level (last in the sequence).
void path(const Instance *inst,
2026-01-03 16:59:35 -08:00
// Return value.
InstanceSeq &path) const;
2018-09-28 08:54:21 -07:00
virtual Cell *cell(const Instance *instance) const = 0;
2026-03-28 19:13:35 -07:00
virtual std::string cellName(const Instance *instance) const;
2018-09-28 08:54:21 -07:00
virtual LibertyLibrary *libertyLibrary(const Instance *instance) const;
virtual LibertyCell *libertyCell(const Instance *instance) const;
virtual Instance *parent(const Instance *instance) const = 0;
virtual bool isLeaf(const Instance *instance) const = 0;
virtual bool isHierarchical(const Instance *instance) const;
virtual Instance *findChild(const Instance *parent,
2026-03-28 19:13:35 -07:00
std::string_view name) const = 0;
2018-09-28 08:54:21 -07:00
virtual void findChildrenMatching(const Instance *parent,
2026-01-03 16:59:35 -08:00
const PatternMatch *pattern,
2023-01-19 11:23:45 -07:00
// Return value.
InstanceSeq &matches) const;
2018-09-28 08:54:21 -07:00
// Is inst inside of hier_inst?
bool isInside(const Instance *inst,
2026-01-03 16:59:35 -08:00
const Instance *hier_inst) const;
2018-09-28 08:54:21 -07:00
// Iterate over all of the leaf instances in the hierarchy
// This iterator is not virtual because it can be written in terms of
// the other primitives.
LeafInstanceIterator *leafInstanceIterator() const;
LeafInstanceIterator *leafInstanceIterator(const Instance *hier_inst) const;
2024-01-22 11:17:08 -07:00
InstanceSeq leafInstances();
2018-09-28 08:54:21 -07:00
// Iterate over the children of an instance.
virtual InstanceChildIterator *
childIterator(const Instance *instance) const = 0;
// Iterate over the pins on an instance.
virtual InstancePinIterator *
pinIterator(const Instance *instance) const = 0;
// Iterate over the nets in an instance.
// This should include nets that are connected to the
// instance parent thru pins.
virtual InstanceNetIterator *
netIterator(const Instance *instance) const = 0;
int instanceCount();
int instanceCount(Instance *inst);
int leafInstanceCount();
////////////////////////////////////////////////////////////////
// Pin functions
2023-01-19 11:23:45 -07:00
// Name is instance_name/port_name (the same as path name).
2026-03-28 19:13:35 -07:00
virtual std::string name(const Pin *pin) const;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Pin *pin) const = 0;
2026-03-28 19:13:35 -07:00
virtual Pin *findPin(std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
virtual Pin *findPin(const Instance *instance,
2026-03-28 19:13:35 -07:00
std::string_view port_name) const = 0;
2018-09-28 08:54:21 -07:00
virtual Pin *findPin(const Instance *instance,
2026-01-03 16:59:35 -08:00
const Port *port) const;
2018-09-28 08:54:21 -07:00
virtual Pin *findPin(const Instance *instance,
2026-01-03 16:59:35 -08:00
const LibertyPort *port) const;
2018-09-28 08:54:21 -07:00
// Find pin relative to hierarchical instance.
Pin *findPinRelative(const Instance *inst,
2026-03-28 19:13:35 -07:00
std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
// Default implementation uses linear search.
2023-01-19 11:23:45 -07:00
virtual PinSeq findPinsMatching(const Instance *instance,
const PatternMatch *pattern) const;
2018-09-28 08:54:21 -07:00
// Traverse the hierarchy from instance down and find pins matching
// pattern of the form instance_name/port_name.
2023-01-19 11:23:45 -07:00
virtual PinSeq findPinsHierMatching(const Instance *instance,
const PatternMatch *pattern) const;
2026-03-28 19:13:35 -07:00
virtual std::string portName(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Path name is instance_name/port_name.
2026-03-28 19:13:35 -07:00
virtual std::string pathName(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
bool pathNameLess(const Pin *pin1,
2026-01-03 16:59:35 -08:00
const Pin *pin2) const;
2018-09-28 08:54:21 -07:00
int pathNameCmp(const Pin *pin1,
2026-01-03 16:59:35 -08:00
const Pin *pin2) const;
2018-09-28 08:54:21 -07:00
virtual Port *port(const Pin *pin) const = 0;
virtual LibertyPort *libertyPort(const Pin *pin) const;
virtual Instance *instance(const Pin *pin) const = 0;
virtual Net *net(const Pin *pin) const = 0;
virtual Term *term(const Pin *pin) const = 0;
virtual PortDirection *direction(const Pin *pin) const = 0;
2019-06-14 21:03:11 -07:00
virtual bool isLeaf(const Pin *pin) const;
2026-01-03 16:59:35 -08:00
[[nodiscard]] bool isHierarchical(const Pin *pin) const;
[[nodiscard]] bool isTopLevelPort(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Is pin inside the instance hier_pin is attached to?
2026-04-04 09:26:03 -07:00
[[nodiscard]] bool isInside(const Pin *pin,
const Pin *hier_pin) const;
2018-09-28 08:54:21 -07:00
// Is pin inside of hier_inst?
2026-04-04 09:26:03 -07:00
[[nodiscard]] bool isInside(const Pin *pin,
const Instance *hier_inst) const;
[[nodiscard]] bool isDriver(const Pin *pin) const;
[[nodiscard]] bool isLoad(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Has register/latch rise/fall edges from pin.
2026-04-04 09:26:03 -07:00
[[nodiscard]] bool isRegClkPin(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Pin clocks a timing check.
2026-04-04 09:26:03 -07:00
[[nodiscard]] bool isCheckClk(const Pin *pin) const;
[[nodiscard]] bool isLatchData(const Pin *pin) const;
2026-06-18 14:42:12 -07:00
[[nodiscard]] bool isLatchOutput(const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Iterate over all of the pins connected to a pin and the parent
// and child nets it is hierarchically connected to (port, leaf and
// hierarchical pins).
virtual PinConnectedPinIterator *connectedPinIterator(const Pin *pin) const;
2023-01-19 11:23:45 -07:00
virtual void visitConnectedPins(const Pin *pin,
2026-01-03 16:59:35 -08:00
PinVisitor &visitor) const;
2018-09-28 08:54:21 -07:00
// Find driver pins for the net connected to pin.
// Return value is owned by the network.
virtual PinSet *drivers(const Pin *pin);
virtual bool pinLess(const Pin *pin1,
2026-01-03 16:59:35 -08:00
const Pin *pin2) const;
2019-11-11 08:28:42 -07:00
// Return the id of the pin graph vertex.
2019-11-11 09:38:25 -07:00
virtual VertexId vertexId(const Pin *pin) const = 0;
virtual void setVertexId(Pin *pin,
2026-01-03 16:59:35 -08:00
VertexId id) = 0;
2020-07-06 15:18:13 -07:00
// Return the physical X/Y coordinates of the pin.
virtual void location(const Pin *pin,
2026-01-03 16:59:35 -08:00
// Return values.
double &x,
double &y,
bool &exists) const;
2020-07-06 15:18:13 -07:00
2018-09-28 08:54:21 -07:00
int pinCount();
int pinCount(Instance *inst);
int leafPinCount();
////////////////////////////////////////////////////////////////
// Terminal functions
// Name is instance_name/port_name (the same as path name).
2026-03-28 19:13:35 -07:00
virtual std::string name(const Term *term) const;
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Term *term) const = 0;
2026-03-28 19:13:35 -07:00
virtual std::string portName(const Term *term) const;
2018-09-28 08:54:21 -07:00
// Path name is instance_name/port_name (pin name).
2026-03-28 19:13:35 -07:00
virtual std::string pathName(const Term *term) const;
2018-09-28 08:54:21 -07:00
virtual Net *net(const Term *term) const = 0;
virtual Pin *pin(const Term *term) const = 0;
////////////////////////////////////////////////////////////////
// Net functions
2026-03-28 19:13:35 -07:00
virtual std::string name(const Net *net) const = 0; // no hierarchy prefix
2023-01-19 11:23:45 -07:00
virtual ObjectId id(const Net *net) const = 0;
2026-03-28 19:13:35 -07:00
virtual Net *findNet(std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
// Find net relative to hierarchical instance.
2025-02-10 17:32:50 -07:00
virtual Net *findNetRelative(const Instance *inst,
2026-03-28 19:13:35 -07:00
std::string_view path_name) const;
2018-09-28 08:54:21 -07:00
// Default implementation uses linear search.
2023-01-19 11:23:45 -07:00
virtual NetSeq findNetsMatching(const Instance *context,
const PatternMatch *pattern) const;
2018-09-28 08:54:21 -07:00
virtual Net *findNet(const Instance *instance,
2026-03-28 19:13:35 -07:00
std::string_view net_name) const = 0;
2018-09-28 08:54:21 -07:00
// Traverse the hierarchy from instance down and find nets matching
// pattern of the form instance_name/net_name.
2023-01-19 11:23:45 -07:00
virtual NetSeq findNetsHierMatching(const Instance *instance,
const PatternMatch *pattern) const;
// Primitive used by findNetsMatching.
2018-09-28 08:54:21 -07:00
virtual void findInstNetsMatching(const Instance *instance,
2023-01-19 11:23:45 -07:00
const PatternMatch *pattern,
NetSeq &matches) const = 0;
2026-03-28 19:13:35 -07:00
virtual std::string pathName(const Net *net) const;
2018-09-28 08:54:21 -07:00
bool pathNameLess(const Net *net1,
2026-01-03 16:59:35 -08:00
const Net *net2) const;
2018-09-28 08:54:21 -07:00
int pathNameCmp(const Net *net1,
2026-01-03 16:59:35 -08:00
const Net *net2) const;
2018-09-28 08:54:21 -07:00
virtual Instance *instance(const Net *net) const = 0;
// Is net inside of hier_inst?
2020-04-17 11:07:57 -07:00
virtual bool isInside(const Net *net,
2026-01-03 16:59:35 -08:00
const Instance *hier_inst) const;
2018-09-28 08:54:21 -07:00
// Is pin connected to net anywhere in the hierarchy?
virtual bool isConnected(const Net *net,
2026-01-03 16:59:35 -08:00
const Pin *pin) const;
2018-09-28 08:54:21 -07:00
// Is net1 connected to net2 anywhere in the hierarchy?
virtual bool isConnected(const Net *net1,
2026-01-03 16:59:35 -08:00
const Net *net2) const;
2020-04-17 11:07:57 -07:00
virtual Net *highestNetAbove(Net *net) const;
2023-01-19 11:23:45 -07:00
virtual const Net *highestConnectedNet(Net *net) const;
2018-09-28 08:54:21 -07:00
virtual void connectedNets(Net *net,
2026-01-03 16:59:35 -08:00
NetSet *nets) const;
2018-09-28 08:54:21 -07:00
virtual void connectedNets(const Pin *pin,
2026-01-03 16:59:35 -08:00
NetSet *nets) const;
2018-09-28 08:54:21 -07:00
virtual bool isPower(const Net *net) const = 0;
virtual bool isGround(const Net *net) const = 0;
// Iterate over the pins connected to a net (port, leaf and hierarchical).
virtual NetPinIterator *pinIterator(const Net *net) const = 0;
// Iterate over the terminals connected to a net.
virtual NetTermIterator *termIterator(const Net *net) const = 0;
// Iterate over all of the pins connected to a net and the parent
// and child nets it is hierarchically connected to (port, leaf and
// hierarchical pins).
virtual NetConnectedPinIterator *connectedPinIterator(const Net *net) const;
virtual void visitConnectedPins(const Net *net,
2026-01-03 16:59:35 -08:00
PinVisitor &visitor) const;
2018-09-28 08:54:21 -07:00
// Find driver pins for net.
// Return value is owned by the network.
virtual PinSet *drivers(const Net *net);
int netCount();
int netCount(Instance *inst);
// Iterate over pins connected to nets tied off to logic zero and one.
virtual ConstantPinIterator *constantPinIterator() = 0;
////////////////////////////////////////////////////////////////
// Parse path into first/tail (first hierarchy divider separated token).
2026-03-28 19:13:35 -07:00
void pathNameFirst(std::string_view path_name,
std::string &first,
std::string &tail) const;
2018-09-28 08:54:21 -07:00
// Parse path into head/last (last hierarchy divider separated token).
2026-03-28 19:13:35 -07:00
void pathNameLast(std::string_view path_name,
std::string &head,
std::string &last) const;
2018-09-28 08:54:21 -07:00
// Divider between instance names in a hierarchical path name.
virtual char pathDivider() const { return divider_; }
virtual void setPathDivider(char divider);
// Escape prefix for path dividers in path names.
virtual char pathEscape() const { return escape_; }
virtual void setPathEscape(char escape);
protected:
Pin *findPinLinear(const Instance *instance,
2026-03-28 19:13:35 -07:00
std::string_view port_name) const;
2018-09-28 08:54:21 -07:00
void findInstancesMatching1(const Instance *context,
2026-01-03 16:59:35 -08:00
size_t context_name_length,
const PatternMatch *pattern,
2026-04-15 09:38:10 -07:00
InstanceSeq &matches) const;
2023-01-19 11:23:45 -07:00
void findInstancesHierMatching1(const Instance *instance,
const PatternMatch *pattern,
InstanceSeq &matches) const;
void findNetsMatching(const Instance *context,
const PatternMatch *pattern,
NetSeq &matches) const;
void findNetsHierMatching(const Instance *instance,
const PatternMatch *pattern,
NetSeq &matches) const;
void findPinsHierMatching(const Instance *instance,
const PatternMatch *pattern,
// Return value.
PinSeq &matches) const;
2018-09-28 08:54:21 -07:00
bool isConnected(const Net *net,
2026-01-03 16:59:35 -08:00
const Pin *pin,
NetSet &nets) const;
2018-09-28 08:54:21 -07:00
bool isConnected(const Net *net1,
2026-01-03 16:59:35 -08:00
const Net *net2,
NetSet &nets) const;
2018-09-28 08:54:21 -07:00
int hierarchyLevel(const Net *net) const;
virtual void visitConnectedPins(const Net *net,
2026-01-03 16:59:35 -08:00
PinVisitor &visitor,
NetSet &visited_nets) const;
2018-09-28 08:54:21 -07:00
// Default implementation uses linear search.
virtual void findInstPinsMatching(const Instance *instance,
2023-01-19 11:23:45 -07:00
const PatternMatch *pattern,
// Return value.
PinSeq &matches) const;
2026-04-15 09:38:10 -07:00
void findInstPinsHierMatching(const Instance *instance,
2023-01-19 11:23:45 -07:00
const PatternMatch *pattern,
// Return value.
PinSeq &matches) const;
2018-09-28 08:54:21 -07:00
// findNet using linear search.
Net *findNetLinear(const Instance *instance,
2026-03-28 19:13:35 -07:00
std::string_view net_name) const;
2018-09-28 08:54:21 -07:00
// findNetsMatching using linear search.
2023-01-19 11:23:45 -07:00
NetSeq findNetsMatchingLinear(const Instance *instance,
const PatternMatch *pattern) const;
2018-09-28 08:54:21 -07:00
// Connect/disconnect net/pins should clear the net->drvrs map.
// Incrementally maintaining the map is expensive because
// nets may be connected across hierarchy levels.
2020-03-15 20:05:30 -07:00
void clearNetDrvrPinMap();
2018-09-28 08:54:21 -07:00
2026-04-15 09:38:10 -07:00
LibertyLibrary *default_liberty_{nullptr};
char divider_{'/'};
char escape_{'\\'};
2018-09-28 08:54:21 -07:00
NetDrvrPinsMap net_drvr_pin_map_;
};
// Network API to support network edits.
class NetworkEdit : public Network
{
public:
2026-04-15 09:38:10 -07:00
NetworkEdit() = default;
2026-04-13 14:58:16 -07:00
bool isEditable() const override { return true; }
virtual Port *makePort(Cell *cell,
std::string_view name) = 0;
2018-09-28 08:54:21 -07:00
virtual Instance *makeInstance(LibertyCell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name,
2026-01-03 16:59:35 -08:00
Instance *parent) = 0;
2019-01-20 09:44:24 -08:00
virtual void makePins(Instance *inst) = 0;
virtual void replaceCell(Instance *inst,
2026-01-03 16:59:35 -08:00
Cell *cell) = 0;
2018-09-28 08:54:21 -07:00
// Deleting instance also deletes instance pins.
virtual void deleteInstance(Instance *inst) = 0;
// Connect the port on an instance to a net.
virtual Pin *connect(Instance *inst,
2026-01-03 16:59:35 -08:00
Port *port,
Net *net) = 0;
2019-05-03 08:07:00 -07:00
virtual Pin *connect(Instance *inst,
2026-01-03 16:59:35 -08:00
LibertyPort *port,
Net *net) = 0;
2018-09-28 08:54:21 -07:00
// Disconnect pin from net.
virtual void disconnectPin(Pin *pin) = 0;
virtual void deletePin(Pin *pin) = 0;
2026-03-28 19:13:35 -07:00
virtual Net *makeNet(std::string_view name,
2026-01-03 16:59:35 -08:00
Instance *parent) = 0;
2018-09-28 08:54:21 -07:00
// Deleting net disconnects (but does not delete) net pins.
virtual void deleteNet(Net *net) = 0;
virtual void mergeInto(Net *net,
2026-01-03 16:59:35 -08:00
Net *into_net) = 0;
2018-09-28 08:54:21 -07:00
virtual Net *mergedInto(Net *net) = 0;
};
// Network API to support the Parallax readers.
class NetworkReader : public NetworkEdit
{
public:
// Called before reading a netlist to delete any previously linked network.
virtual void readNetlistBefore() = 0;
2025-01-21 18:35:21 -07:00
virtual void setLinkFunc(LinkNetworkFunc link) = 0;
2026-03-28 19:13:35 -07:00
virtual Library *makeLibrary(std::string_view name,
std::string_view filename) = 0;
2021-08-13 08:37:42 -07:00
virtual void deleteLibrary(Library *library) = 0;
2018-09-28 08:54:21 -07:00
// Search the libraries in read order for a cell by name.
2026-03-28 19:13:35 -07:00
virtual Cell *findAnyCell(std::string_view name) = 0;
2018-09-28 08:54:21 -07:00
virtual Cell *makeCell(Library *library,
2026-03-28 19:13:35 -07:00
std::string_view name,
2026-01-03 16:59:35 -08:00
bool is_leaf,
2026-03-28 19:13:35 -07:00
std::string_view filename) = 0;
2018-09-28 08:54:21 -07:00
virtual void deleteCell(Cell *cell) = 0;
virtual void setName(Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name) = 0;
2018-09-28 08:54:21 -07:00
virtual void setIsLeaf(Cell *cell,
2026-01-03 16:59:35 -08:00
bool is_leaf) = 0;
2022-07-11 08:49:12 -07:00
virtual void setAttribute(Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view key,
std::string_view value) = 0;
2022-07-11 08:49:12 -07:00
virtual void setAttribute(Instance *instance,
2026-03-28 19:13:35 -07:00
std::string_view key,
std::string_view value) = 0;
2018-09-28 08:54:21 -07:00
virtual Port *makeBusPort(Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name,
2026-01-03 16:59:35 -08:00
int from_index,
int to_index) = 0;
2021-08-12 15:50:25 -07:00
virtual void groupBusPorts(Cell *cell,
2026-03-28 19:13:35 -07:00
std::function<bool(std::string_view)> port_msb_first) = 0;
2018-09-28 08:54:21 -07:00
virtual Port *makeBundlePort(Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name,
2026-01-03 16:59:35 -08:00
PortSeq *members) = 0;
2018-09-28 08:54:21 -07:00
virtual Instance *makeInstance(Cell *cell,
2026-03-28 19:13:35 -07:00
std::string_view name,
2026-01-03 16:59:35 -08:00
Instance *parent) = 0;
2018-09-28 08:54:21 -07:00
virtual Pin *makePin(Instance *inst,
2026-01-03 16:59:35 -08:00
Port *port,
Net *net) = 0;
2018-09-28 08:54:21 -07:00
virtual Term *makeTerm(Pin *pin,
2026-01-03 16:59:35 -08:00
Net *net) = 0;
2018-09-28 08:54:21 -07:00
virtual void setDirection(Port *port,
2026-01-03 16:59:35 -08:00
PortDirection *dir) = 0;
2018-09-28 08:54:21 -07:00
// Instance is the network view for cell.
virtual void setCellNetworkView(Cell *cell,
2026-01-03 16:59:35 -08:00
Instance *inst) = 0;
2018-09-28 08:54:21 -07:00
virtual Instance *cellNetworkView(Cell *cell) = 0;
virtual void deleteCellNetworkViews() = 0;
virtual void addConstantNet(Net *net,
2026-01-03 16:59:35 -08:00
LogicValue const_value) = 0;
2018-09-28 08:54:21 -07:00
using NetworkEdit::makeInstance;
};
Instance *
linkReaderNetwork(Cell *top_cell,
2026-01-03 16:59:35 -08:00
bool make_black_boxes,
Report *report,
NetworkReader *network);
2018-09-28 08:54:21 -07:00
// Abstract class for Network::constantPinIterator().
class ConstantPinIterator
{
public:
2026-04-13 14:58:16 -07:00
virtual ~ConstantPinIterator() = default;
2018-09-28 08:54:21 -07:00
virtual bool hasNext() = 0;
2023-01-19 11:23:45 -07:00
virtual void next(const Pin *&pin,
2026-01-03 16:59:35 -08:00
LogicValue &value) = 0;
2018-09-28 08:54:21 -07:00
};
// Implementation class for Network::constantPinIterator().
class NetworkConstantPinIterator : public ConstantPinIterator
{
public:
NetworkConstantPinIterator(const Network *network,
2026-01-03 16:59:35 -08:00
NetSet &zero_nets,
NetSet &one_nets);
2026-04-13 14:58:16 -07:00
bool hasNext() override;
void next(const Pin *&pin, LogicValue &value) override;
2018-09-28 08:54:21 -07:00
private:
void findConstantPins(NetSet &nets,
2026-01-03 16:59:35 -08:00
PinSet &pins);
2018-09-28 08:54:21 -07:00
const Network *network_;
2026-04-15 09:38:10 -07:00
PinSet constant_pins_[2]{PinSet(network_), PinSet(network_)};
2018-09-28 08:54:21 -07:00
LogicValue value_;
2026-01-03 16:59:35 -08:00
PinSet::iterator pin_iter_;
2018-09-28 08:54:21 -07:00
};
// Abstract base class for visitDrvrLoadsThruHierPin visitor.
class HierPinThruVisitor
{
public:
2026-04-13 14:58:16 -07:00
virtual ~HierPinThruVisitor() = default;
2023-01-19 11:23:45 -07:00
virtual void visit(const Pin *drvr,
2026-01-03 16:59:35 -08:00
const Pin *load) = 0;
2018-09-28 08:54:21 -07:00
};
class PinVisitor
{
public:
2026-04-13 14:58:16 -07:00
virtual ~PinVisitor() = default;
2023-01-19 11:23:45 -07:00
virtual void operator()(const Pin *pin) = 0;
2018-09-28 08:54:21 -07:00
};
class FindNetDrvrLoads : public PinVisitor
{
public:
2023-01-19 11:23:45 -07:00
FindNetDrvrLoads(const Pin *drvr_pin,
2026-01-03 16:59:35 -08:00
PinSet &visited_drvrs,
PinSeq &loads,
PinSeq &drvrs,
const Network *network);
2026-04-13 14:58:16 -07:00
void operator()(const Pin *pin) override;
2018-09-28 08:54:21 -07:00
protected:
2023-01-19 11:23:45 -07:00
const Pin *drvr_pin_;
2018-09-28 08:54:21 -07:00
PinSet &visited_drvrs_;
PinSeq &loads_;
PinSeq &drvrs_;
const Network *network_;
};
// Visit driver/loads pins through a hierarcial pin.
void
visitDrvrLoadsThruHierPin(const Pin *hpin,
2026-01-03 16:59:35 -08:00
const Network *network,
HierPinThruVisitor *visitor);
2018-09-28 08:54:21 -07:00
void
2023-01-19 11:23:45 -07:00
visitDrvrLoadsThruNet(const Net *net,
2026-01-03 16:59:35 -08:00
const Network *network,
HierPinThruVisitor *visitor);
2018-09-28 08:54:21 -07:00
char
logicValueString(LogicValue value);
2026-04-13 14:58:16 -07:00
} // namespace sta