From d7f3aabd05b3db2930cc6bb4c54336a13d23b806 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 21 Jul 2024 19:14:31 -0700 Subject: [PATCH] Network.i Signed-off-by: James Cherry --- graph/Graph.i | 6 + liberty/Liberty.i | 6 + network/Network.i | 709 ++++++++++++++++++++++++++++++++++++++ sdc/Sdc.i | 140 ++++++++ tcl/StaTcl.i | 844 +--------------------------------------------- 5 files changed, 866 insertions(+), 839 deletions(-) diff --git a/graph/Graph.i b/graph/Graph.i index 5ac3d417..c5a4aa6f 100644 --- a/graph/Graph.i +++ b/graph/Graph.i @@ -120,6 +120,12 @@ remove_delay_slew_annotations() %} // inline +//////////////////////////////////////////////////////////////// +// +// Object Methods +// +//////////////////////////////////////////////////////////////// + %extend Vertex { Pin *pin() { return self->pin(); } bool is_bidirect_driver() { return self->isBidirectDriver(); } diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 5aefae7d..e6508cc5 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -198,6 +198,12 @@ find_liberty_cell(const char *name) %} // inline +//////////////////////////////////////////////////////////////// +// +// Object Methods +// +//////////////////////////////////////////////////////////////// + %extend LibertyLibrary { const char *name() { return self->name(); } diff --git a/network/Network.i b/network/Network.i index 37719c3f..ce9d8451 100644 --- a/network/Network.i +++ b/network/Network.i @@ -27,6 +27,715 @@ // //////////////////////////////////////////////////////////////// +class Library +{ +private: + Library(); + ~Library(); +}; + +class LibraryIterator +{ +private: + LibraryIterator(); + ~LibraryIterator(); +}; + +class Cell +{ +private: + Cell(); + ~Cell(); +}; + +class CellPortIterator +{ +private: + CellPortIterator(); + ~CellPortIterator(); +}; + +class Port +{ +private: + Port(); + ~Port(); +}; + +class PortMemberIterator +{ +private: + PortMemberIterator(); + ~PortMemberIterator(); +}; + +class Instance +{ +private: + Instance(); + ~Instance(); +}; + +class Pin +{ +private: + Pin(); + ~Pin(); +}; + +class Term +{ +private: + Term(); + ~Term(); +}; + +class InstanceChildIterator +{ +private: + InstanceChildIterator(); + ~InstanceChildIterator(); +}; + +class InstancePinIterator +{ +private: + InstancePinIterator(); + ~InstancePinIterator(); +}; + +class InstanceNetIterator +{ +private: + InstanceNetIterator(); + ~InstanceNetIterator(); +}; + +class LeafInstanceIterator +{ +private: + LeafInstanceIterator(); + ~LeafInstanceIterator(); +}; + +class Net +{ +private: + Net(); + ~Net(); +}; + +class NetPinIterator +{ +private: + NetPinIterator(); + ~NetPinIterator(); +}; + +class NetTermIterator +{ +private: + NetTermIterator(); + ~NetTermIterator(); +}; + +class NetConnectedPinIterator +{ +private: + NetConnectedPinIterator(); + ~NetConnectedPinIterator(); +}; + +class PinConnectedPinIterator +{ +private: + PinConnectedPinIterator(); + ~PinConnectedPinIterator(); +}; + %inline %{ +bool +network_is_linked() +{ + return Sta::sta()->cmdNetwork()->isLinked(); +} + +void +set_path_divider(char divider) +{ + cmdNetwork()->setPathDivider(divider); +} + +void +set_current_instance(Instance *inst) +{ + Sta::sta()->setCurrentInstance(inst); +} + +Library * +find_library(const char *name) +{ + return cmdNetwork()->findLibrary(name); +} + +LibraryIterator * +library_iterator() +{ + return cmdNetwork()->libraryIterator(); +} + +CellSeq +find_cells_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Network *network = cmdNetwork(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + CellSeq matches; + LibraryIterator *lib_iter = network->libraryIterator(); + while (lib_iter->hasNext()) { + Library *lib = lib_iter->next(); + CellSeq lib_matches = network->findCellsMatching(lib, &matcher); + for (Cell *match : lib_matches) + matches.push_back(match); + } + delete lib_iter; + return matches; +} + +void +set_cmd_namespace_cmd(const char *namespc) +{ + Sta *sta = Sta::sta(); + if (stringEq(namespc, "sdc")) + sta->setCmdNamespace(CmdNamespace::sdc); + else if (stringEq(namespc, "sta")) + sta->setCmdNamespace(CmdNamespace::sta); + else + sta->report()->warn(2120, "unknown namespace"); +} + +bool +link_design_cmd(const char *top_cell_name) +{ + return Sta::sta()->linkDesign(top_cell_name); +} + +bool +link_make_black_boxes() +{ + return Sta::sta()->linkMakeBlackBoxes(); +} + +void +set_link_make_black_boxes(bool make) +{ + Sta::sta()->setLinkMakeBlackBoxes(make); +} + +Instance * +top_instance() +{ + return cmdLinkedNetwork()->topInstance(); +} + +LeafInstanceIterator * +leaf_instance_iterator() +{ + return cmdLinkedNetwork()->leafInstanceIterator(); +} + +const char * +port_direction(const Port *port) +{ + return cmdLinkedNetwork()->direction(port)->name(); +} + +const char * +pin_direction(const Pin *pin) +{ + return cmdLinkedNetwork()->direction(pin)->name(); +} + +PortSeq +find_ports_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Network *network = cmdLinkedNetwork(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + Cell *top_cell = network->cell(network->topInstance()); + PortSeq matches1 = network->findPortsMatching(top_cell, &matcher); + // Expand bus/bundle ports. + PortSeq matches; + for (const Port *port : matches1) { + if (network->isBus(port) + || network->isBundle(port)) { + PortMemberIterator *member_iter = network->memberIterator(port); + while (member_iter->hasNext()) { + Port *member = member_iter->next(); + matches.push_back(member); + } + delete member_iter; + } + else + matches.push_back(port); + } + return matches; +} + +PinSeq +find_port_pins_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Network *network = cmdLinkedNetwork(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + Instance *top_inst = network->topInstance(); + Cell *top_cell = network->cell(top_inst); + PortSeq ports = network->findPortsMatching(top_cell, &matcher); + PinSeq pins; + for (const Port *port : ports) { + if (network->isBus(port) + || network->isBundle(port)) { + PortMemberIterator *member_iter = network->memberIterator(port); + while (member_iter->hasNext()) { + Port *member = member_iter->next(); + Pin *pin = network->findPin(top_inst, member); + if (pin) + pins.push_back(pin); + } + delete member_iter; + } + else { + Pin *pin = network->findPin(top_inst, port); + if (pin) + pins.push_back(pin); + } + } + return pins; +} + +Pin * +find_pin(const char *path_name) +{ + return cmdLinkedNetwork()->findPin(path_name); +} + +Pin * +get_port_pin(const Port *port) +{ + Network *network = cmdLinkedNetwork(); + return network->findPin(network->topInstance(), port); +} + +PinSeq +find_pins_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Sta *sta = Sta::sta(); + Network *network = cmdLinkedNetwork(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + Instance *current_instance = sta->currentInstance(); + PinSeq matches = network->findPinsMatching(current_instance, &matcher); + return matches; +} + +PinSeq +find_pins_hier_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Sta *sta = Sta::sta(); + Network *network = cmdLinkedNetwork(); + Instance *current_instance = sta->currentInstance(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + PinSeq matches = network->findPinsHierMatching(current_instance, &matcher); + return matches; +} + +Instance * +find_instance(char *path_name) +{ + return cmdLinkedNetwork()->findInstance(path_name); +} + +InstanceSeq +network_leaf_instances() +{ + return cmdLinkedNetwork()->leafInstances(); +} + +InstanceSeq +find_instances_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Sta *sta = Sta::sta(); + Instance *current_instance = sta->currentInstance(); + PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp()); + Network *network = cmdLinkedNetwork(); + InstanceSeq matches = network->findInstancesMatching(current_instance, &matcher); + return matches; +} + +InstanceSeq +find_instances_hier_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Sta *sta = Sta::sta(); + Network *network = cmdLinkedNetwork(); + Instance *current_instance = sta->currentInstance(); + PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp()); + InstanceSeq matches = network->findInstancesHierMatching(current_instance, &matcher); + return matches; +} + +InstanceSet +find_register_instances(ClockSet *clks, + const RiseFallBoth *clk_tr, + bool edge_triggered, + bool latches) +{ + cmdLinkedNetwork(); + InstanceSet insts = Sta::sta()->findRegisterInstances(clks, clk_tr, + edge_triggered, + latches); + delete clks; + return insts; +} + +PinSet +find_register_data_pins(ClockSet *clks, + const RiseFallBoth *clk_tr, + bool edge_triggered, + bool latches) +{ + cmdLinkedNetwork(); + PinSet pins = Sta::sta()->findRegisterDataPins(clks, clk_tr, + edge_triggered, latches); + delete clks; + return pins; +} + +PinSet +find_register_clk_pins(ClockSet *clks, + const RiseFallBoth *clk_tr, + bool edge_triggered, + bool latches) +{ + cmdLinkedNetwork(); + PinSet pins = Sta::sta()->findRegisterClkPins(clks, clk_tr, + edge_triggered, latches); + delete clks; + return pins; +} + +PinSet +find_register_async_pins(ClockSet *clks, + const RiseFallBoth *clk_tr, + bool edge_triggered, + bool latches) +{ + cmdLinkedNetwork(); + PinSet pins = Sta::sta()->findRegisterAsyncPins(clks, clk_tr, + edge_triggered, latches); + delete clks; + return pins; +} + +PinSet +find_register_output_pins(ClockSet *clks, + const RiseFallBoth *clk_tr, + bool edge_triggered, + bool latches) +{ + cmdLinkedNetwork(); + PinSet pins = Sta::sta()->findRegisterOutputPins(clks, clk_tr, + edge_triggered, latches); + delete clks; + return pins; +} + +Net * +find_net(char *path_name) +{ + return cmdLinkedNetwork()->findNet(path_name); +} + +NetSeq +find_nets_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Network *network = cmdLinkedNetwork(); + Instance *current_instance = Sta::sta()->currentInstance(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + NetSeq matches = network->findNetsMatching(current_instance, &matcher); + return matches; +} + +NetSeq +find_nets_hier_matching(const char *pattern, + bool regexp, + bool nocase) +{ + Network *network = cmdLinkedNetwork(); + Instance *current_instance = Sta::sta()->currentInstance(); + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + NetSeq matches = network->findNetsHierMatching(current_instance, &matcher); + return matches; +} + %} // inline + +//////////////////////////////////////////////////////////////// +// +// Object Methods +// +//////////////////////////////////////////////////////////////// + +%extend Library { +const char *name() +{ + return cmdNetwork()->name(self); +} + +Cell * +find_cell(const char *name) +{ + return cmdNetwork()->findCell(self, name); +} + +CellSeq +find_cells_matching(const char *pattern, + bool regexp, + bool nocase) +{ + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + CellSeq matches = cmdNetwork()->findCellsMatching(self, &matcher); + return matches; +} + +} // Library methods + +%extend LibraryIterator { +bool has_next() { return self->hasNext(); } +Library *next() { return self->next(); } +void finish() { delete self; } +} // LibraryIterator methods + +%extend Cell { +const char *name() { return cmdNetwork()->name(self); } +Library *library() { return cmdNetwork()->library(self); } +LibertyCell *liberty_cell() { return cmdNetwork()->libertyCell(self); } +bool is_leaf() { return cmdNetwork()->isLeaf(self); } +CellPortIterator * +port_iterator() { return cmdNetwork()->portIterator(self); } +string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); } + +Port * +find_port(const char *name) +{ + return cmdNetwork()->findPort(self, name); +} + +PortSeq +find_ports_matching(const char *pattern, + bool regexp, + bool nocase) +{ + PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); + return cmdNetwork()->findPortsMatching(self, &matcher); +} + +} // Cell methods + +%extend CellPortIterator { +bool has_next() { return self->hasNext(); } +Port *next() { return self->next(); } +void finish() { delete self; } +} // CellPortIterator methods + +%extend Port { +const char *bus_name() { return cmdNetwork()->busName(self); } +Cell *cell() { return cmdNetwork()->cell(self); } +LibertyPort *liberty_port() { return cmdNetwork()->libertyPort(self); } +bool is_bus() { return cmdNetwork()->isBus(self); } +PortMemberIterator * +member_iterator() { return cmdNetwork()->memberIterator(self); } + +} // Port methods + +%extend PortMemberIterator { +bool has_next() { return self->hasNext(); } +Port *next() { return self->next(); } +void finish() { delete self; } +} // PortMemberIterator methods + +%extend Instance { +Instance *parent() { return cmdLinkedNetwork()->parent(self); } +Cell *cell() { return cmdLinkedNetwork()->cell(self); } +LibertyCell *liberty_cell() { return cmdLinkedNetwork()->libertyCell(self); } +bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); } +InstanceChildIterator * +child_iterator() { return cmdLinkedNetwork()->childIterator(self); } +InstancePinIterator * +pin_iterator() { return cmdLinkedNetwork()->pinIterator(self); } +InstanceNetIterator * +net_iterator() { return cmdLinkedNetwork()->netIterator(self); } +Pin * +find_pin(const char *name) +{ + return cmdLinkedNetwork()->findPin(self, name); +} +string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); } +} // Instance methods + +%extend InstanceChildIterator { +bool has_next() { return self->hasNext(); } +Instance *next() { return self->next(); } +void finish() { delete self; } +} // InstanceChildIterator methods + +%extend LeafInstanceIterator { +bool has_next() { return self->hasNext(); } +Instance *next() { return self->next(); } +void finish() { delete self; } +} // LeafInstanceIterator methods + +%extend InstancePinIterator { +bool has_next() { return self->hasNext(); } +Pin *next() { return self->next(); } +void finish() { delete self; } +} // InstancePinIterator methods + +%extend InstanceNetIterator { +bool has_next() { return self->hasNext(); } +Net *next() { return self->next(); } +void finish() { delete self; } +} // InstanceNetIterator methods + +%extend Pin { +const char *port_name() { return cmdLinkedNetwork()->portName(self); } +Instance *instance() { return cmdLinkedNetwork()->instance(self); } +Net *net() { return cmdLinkedNetwork()->net(self); } +Port *port() { return cmdLinkedNetwork()->port(self); } +Term *term() { return cmdLinkedNetwork()->term(self); } +LibertyPort *liberty_port() { return cmdLinkedNetwork()->libertyPort(self); } +bool is_driver() { return cmdLinkedNetwork()->isDriver(self); } +bool is_load() { return cmdLinkedNetwork()->isLoad(self); } +bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); } +bool is_hierarchical() { return cmdLinkedNetwork()->isHierarchical(self); } +bool is_top_level_port() { return cmdLinkedNetwork()->isTopLevelPort(self); } +PinConnectedPinIterator *connected_pin_iterator() +{ return cmdLinkedNetwork()->connectedPinIterator(self); } + +Vertex ** +vertices() +{ + Vertex *vertex, *vertex_bidirect_drvr; + static Vertex *vertices[3]; + + cmdGraph()->pinVertices(self, vertex, vertex_bidirect_drvr); + vertices[0] = vertex; + vertices[1] = vertex_bidirect_drvr; + vertices[2] = nullptr; + return vertices; +} + +} // Pin methods + +%extend PinConnectedPinIterator { +bool has_next() { return self->hasNext(); } +const Pin *next() { return self->next(); } +void finish() { delete self; } +} // PinConnectedPinIterator methods + +%extend Term { +Net *net() { return cmdLinkedNetwork()->net(self); } +Pin *pin() { return cmdLinkedNetwork()->pin(self); } +} // Term methods + +%extend Net { +Instance *instance() { return cmdLinkedNetwork()->instance(self); } +const Net *highest_connected_net() +{ return cmdLinkedNetwork()->highestConnectedNet(self); } +NetPinIterator *pin_iterator() { return cmdLinkedNetwork()->pinIterator(self);} +NetTermIterator *term_iterator() {return cmdLinkedNetwork()->termIterator(self);} +NetConnectedPinIterator *connected_pin_iterator() +{ return cmdLinkedNetwork()->connectedPinIterator(self); } +bool is_power() { return cmdLinkedNetwork()->isPower(self);} +bool is_ground() { return cmdLinkedNetwork()->isGround(self);} + +float +capacitance(Corner *corner, + const MinMax *min_max) +{ + cmdLinkedNetwork(); + float pin_cap, wire_cap; + Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); + return pin_cap + wire_cap; +} + +float +pin_capacitance(Corner *corner, + const MinMax *min_max) +{ + cmdLinkedNetwork(); + float pin_cap, wire_cap; + Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); + return pin_cap; +} + +float +wire_capacitance(Corner *corner, + const MinMax *min_max) +{ + cmdLinkedNetwork(); + float pin_cap, wire_cap; + Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); + return wire_cap; +} + +// get_ports -of_objects net +PortSeq +ports() +{ + Network *network = cmdLinkedNetwork(); + PortSeq ports; + if (network->isTopInstance(network->instance(self))) { + NetTermIterator *term_iter = network->termIterator(self); + while (term_iter->hasNext()) { + Term *term = term_iter->next(); + Port *port = network->port(network->pin(term)); + ports.push_back(port); + } + delete term_iter; + } + return ports; +} + +} // Net methods + +%extend NetPinIterator { +bool has_next() { return self->hasNext(); } +const Pin *next() { return self->next(); } +void finish() { delete self; } +} // NetPinIterator methods + +%extend NetTermIterator { +bool has_next() { return self->hasNext(); } +const Term *next() { return self->next(); } +void finish() { delete self; } +} // NetTermIterator methods + +%extend NetConnectedPinIterator { +bool has_next() { return self->hasNext(); } +const Pin *next() { return self->next(); } +void finish() { delete self; } +} // NetConnectedPinIterator methods + diff --git a/sdc/Sdc.i b/sdc/Sdc.i index dcdf2db3..23ff34d5 100644 --- a/sdc/Sdc.i +++ b/sdc/Sdc.i @@ -1252,8 +1252,148 @@ remove_constraints() Sta::sta()->removeConstraints(); } +PortSeq +all_inputs_cmd(bool no_clocks) +{ + Sta *sta = Sta::sta(); + cmdLinkedNetwork(); + return sta->sdc()->allInputs(no_clocks); +} + +PortSeq +all_outputs_cmd() +{ + Sta *sta = Sta::sta(); + cmdLinkedNetwork(); + return sta->sdc()->allOutputs(); +} + +PortSeq +filter_ports(const char *property, + const char *op, + const char *pattern, + PortSeq *ports) +{ + PortSeq filtered_ports; + if (ports) { + Sta *sta = Sta::sta(); + bool exact_match = stringEq(op, "=="); + bool pattern_match = stringEq(op, "=~"); + bool not_match = stringEq(op, "!="); + for (const Port *port : *ports) { + PropertyValue value(getProperty(port, property, sta)); + const char *prop = value.stringValue(); + if (prop && + ((exact_match && stringEq(prop, pattern)) + || (not_match && !stringEq(prop, pattern)) + || (pattern_match && patternMatch(pattern, prop)))) + filtered_ports.push_back(port); + } + delete ports; + } + return filtered_ports; +} + +InstanceSeq +filter_insts(const char *property, + const char *op, + const char *pattern, + InstanceSeq *insts) +{ + InstanceSeq filtered_insts; + if (insts) { + Sta *sta = Sta::sta(); + cmdLinkedNetwork(); + bool exact_match = stringEq(op, "=="); + bool pattern_match = stringEq(op, "=~"); + bool not_match = stringEq(op, "!="); + for (const Instance *inst : *insts) { + PropertyValue value(getProperty(inst, property, sta)); + const char *prop = value.stringValue(); + if (prop && + ((exact_match && stringEq(prop, pattern)) + || (not_match && !stringEq(prop, pattern)) + || (pattern_match && patternMatch(pattern, prop)))) + filtered_insts.push_back(inst); + } + delete insts; + } + return filtered_insts; +} + +PinSeq +filter_pins(const char *property, + const char *op, + const char *pattern, + PinSeq *pins) +{ + PinSeq filtered_pins; + if (pins) { + Sta *sta = Sta::sta(); + bool exact_match = stringEq(op, "=="); + bool pattern_match = stringEq(op, "=~"); + bool not_match = stringEq(op, "!="); + for (const Pin *pin : *pins) { + PropertyValue value(getProperty(pin, property, sta)); + const char *prop = value.asString(sta->sdcNetwork()); + if (prop && + ((exact_match && stringEq(prop, pattern)) + || (not_match && !stringEq(prop, pattern)) + || (pattern_match && patternMatch(pattern, prop)))) + filtered_pins.push_back(pin); + } + delete pins; + } + return filtered_pins; +} + +EdgeSeq +filter_timing_arcs(const char *property, + const char *op, + const char *pattern, + EdgeSeq *edges) +{ + Sta *sta = Sta::sta(); + EdgeSeq filtered_edges; + bool exact_match = stringEq(op, "=="); + bool pattern_match = stringEq(op, "=~"); + bool not_match = stringEq(op, "!="); + for (Edge *edge : *edges) { + PropertyValue value(getProperty(edge, property, sta)); + const char *prop = value.stringValue(); + if (prop && + ((exact_match && stringEq(prop, pattern)) + || (not_match && !stringEq(prop, pattern)) + || (pattern_match && patternMatch(pattern, prop)))) + filtered_edges.push_back(edge); + } + delete edges; + return filtered_edges; +} + +void +set_voltage_global(const MinMax *min_max, + float voltage) +{ + Sta::sta()->setVoltage(min_max, voltage); +} + +void +set_voltage_net(const Net *net, + const MinMax *min_max, + float voltage) +{ + Sta::sta()->setVoltage(net, min_max, voltage); +} + %} // inline +//////////////////////////////////////////////////////////////// +// +// Object Methods +// +//////////////////////////////////////////////////////////////// + %extend Clock { float period() { return self->period(); } FloatSeq *waveform() { return self->waveform(); } diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 20ecca6f..8b803ec1 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -16,10 +16,6 @@ //////////////////////////////////////////////////////////////// // -// Most of the TCL SWIG interface code is in this file. This and any -// optional interface code is %included into a final interface file -// used by the application. -// // Define TCL methods for each network object. This works despite the // fact that the underlying implementation does not have class methods // corresponding to the TCL methods defined here. @@ -141,48 +137,6 @@ using namespace sta; // //////////////////////////////////////////////////////////////// -class Library -{ -private: - Library(); - ~Library(); -}; - -class LibraryIterator -{ -private: - LibraryIterator(); - ~LibraryIterator(); -}; - -class Cell -{ -private: - Cell(); - ~Cell(); -}; - -class CellPortIterator -{ -private: - CellPortIterator(); - ~CellPortIterator(); -}; - -class Port -{ -private: - Port(); - ~Port(); -}; - -class PortMemberIterator -{ -private: - PortMemberIterator(); - ~PortMemberIterator(); -}; - class Transition { private: @@ -190,90 +144,6 @@ private: ~Transition(); }; -class Instance -{ -private: - Instance(); - ~Instance(); -}; - -class Pin -{ -private: - Pin(); - ~Pin(); -}; - -class Term -{ -private: - Term(); - ~Term(); -}; - -class InstanceChildIterator -{ -private: - InstanceChildIterator(); - ~InstanceChildIterator(); -}; - -class InstancePinIterator -{ -private: - InstancePinIterator(); - ~InstancePinIterator(); -}; - -class InstanceNetIterator -{ -private: - InstanceNetIterator(); - ~InstanceNetIterator(); -}; - -class LeafInstanceIterator -{ -private: - LeafInstanceIterator(); - ~LeafInstanceIterator(); -}; - -class Net -{ -private: - Net(); - ~Net(); -}; - -class NetPinIterator -{ -private: - NetPinIterator(); - ~NetPinIterator(); -}; - -class NetTermIterator -{ -private: - NetTermIterator(); - ~NetTermIterator(); -}; - -class NetConnectedPinIterator -{ -private: - NetConnectedPinIterator(); - ~NetConnectedPinIterator(); -}; - -class PinConnectedPinIterator -{ -private: - PinConnectedPinIterator(); - ~PinConnectedPinIterator(); -}; - class PathRef { private: @@ -346,6 +216,8 @@ git_sha1() return STA_GIT_SHA1; } +//////////////////////////////////////////////////////////////// + void report_error(int id, const char *msg) @@ -442,6 +314,8 @@ log_end() Sta::sta()->report()->logEnd(); } +//////////////////////////////////////////////////////////////// + void set_debug(const char *what, int level) @@ -507,429 +381,7 @@ fall_short_name() return RiseFall::fall()->shortName(); } -bool -network_is_linked() -{ - return Sta::sta()->cmdNetwork()->isLinked(); -} - -void -set_path_divider(char divider) -{ - cmdNetwork()->setPathDivider(divider); -} - -void -set_current_instance(Instance *inst) -{ - Sta::sta()->setCurrentInstance(inst); -} - -Library * -find_library(const char *name) -{ - return cmdNetwork()->findLibrary(name); -} - -LibraryIterator * -library_iterator() -{ - return cmdNetwork()->libraryIterator(); -} - -CellSeq -find_cells_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Network *network = cmdNetwork(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - CellSeq matches; - LibraryIterator *lib_iter = network->libraryIterator(); - while (lib_iter->hasNext()) { - Library *lib = lib_iter->next(); - CellSeq lib_matches = network->findCellsMatching(lib, &matcher); - for (Cell *match : lib_matches) - matches.push_back(match); - } - delete lib_iter; - return matches; -} - -void -set_cmd_namespace_cmd(const char *namespc) -{ - Sta *sta = Sta::sta(); - if (stringEq(namespc, "sdc")) - sta->setCmdNamespace(CmdNamespace::sdc); - else if (stringEq(namespc, "sta")) - sta->setCmdNamespace(CmdNamespace::sta); - else - sta->report()->warn(2120, "unknown namespace"); -} - -bool -link_design_cmd(const char *top_cell_name) -{ - return Sta::sta()->linkDesign(top_cell_name); -} - -bool -link_make_black_boxes() -{ - return Sta::sta()->linkMakeBlackBoxes(); -} - -void -set_link_make_black_boxes(bool make) -{ - Sta::sta()->setLinkMakeBlackBoxes(make); -} - -Instance * -top_instance() -{ - return cmdLinkedNetwork()->topInstance(); -} - -const char * -port_direction(const Port *port) -{ - return cmdLinkedNetwork()->direction(port)->name(); -} - -const char * -pin_direction(const Pin *pin) -{ - return cmdLinkedNetwork()->direction(pin)->name(); -} - -PortSeq -find_ports_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Network *network = cmdLinkedNetwork(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - Cell *top_cell = network->cell(network->topInstance()); - PortSeq matches1 = network->findPortsMatching(top_cell, &matcher); - // Expand bus/bundle ports. - PortSeq matches; - for (const Port *port : matches1) { - if (network->isBus(port) - || network->isBundle(port)) { - PortMemberIterator *member_iter = network->memberIterator(port); - while (member_iter->hasNext()) { - Port *member = member_iter->next(); - matches.push_back(member); - } - delete member_iter; - } - else - matches.push_back(port); - } - return matches; -} - -PinSeq -find_port_pins_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Network *network = cmdLinkedNetwork(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - Instance *top_inst = network->topInstance(); - Cell *top_cell = network->cell(top_inst); - PortSeq ports = network->findPortsMatching(top_cell, &matcher); - PinSeq pins; - for (const Port *port : ports) { - if (network->isBus(port) - || network->isBundle(port)) { - PortMemberIterator *member_iter = network->memberIterator(port); - while (member_iter->hasNext()) { - Port *member = member_iter->next(); - Pin *pin = network->findPin(top_inst, member); - if (pin) - pins.push_back(pin); - } - delete member_iter; - } - else { - Pin *pin = network->findPin(top_inst, port); - if (pin) - pins.push_back(pin); - } - } - return pins; -} - -Pin * -find_pin(const char *path_name) -{ - return cmdLinkedNetwork()->findPin(path_name); -} - -Pin * -get_port_pin(const Port *port) -{ - Network *network = cmdLinkedNetwork(); - return network->findPin(network->topInstance(), port); -} - -PinSeq -find_pins_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Sta *sta = Sta::sta(); - Network *network = cmdLinkedNetwork(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - Instance *current_instance = sta->currentInstance(); - PinSeq matches = network->findPinsMatching(current_instance, &matcher); - return matches; -} - -PinSeq -find_pins_hier_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Sta *sta = Sta::sta(); - Network *network = cmdLinkedNetwork(); - Instance *current_instance = sta->currentInstance(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - PinSeq matches = network->findPinsHierMatching(current_instance, &matcher); - return matches; -} - -Instance * -find_instance(char *path_name) -{ - return cmdLinkedNetwork()->findInstance(path_name); -} - -InstanceSeq -network_leaf_instances() -{ - return cmdLinkedNetwork()->leafInstances(); -} - -InstanceSeq -find_instances_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Sta *sta = Sta::sta(); - Instance *current_instance = sta->currentInstance(); - PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp()); - Network *network = cmdLinkedNetwork(); - InstanceSeq matches = network->findInstancesMatching(current_instance, &matcher); - return matches; -} - -InstanceSeq -find_instances_hier_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Sta *sta = Sta::sta(); - Network *network = cmdLinkedNetwork(); - Instance *current_instance = sta->currentInstance(); - PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp()); - InstanceSeq matches = network->findInstancesHierMatching(current_instance, &matcher); - return matches; -} - -InstanceSet -find_register_instances(ClockSet *clks, - const RiseFallBoth *clk_tr, - bool edge_triggered, - bool latches) -{ - cmdLinkedNetwork(); - InstanceSet insts = Sta::sta()->findRegisterInstances(clks, clk_tr, - edge_triggered, - latches); - delete clks; - return insts; -} - -PinSet -find_register_data_pins(ClockSet *clks, - const RiseFallBoth *clk_tr, - bool edge_triggered, - bool latches) -{ - cmdLinkedNetwork(); - PinSet pins = Sta::sta()->findRegisterDataPins(clks, clk_tr, - edge_triggered, latches); - delete clks; - return pins; -} - -PinSet -find_register_clk_pins(ClockSet *clks, - const RiseFallBoth *clk_tr, - bool edge_triggered, - bool latches) -{ - cmdLinkedNetwork(); - PinSet pins = Sta::sta()->findRegisterClkPins(clks, clk_tr, - edge_triggered, latches); - delete clks; - return pins; -} - -PinSet -find_register_async_pins(ClockSet *clks, - const RiseFallBoth *clk_tr, - bool edge_triggered, - bool latches) -{ - cmdLinkedNetwork(); - PinSet pins = Sta::sta()->findRegisterAsyncPins(clks, clk_tr, - edge_triggered, latches); - delete clks; - return pins; -} - -PinSet -find_register_output_pins(ClockSet *clks, - const RiseFallBoth *clk_tr, - bool edge_triggered, - bool latches) -{ - cmdLinkedNetwork(); - PinSet pins = Sta::sta()->findRegisterOutputPins(clks, clk_tr, - edge_triggered, latches); - delete clks; - return pins; -} - -Net * -find_net(char *path_name) -{ - return cmdLinkedNetwork()->findNet(path_name); -} - -NetSeq -find_nets_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Network *network = cmdLinkedNetwork(); - Instance *current_instance = Sta::sta()->currentInstance(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - NetSeq matches = network->findNetsMatching(current_instance, &matcher); - return matches; -} - -NetSeq -find_nets_hier_matching(const char *pattern, - bool regexp, - bool nocase) -{ - Network *network = cmdLinkedNetwork(); - Instance *current_instance = Sta::sta()->currentInstance(); - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - NetSeq matches = network->findNetsHierMatching(current_instance, &matcher); - return matches; -} - -PortSeq -all_inputs_cmd(bool no_clocks) -{ - Sta *sta = Sta::sta(); - cmdLinkedNetwork(); - return sta->sdc()->allInputs(no_clocks); -} - -PortSeq -all_outputs_cmd() -{ - Sta *sta = Sta::sta(); - cmdLinkedNetwork(); - return sta->sdc()->allOutputs(); -} - -PortSeq -filter_ports(const char *property, - const char *op, - const char *pattern, - PortSeq *ports) -{ - PortSeq filtered_ports; - if (ports) { - Sta *sta = Sta::sta(); - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - for (const Port *port : *ports) { - PropertyValue value(getProperty(port, property, sta)); - const char *prop = value.stringValue(); - if (prop && - ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)))) - filtered_ports.push_back(port); - } - delete ports; - } - return filtered_ports; -} - -InstanceSeq -filter_insts(const char *property, - const char *op, - const char *pattern, - InstanceSeq *insts) -{ - InstanceSeq filtered_insts; - if (insts) { - Sta *sta = Sta::sta(); - cmdLinkedNetwork(); - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - for (const Instance *inst : *insts) { - PropertyValue value(getProperty(inst, property, sta)); - const char *prop = value.stringValue(); - if (prop && - ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)))) - filtered_insts.push_back(inst); - } - delete insts; - } - return filtered_insts; -} - -PinSeq -filter_pins(const char *property, - const char *op, - const char *pattern, - PinSeq *pins) -{ - PinSeq filtered_pins; - if (pins) { - Sta *sta = Sta::sta(); - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - for (const Pin *pin : *pins) { - PropertyValue value(getProperty(pin, property, sta)); - const char *prop = value.asString(sta->sdcNetwork()); - if (prop && - ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)))) - filtered_pins.push_back(pin); - } - delete pins; - } - return filtered_pins; -} +//////////////////////////////////////////////////////////////// PropertyValue pin_property(const Pin *pin, @@ -1038,12 +490,6 @@ timing_arc_set_property(TimingArcSet *arc_set, return getProperty(arc_set, property, Sta::sta()); } -LeafInstanceIterator * -leaf_instance_iterator() -{ - return cmdLinkedNetwork()->leafInstanceIterator(); -} - //////////////////////////////////////////////////////////////// void @@ -1086,30 +532,6 @@ multi_corner() //////////////////////////////////////////////////////////////// -EdgeSeq -filter_timing_arcs(const char *property, - const char *op, - const char *pattern, - EdgeSeq *edges) -{ - Sta *sta = Sta::sta(); - EdgeSeq filtered_edges; - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - for (Edge *edge : *edges) { - PropertyValue value(getProperty(edge, property, sta)); - const char *prop = value.stringValue(); - if (prop && - ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)))) - filtered_edges.push_back(edge); - } - delete edges; - return filtered_edges; -} - // format_unit functions print with fixed digits and suffix. // Pass value arg as string to support NaNs. const char * @@ -2623,21 +2045,6 @@ endpoint_violation_count(const MinMax *min_max) return Sta::sta()->endpointViolationCount(min_max); } -void -set_voltage_global(const MinMax *min_max, - float voltage) -{ - Sta::sta()->setVoltage(min_max, voltage); -} - -void -set_voltage_net(const Net *net, - const MinMax *min_max, - float voltage) -{ - Sta::sta()->setVoltage(net, min_max, voltage); -} - %} // inline //////////////////////////////////////////////////////////////// @@ -2646,247 +2053,6 @@ set_voltage_net(const Net *net, // //////////////////////////////////////////////////////////////// -%extend Library { -const char *name() -{ - return cmdNetwork()->name(self); -} - -Cell * -find_cell(const char *name) -{ - return cmdNetwork()->findCell(self, name); -} - -CellSeq -find_cells_matching(const char *pattern, - bool regexp, - bool nocase) -{ - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - CellSeq matches = cmdNetwork()->findCellsMatching(self, &matcher); - return matches; -} - -} // Library methods - -%extend LibraryIterator { -bool has_next() { return self->hasNext(); } -Library *next() { return self->next(); } -void finish() { delete self; } -} // LibraryIterator methods - -%extend Cell { -const char *name() { return cmdNetwork()->name(self); } -Library *library() { return cmdNetwork()->library(self); } -LibertyCell *liberty_cell() { return cmdNetwork()->libertyCell(self); } -bool is_leaf() { return cmdNetwork()->isLeaf(self); } -CellPortIterator * -port_iterator() { return cmdNetwork()->portIterator(self); } -string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); } - -Port * -find_port(const char *name) -{ - return cmdNetwork()->findPort(self, name); -} - -PortSeq -find_ports_matching(const char *pattern, - bool regexp, - bool nocase) -{ - PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp()); - return cmdNetwork()->findPortsMatching(self, &matcher); -} - -} // Cell methods - -%extend CellPortIterator { -bool has_next() { return self->hasNext(); } -Port *next() { return self->next(); } -void finish() { delete self; } -} // CellPortIterator methods - -%extend Port { -const char *bus_name() { return cmdNetwork()->busName(self); } -Cell *cell() { return cmdNetwork()->cell(self); } -LibertyPort *liberty_port() { return cmdNetwork()->libertyPort(self); } -bool is_bus() { return cmdNetwork()->isBus(self); } -PortMemberIterator * -member_iterator() { return cmdNetwork()->memberIterator(self); } - -} // Port methods - -%extend PortMemberIterator { -bool has_next() { return self->hasNext(); } -Port *next() { return self->next(); } -void finish() { delete self; } -} // PortMemberIterator methods - -%extend Instance { -Instance *parent() { return cmdLinkedNetwork()->parent(self); } -Cell *cell() { return cmdLinkedNetwork()->cell(self); } -LibertyCell *liberty_cell() { return cmdLinkedNetwork()->libertyCell(self); } -bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); } -InstanceChildIterator * -child_iterator() { return cmdLinkedNetwork()->childIterator(self); } -InstancePinIterator * -pin_iterator() { return cmdLinkedNetwork()->pinIterator(self); } -InstanceNetIterator * -net_iterator() { return cmdLinkedNetwork()->netIterator(self); } -Pin * -find_pin(const char *name) -{ - return cmdLinkedNetwork()->findPin(self, name); -} -string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); } -} // Instance methods - -%extend InstanceChildIterator { -bool has_next() { return self->hasNext(); } -Instance *next() { return self->next(); } -void finish() { delete self; } -} // InstanceChildIterator methods - -%extend LeafInstanceIterator { -bool has_next() { return self->hasNext(); } -Instance *next() { return self->next(); } -void finish() { delete self; } -} // LeafInstanceIterator methods - -%extend InstancePinIterator { -bool has_next() { return self->hasNext(); } -Pin *next() { return self->next(); } -void finish() { delete self; } -} // InstancePinIterator methods - -%extend InstanceNetIterator { -bool has_next() { return self->hasNext(); } -Net *next() { return self->next(); } -void finish() { delete self; } -} // InstanceNetIterator methods - -%extend Pin { -const char *port_name() { return cmdLinkedNetwork()->portName(self); } -Instance *instance() { return cmdLinkedNetwork()->instance(self); } -Net *net() { return cmdLinkedNetwork()->net(self); } -Port *port() { return cmdLinkedNetwork()->port(self); } -Term *term() { return cmdLinkedNetwork()->term(self); } -LibertyPort *liberty_port() { return cmdLinkedNetwork()->libertyPort(self); } -bool is_driver() { return cmdLinkedNetwork()->isDriver(self); } -bool is_load() { return cmdLinkedNetwork()->isLoad(self); } -bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); } -bool is_hierarchical() { return cmdLinkedNetwork()->isHierarchical(self); } -bool is_top_level_port() { return cmdLinkedNetwork()->isTopLevelPort(self); } -PinConnectedPinIterator *connected_pin_iterator() -{ return cmdLinkedNetwork()->connectedPinIterator(self); } - -Vertex ** -vertices() -{ - Vertex *vertex, *vertex_bidirect_drvr; - static Vertex *vertices[3]; - - cmdGraph()->pinVertices(self, vertex, vertex_bidirect_drvr); - vertices[0] = vertex; - vertices[1] = vertex_bidirect_drvr; - vertices[2] = nullptr; - return vertices; -} - -} // Pin methods - -%extend PinConnectedPinIterator { -bool has_next() { return self->hasNext(); } -const Pin *next() { return self->next(); } -void finish() { delete self; } -} // PinConnectedPinIterator methods - -%extend Term { -Net *net() { return cmdLinkedNetwork()->net(self); } -Pin *pin() { return cmdLinkedNetwork()->pin(self); } -} // Term methods - -%extend Net { -Instance *instance() { return cmdLinkedNetwork()->instance(self); } -const Net *highest_connected_net() -{ return cmdLinkedNetwork()->highestConnectedNet(self); } -NetPinIterator *pin_iterator() { return cmdLinkedNetwork()->pinIterator(self);} -NetTermIterator *term_iterator() {return cmdLinkedNetwork()->termIterator(self);} -NetConnectedPinIterator *connected_pin_iterator() -{ return cmdLinkedNetwork()->connectedPinIterator(self); } -bool is_power() { return cmdLinkedNetwork()->isPower(self);} -bool is_ground() { return cmdLinkedNetwork()->isGround(self);} - -float -capacitance(Corner *corner, - const MinMax *min_max) -{ - cmdLinkedNetwork(); - float pin_cap, wire_cap; - Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); - return pin_cap + wire_cap; -} - -float -pin_capacitance(Corner *corner, - const MinMax *min_max) -{ - cmdLinkedNetwork(); - float pin_cap, wire_cap; - Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); - return pin_cap; -} - -float -wire_capacitance(Corner *corner, - const MinMax *min_max) -{ - cmdLinkedNetwork(); - float pin_cap, wire_cap; - Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap); - return wire_cap; -} - -// get_ports -of_objects net -PortSeq -ports() -{ - Network *network = cmdLinkedNetwork(); - PortSeq ports; - if (network->isTopInstance(network->instance(self))) { - NetTermIterator *term_iter = network->termIterator(self); - while (term_iter->hasNext()) { - Term *term = term_iter->next(); - Port *port = network->port(network->pin(term)); - ports.push_back(port); - } - delete term_iter; - } - return ports; -} - -} // Net methods - -%extend NetPinIterator { -bool has_next() { return self->hasNext(); } -const Pin *next() { return self->next(); } -void finish() { delete self; } -} // NetPinIterator methods - -%extend NetTermIterator { -bool has_next() { return self->hasNext(); } -const Term *next() { return self->next(); } -void finish() { delete self; } -} // NetTermIterator methods - -%extend NetConnectedPinIterator { -bool has_next() { return self->hasNext(); } -const Pin *next() { return self->next(); } -void finish() { delete self; } -} // NetConnectedPinIterator methods - %extend PathEnd { bool is_unconstrained() { return self->isUnconstrained(); } bool is_check() { return self->isCheck(); }