Network.i

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2024-07-21 19:14:31 -07:00
parent 1baa0dc907
commit d7f3aabd05
5 changed files with 866 additions and 839 deletions

View File

@ -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(); }

View File

@ -198,6 +198,12 @@ find_liberty_cell(const char *name)
%} // inline
////////////////////////////////////////////////////////////////
//
// Object Methods
//
////////////////////////////////////////////////////////////////
%extend LibertyLibrary {
const char *name() { return self->name(); }

View File

@ -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

140
sdc/Sdc.i
View File

@ -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(); }

View File

@ -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(); }