diff --git a/CMakeLists.txt b/CMakeLists.txt
index 834fd6f4..d3adc13b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -420,20 +420,24 @@ set_property(SOURCE ${STA_SWIG_FILE}
PROPERTY SWIG_FLAGS
-module sta
-namespace -prefix sta
- -I${STA_HOME}/tcl
+ -I${STA_HOME}/dcalc
+ -I${STA_HOME}/graph
+ -I${STA_HOME}/liberty
+ -I${STA_HOME}/network
-I${STA_HOME}/sdc
-I${STA_HOME}/sdf
- -I${STA_HOME}/dcalc
- -I${STA_HOME}/liberty
-I${STA_HOME}/parasitics
-I${STA_HOME}/power
-I${STA_HOME}/spice
+ -I${STA_HOME}/tcl
-I${STA_HOME}/verilog
)
set(SWIG_FILES
${STA_HOME}/dcalc/DelayCalc.i
+ ${STA_HOME}/graph/Graph.i
${STA_HOME}/liberty/Liberty.i
+ ${STA_HOME}/network/Network.i
${STA_HOME}/parasitics/Parasitics.i
${STA_HOME}/power/Power.i
${STA_HOME}/sdc/Sdc.i
diff --git a/app/StaApp.i b/app/StaApp.i
index 3e192658..e4adf39d 100644
--- a/app/StaApp.i
+++ b/app/StaApp.i
@@ -18,9 +18,11 @@
%include "Exception.i"
%include "StaTclTypes.i"
+%include "Graph.i"
%include "StaTcl.i"
%include "Liberty.i"
%include "Verilog.i"
+%include "Network.i"
%include "NetworkEdit.i"
%include "Sdf.i"
%include "Sdc.i"
diff --git a/graph/Graph.i b/graph/Graph.i
new file mode 100644
index 00000000..5ac3d417
--- /dev/null
+++ b/graph/Graph.i
@@ -0,0 +1,435 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2024, Parallax Software, Inc.
+//
+// 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+%module graph
+
+%{
+#include "Graph.hh"
+#include "FuncExpr.hh"
+#include "TimingRole.hh"
+#include "Liberty.hh"
+#include "Network.hh"
+#include "Clock.hh"
+#include "Corner.hh"
+#include "Search.hh"
+#include "Sta.hh"
+
+namespace sta {
+
+Graph *
+cmdGraph();
+
+} // namespace
+
+using namespace sta;
+
+%}
+
+////////////////////////////////////////////////////////////////
+//
+// Empty class definitions to make swig happy.
+// Private constructor/destructor so swig doesn't emit them.
+//
+////////////////////////////////////////////////////////////////
+
+class Vertex
+{
+private:
+ Vertex();
+ ~Vertex();
+};
+
+class Edge
+{
+private:
+ Edge();
+ ~Edge();
+};
+
+class VertexIterator
+{
+private:
+ VertexIterator();
+ ~VertexIterator();
+};
+
+class VertexInEdgeIterator
+{
+private:
+ VertexInEdgeIterator();
+ ~VertexInEdgeIterator();
+};
+
+class VertexOutEdgeIterator
+{
+private:
+ VertexOutEdgeIterator();
+ ~VertexOutEdgeIterator();
+};
+
+%inline %{
+
+VertexIterator *
+vertex_iterator()
+{
+ return new VertexIterator(cmdGraph());
+}
+
+void
+set_arc_delay(Edge *edge,
+ TimingArc *arc,
+ const Corner *corner,
+ const MinMaxAll *min_max,
+ float delay)
+{
+ cmdGraph();
+ Sta::sta()->setArcDelay(edge, arc, corner, min_max, delay);
+}
+
+void
+set_annotated_slew(Vertex *vertex,
+ const Corner *corner,
+ const MinMaxAll *min_max,
+ const RiseFallBoth *rf,
+ float slew)
+{
+ cmdGraph();
+ Sta::sta()->setAnnotatedSlew(vertex, corner, min_max, rf, slew);
+}
+
+// Remove all delay and slew annotations.
+void
+remove_delay_slew_annotations()
+{
+ cmdGraph();
+ Sta::sta()->removeDelaySlewAnnotations();
+}
+
+%} // inline
+
+%extend Vertex {
+Pin *pin() { return self->pin(); }
+bool is_bidirect_driver() { return self->isBidirectDriver(); }
+int level() { return Sta::sta()->vertexLevel(self); }
+int tag_group_index() { return self->tagGroupIndex(); }
+
+Slew
+slew(const RiseFall *rf,
+ const MinMax *min_max)
+{
+ Sta *sta = Sta::sta();
+ return sta->vertexSlew(self, rf, min_max);
+}
+
+Slew
+slew_corner(const RiseFall *rf,
+ const Corner *corner,
+ const MinMax *min_max)
+{
+ Sta *sta = Sta::sta();
+ return sta->vertexSlew(self, rf, corner, min_max);
+}
+
+VertexOutEdgeIterator *
+out_edge_iterator()
+{
+ return new VertexOutEdgeIterator(self, Sta::sta()->graph());
+}
+
+VertexInEdgeIterator *
+in_edge_iterator()
+{
+ return new VertexInEdgeIterator(self, Sta::sta()->graph());
+}
+
+FloatSeq
+arrivals_clk(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf)
+{
+ Sta *sta = Sta::sta();
+ FloatSeq arrivals;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ arrivals.push_back(delayAsFloat(sta->vertexArrival(self, rf, clk_edge,
+ path_ap, nullptr)));
+ }
+ return arrivals;
+}
+
+StringSeq
+arrivals_clk_delays(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf,
+ int digits)
+{
+ Sta *sta = Sta::sta();
+ StringSeq arrivals;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ arrivals.push_back(delayAsString(sta->vertexArrival(self, rf, clk_edge,
+ path_ap, nullptr),
+ sta, digits));
+ }
+ return arrivals;
+}
+
+FloatSeq
+requireds_clk(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf)
+{
+ Sta *sta = Sta::sta();
+ FloatSeq reqs;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ reqs.push_back(delayAsFloat(sta->vertexRequired(self, rf, clk_edge,
+ path_ap)));
+ }
+ return reqs;
+}
+
+StringSeq
+requireds_clk_delays(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf,
+ int digits)
+{
+ Sta *sta = Sta::sta();
+ StringSeq reqs;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ reqs.push_back(delayAsString(sta->vertexRequired(self, rf, clk_edge, path_ap),
+ sta, digits));
+ }
+ return reqs;
+}
+
+Slack
+slack(MinMax *min_max)
+{
+ Sta *sta = Sta::sta();
+ return sta->vertexSlack(self, min_max);
+}
+
+FloatSeq
+slacks(RiseFall *rf)
+{
+ Sta *sta = Sta::sta();
+ FloatSeq slacks;
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ slacks.push_back(delayAsFloat(sta->vertexSlack(self, rf, path_ap)));
+ }
+ return slacks;
+}
+
+// Slack with respect to a clock rise/fall edge.
+FloatSeq
+slacks_clk(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf)
+{
+ Sta *sta = Sta::sta();
+ FloatSeq slacks;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ slacks.push_back(delayAsFloat(sta->vertexSlack(self, rf, clk_edge,
+ path_ap)));
+ }
+ return slacks;
+}
+
+StringSeq
+slacks_clk_delays(const RiseFall *rf,
+ Clock *clk,
+ const RiseFall *clk_rf,
+ int digits)
+{
+ Sta *sta = Sta::sta();
+ StringSeq slacks;
+ const ClockEdge *clk_edge = nullptr;
+ if (clk)
+ clk_edge = clk->edge(clk_rf);
+ for (auto path_ap : sta->corners()->pathAnalysisPts()) {
+ slacks.push_back(delayAsString(sta->vertexSlack(self, rf, clk_edge,
+ path_ap),
+ sta, digits));
+ }
+ return slacks;
+}
+
+VertexPathIterator *
+path_iterator(const RiseFall *rf,
+ const MinMax *min_max)
+{
+ return Sta::sta()->vertexPathIterator(self, rf, min_max);
+}
+
+bool
+has_downstream_clk_pin()
+{
+ return self->hasDownstreamClkPin();
+}
+
+bool
+is_clock()
+{
+ Sta *sta = Sta::sta();
+ Search *search = sta->search();
+ return search->isClock(self);
+}
+
+bool is_disabled_constraint() { return self->isDisabledConstraint(); }
+
+} // Vertex methods
+
+%extend Edge {
+Vertex *from() { return self->from(Sta::sta()->graph()); }
+Vertex *to() { return self->to(Sta::sta()->graph()); }
+Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); }
+Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); }
+TimingRole *role() { return self->role(); }
+const char *sense() { return timingSenseString(self->sense()); }
+TimingArcSeq &
+timing_arcs() { return self->timingArcSet()->arcs(); }
+bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); }
+bool is_disabled_constraint() { return Sta::sta()->isDisabledConstraint(self);}
+bool is_disabled_constant() { return Sta::sta()->isDisabledConstant(self); }
+bool is_disabled_cond_default()
+{ return Sta::sta()->isDisabledCondDefault(self); }
+PinSet
+disabled_constant_pins() { return Sta::sta()->disabledConstantPins(self); }
+bool is_disabled_bidirect_inst_path()
+{ return Sta::sta()->isDisabledBidirectInstPath(self); }
+bool is_disabled_bidirect_net_path()
+{ return Sta::sta()->isDisabledBidirectNetPath(self); }
+bool is_disabled_preset_clear()
+{ return Sta::sta()->isDisabledPresetClr(self); }
+const char *
+sim_timing_sense(){return timingSenseString(Sta::sta()->simTimingSense(self));}
+
+FloatSeq
+arc_delays(TimingArc *arc)
+{
+ Sta *sta = Sta::sta();
+ FloatSeq delays;
+ for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
+ delays.push_back(delayAsFloat(sta->arcDelay(self, arc, dcalc_ap)));
+ return delays;
+}
+
+StringSeq
+arc_delay_strings(TimingArc *arc,
+ int digits)
+{
+ Sta *sta = Sta::sta();
+ StringSeq delays;
+ for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
+ delays.push_back(delayAsString(sta->arcDelay(self, arc, dcalc_ap),
+ sta, digits));
+ return delays;
+}
+
+bool
+delay_annotated(TimingArc *arc,
+ const Corner *corner,
+ const MinMax *min_max)
+{
+ DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
+ return Sta::sta()->arcDelayAnnotated(self, arc, dcalc_ap);
+}
+
+float
+arc_delay(TimingArc *arc,
+ const Corner *corner,
+ const MinMax *min_max)
+{
+ DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
+ return delayAsFloat(Sta::sta()->arcDelay(self, arc, dcalc_ap));
+}
+
+const char *
+cond()
+{
+ FuncExpr *cond = self->timingArcSet()->cond();
+ if (cond)
+ return cond->asString();
+ else
+ return nullptr;
+}
+
+const char *
+mode_name()
+{
+ return self->timingArcSet()->modeName();
+}
+
+const char *
+mode_value()
+{
+ return self->timingArcSet()->modeValue();
+}
+
+const char *
+latch_d_to_q_en()
+{
+ if (self->role() == TimingRole::latchDtoQ()) {
+ Sta *sta = Sta::sta();
+ const Network *network = sta->cmdNetwork();
+ const Graph *graph = sta->graph();
+ Pin *from_pin = self->from(graph)->pin();
+ Instance *inst = network->instance(from_pin);
+ LibertyCell *lib_cell = network->libertyCell(inst);
+ TimingArcSet *d_q_set = self->timingArcSet();
+ const LibertyPort *enable_port;
+ const FuncExpr *enable_func;
+ const RiseFall *enable_rf;
+ lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf);
+ if (enable_port)
+ return stringPrintTmp("%s %s", enable_port->name(), enable_rf->asString());
+ }
+ return "";
+}
+
+} // Edge methods
+
+%extend VertexIterator {
+bool has_next() { return self->hasNext(); }
+Vertex *next() { return self->next(); }
+void finish() { delete self; }
+}
+
+%extend VertexInEdgeIterator {
+bool has_next() { return self->hasNext(); }
+Edge *next() { return self->next(); }
+void finish() { delete self; }
+}
+
+%extend VertexOutEdgeIterator {
+bool has_next() { return self->hasNext(); }
+Edge *next() { return self->next(); }
+void finish() { delete self; }
+}
diff --git a/liberty/Liberty.i b/liberty/Liberty.i
index 0b570efb..5aefae7d 100644
--- a/liberty/Liberty.i
+++ b/liberty/Liberty.i
@@ -178,6 +178,24 @@ liberty_supply_exists(const char *supply_name)
return lib && lib->supplyExists(supply_name);
}
+LibertyLibraryIterator *
+liberty_library_iterator()
+{
+ return cmdNetwork()->libertyLibraryIterator();
+}
+
+LibertyLibrary *
+find_liberty(const char *name)
+{
+ return cmdNetwork()->findLiberty(name);
+}
+
+LibertyCell *
+find_liberty_cell(const char *name)
+{
+ return cmdNetwork()->findLibertyCell(name);
+}
+
%} // inline
%extend LibertyLibrary {
diff --git a/network/Network.i b/network/Network.i
new file mode 100644
index 00000000..37719c3f
--- /dev/null
+++ b/network/Network.i
@@ -0,0 +1,32 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2024, Parallax Software, Inc.
+//
+// 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+%module network
+
+%{
+#include "Network.hh"
+%}
+
+////////////////////////////////////////////////////////////////
+//
+// Empty class definitions to make swig happy.
+// Private constructor/destructor so swig doesn't emit them.
+//
+////////////////////////////////////////////////////////////////
+
+%inline %{
+
+%} // inline
diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i
index ed5a9dfd..20ecca6f 100644
--- a/tcl/StaTcl.i
+++ b/tcl/StaTcl.i
@@ -274,41 +274,6 @@ private:
~PinConnectedPinIterator();
};
-class Vertex
-{
-private:
- Vertex();
- ~Vertex();
-};
-
-class Edge
-{
-private:
- Edge();
- ~Edge();
-};
-
-class VertexIterator
-{
-private:
- VertexIterator();
- ~VertexIterator();
-};
-
-class VertexInEdgeIterator
-{
-private:
- VertexInEdgeIterator();
- ~VertexInEdgeIterator();
-};
-
-class VertexOutEdgeIterator
-{
-private:
- VertexOutEdgeIterator();
- ~VertexOutEdgeIterator();
-};
-
class PathRef
{
private:
@@ -572,24 +537,6 @@ library_iterator()
return cmdNetwork()->libraryIterator();
}
-LibertyLibrary *
-find_liberty(const char *name)
-{
- return cmdNetwork()->findLiberty(name);
-}
-
-LibertyLibraryIterator *
-liberty_library_iterator()
-{
- return cmdNetwork()->libertyLibraryIterator();
-}
-
-LibertyCell *
-find_liberty_cell(const char *name)
-{
- return cmdNetwork()->findLibertyCell(name);
-}
-
CellSeq
find_cells_matching(const char *pattern,
bool regexp,
@@ -1396,42 +1343,6 @@ unit_scaled_suffix(const char *unit_name)
////////////////////////////////////////////////////////////////
-VertexIterator *
-vertex_iterator()
-{
- return new VertexIterator(cmdGraph());
-}
-
-void
-set_arc_delay(Edge *edge,
- TimingArc *arc,
- const Corner *corner,
- const MinMaxAll *min_max,
- float delay)
-{
- cmdGraph();
- Sta::sta()->setArcDelay(edge, arc, corner, min_max, delay);
-}
-
-void
-set_annotated_slew(Vertex *vertex,
- const Corner *corner,
- const MinMaxAll *min_max,
- const RiseFallBoth *rf,
- float slew)
-{
- cmdGraph();
- Sta::sta()->setAnnotatedSlew(vertex, corner, min_max, rf, slew);
-}
-
-// Remove all delay and slew annotations.
-void
-remove_delay_slew_annotations()
-{
- cmdGraph();
- Sta::sta()->removeDelaySlewAnnotations();
-}
-
CheckErrorSeq &
check_timing_cmd(bool no_input_delay,
bool no_output_delay,
@@ -2976,320 +2887,6 @@ const Pin *next() { return self->next(); }
void finish() { delete self; }
} // NetConnectedPinIterator methods
-%extend Vertex {
-Pin *pin() { return self->pin(); }
-bool is_bidirect_driver() { return self->isBidirectDriver(); }
-int level() { return Sta::sta()->vertexLevel(self); }
-int tag_group_index() { return self->tagGroupIndex(); }
-
-Slew
-slew(const RiseFall *rf,
- const MinMax *min_max)
-{
- Sta *sta = Sta::sta();
- return sta->vertexSlew(self, rf, min_max);
-}
-
-Slew
-slew_corner(const RiseFall *rf,
- const Corner *corner,
- const MinMax *min_max)
-{
- Sta *sta = Sta::sta();
- return sta->vertexSlew(self, rf, corner, min_max);
-}
-
-VertexOutEdgeIterator *
-out_edge_iterator()
-{
- return new VertexOutEdgeIterator(self, Sta::sta()->graph());
-}
-
-VertexInEdgeIterator *
-in_edge_iterator()
-{
- return new VertexInEdgeIterator(self, Sta::sta()->graph());
-}
-
-FloatSeq
-arrivals_clk(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf)
-{
- Sta *sta = Sta::sta();
- FloatSeq arrivals;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- arrivals.push_back(delayAsFloat(sta->vertexArrival(self, rf, clk_edge,
- path_ap, nullptr)));
- }
- return arrivals;
-}
-
-StringSeq
-arrivals_clk_delays(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf,
- int digits)
-{
- Sta *sta = Sta::sta();
- StringSeq arrivals;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- arrivals.push_back(delayAsString(sta->vertexArrival(self, rf, clk_edge,
- path_ap, nullptr),
- sta, digits));
- }
- return arrivals;
-}
-
-FloatSeq
-requireds_clk(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf)
-{
- Sta *sta = Sta::sta();
- FloatSeq reqs;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- reqs.push_back(delayAsFloat(sta->vertexRequired(self, rf, clk_edge,
- path_ap)));
- }
- return reqs;
-}
-
-StringSeq
-requireds_clk_delays(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf,
- int digits)
-{
- Sta *sta = Sta::sta();
- StringSeq reqs;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- reqs.push_back(delayAsString(sta->vertexRequired(self, rf, clk_edge, path_ap),
- sta, digits));
- }
- return reqs;
-}
-
-Slack
-slack(MinMax *min_max)
-{
- Sta *sta = Sta::sta();
- return sta->vertexSlack(self, min_max);
-}
-
-FloatSeq
-slacks(RiseFall *rf)
-{
- Sta *sta = Sta::sta();
- FloatSeq slacks;
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- slacks.push_back(delayAsFloat(sta->vertexSlack(self, rf, path_ap)));
- }
- return slacks;
-}
-
-// Slack with respect to a clock rise/fall edge.
-FloatSeq
-slacks_clk(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf)
-{
- Sta *sta = Sta::sta();
- FloatSeq slacks;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- slacks.push_back(delayAsFloat(sta->vertexSlack(self, rf, clk_edge,
- path_ap)));
- }
- return slacks;
-}
-
-StringSeq
-slacks_clk_delays(const RiseFall *rf,
- Clock *clk,
- const RiseFall *clk_rf,
- int digits)
-{
- Sta *sta = Sta::sta();
- StringSeq slacks;
- const ClockEdge *clk_edge = nullptr;
- if (clk)
- clk_edge = clk->edge(clk_rf);
- for (auto path_ap : sta->corners()->pathAnalysisPts()) {
- slacks.push_back(delayAsString(sta->vertexSlack(self, rf, clk_edge,
- path_ap),
- sta, digits));
- }
- return slacks;
-}
-
-VertexPathIterator *
-path_iterator(const RiseFall *rf,
- const MinMax *min_max)
-{
- return Sta::sta()->vertexPathIterator(self, rf, min_max);
-}
-
-bool
-has_downstream_clk_pin()
-{
- return self->hasDownstreamClkPin();
-}
-
-bool
-is_clock()
-{
- Sta *sta = Sta::sta();
- Search *search = sta->search();
- return search->isClock(self);
-}
-
-bool is_disabled_constraint() { return self->isDisabledConstraint(); }
-
-} // Vertex methods
-
-%extend Edge {
-Vertex *from() { return self->from(Sta::sta()->graph()); }
-Vertex *to() { return self->to(Sta::sta()->graph()); }
-Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); }
-Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); }
-TimingRole *role() { return self->role(); }
-const char *sense() { return timingSenseString(self->sense()); }
-TimingArcSeq &
-timing_arcs() { return self->timingArcSet()->arcs(); }
-bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); }
-bool is_disabled_constraint() { return Sta::sta()->isDisabledConstraint(self);}
-bool is_disabled_constant() { return Sta::sta()->isDisabledConstant(self); }
-bool is_disabled_cond_default()
-{ return Sta::sta()->isDisabledCondDefault(self); }
-PinSet
-disabled_constant_pins() { return Sta::sta()->disabledConstantPins(self); }
-bool is_disabled_bidirect_inst_path()
-{ return Sta::sta()->isDisabledBidirectInstPath(self); }
-bool is_disabled_bidirect_net_path()
-{ return Sta::sta()->isDisabledBidirectNetPath(self); }
-bool is_disabled_preset_clear()
-{ return Sta::sta()->isDisabledPresetClr(self); }
-const char *
-sim_timing_sense(){return timingSenseString(Sta::sta()->simTimingSense(self));}
-
-FloatSeq
-arc_delays(TimingArc *arc)
-{
- Sta *sta = Sta::sta();
- FloatSeq delays;
- for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
- delays.push_back(delayAsFloat(sta->arcDelay(self, arc, dcalc_ap)));
- return delays;
-}
-
-StringSeq
-arc_delay_strings(TimingArc *arc,
- int digits)
-{
- Sta *sta = Sta::sta();
- StringSeq delays;
- for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
- delays.push_back(delayAsString(sta->arcDelay(self, arc, dcalc_ap),
- sta, digits));
- return delays;
-}
-
-bool
-delay_annotated(TimingArc *arc,
- const Corner *corner,
- const MinMax *min_max)
-{
- DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
- return Sta::sta()->arcDelayAnnotated(self, arc, dcalc_ap);
-}
-
-float
-arc_delay(TimingArc *arc,
- const Corner *corner,
- const MinMax *min_max)
-{
- DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
- return delayAsFloat(Sta::sta()->arcDelay(self, arc, dcalc_ap));
-}
-
-const char *
-cond()
-{
- FuncExpr *cond = self->timingArcSet()->cond();
- if (cond)
- return cond->asString();
- else
- return nullptr;
-}
-
-const char *
-mode_name()
-{
- return self->timingArcSet()->modeName();
-}
-
-const char *
-mode_value()
-{
- return self->timingArcSet()->modeValue();
-}
-
-const char *
-latch_d_to_q_en()
-{
- if (self->role() == TimingRole::latchDtoQ()) {
- Sta *sta = Sta::sta();
- const Network *network = sta->cmdNetwork();
- const Graph *graph = sta->graph();
- Pin *from_pin = self->from(graph)->pin();
- Instance *inst = network->instance(from_pin);
- LibertyCell *lib_cell = network->libertyCell(inst);
- TimingArcSet *d_q_set = self->timingArcSet();
- const LibertyPort *enable_port;
- const FuncExpr *enable_func;
- const RiseFall *enable_rf;
- lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf);
- if (enable_port)
- return stringPrintTmp("%s %s", enable_port->name(), enable_rf->asString());
- }
- return "";
-}
-
-} // Edge methods
-
-%extend VertexIterator {
-bool has_next() { return self->hasNext(); }
-Vertex *next() { return self->next(); }
-void finish() { delete self; }
-}
-
-%extend VertexInEdgeIterator {
-bool has_next() { return self->hasNext(); }
-Edge *next() { return self->next(); }
-void finish() { delete self; }
-}
-
-%extend VertexOutEdgeIterator {
-bool has_next() { return self->hasNext(); }
-Edge *next() { return self->next(); }
-void finish() { delete self; }
-}
-
%extend PathEnd {
bool is_unconstrained() { return self->isUnconstrained(); }
bool is_check() { return self->isCheck(); }