move sdc/liberty code out of StaTcl.i
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
0e0a0624fe
commit
bd42dc5596
|
|
@ -27,6 +27,83 @@ using namespace sta;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Empty class definitions to make swig happy.
|
||||||
|
// Private constructor/destructor so swig doesn't emit them.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class LibertyLibrary
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyLibrary();
|
||||||
|
~LibertyLibrary();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibertyLibraryIterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyLibraryIterator();
|
||||||
|
~LibertyLibraryIterator();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibertyCell
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyCell();
|
||||||
|
~LibertyCell();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibertyPort
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyPort();
|
||||||
|
~LibertyPort();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibertyCellPortIterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyCellPortIterator();
|
||||||
|
~LibertyCellPortIterator();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LibertyPortMemberIterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LibertyPortMemberIterator();
|
||||||
|
~LibertyPortMemberIterator();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimingArcSet
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TimingArcSet();
|
||||||
|
~TimingArcSet();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimingArc
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TimingArc();
|
||||||
|
~TimingArc();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Wireload
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Wireload();
|
||||||
|
~Wireload();
|
||||||
|
};
|
||||||
|
|
||||||
|
class WireloadSelection
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
WireloadSelection();
|
||||||
|
~WireloadSelection();
|
||||||
|
};
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -103,3 +180,333 @@ liberty_supply_exists(const char *supply_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
%} // inline
|
%} // inline
|
||||||
|
|
||||||
|
%extend LibertyLibrary {
|
||||||
|
const char *name() { return self->name(); }
|
||||||
|
|
||||||
|
LibertyCell *
|
||||||
|
find_liberty_cell(const char *name)
|
||||||
|
{
|
||||||
|
return self->findLibertyCell(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyCellSeq
|
||||||
|
find_liberty_cells_matching(const char *pattern,
|
||||||
|
bool regexp,
|
||||||
|
bool nocase)
|
||||||
|
{
|
||||||
|
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
|
||||||
|
return self->findLibertyCellsMatching(&matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wireload *
|
||||||
|
find_wireload(const char *model_name)
|
||||||
|
{
|
||||||
|
return self->findWireload(model_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
WireloadSelection *
|
||||||
|
find_wireload_selection(const char *selection_name)
|
||||||
|
{
|
||||||
|
return self->findWireloadSelection(selection_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
OperatingConditions *
|
||||||
|
find_operating_conditions(const char *op_cond_name)
|
||||||
|
{
|
||||||
|
return self->findOperatingConditions(op_cond_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
OperatingConditions *
|
||||||
|
default_operating_conditions()
|
||||||
|
{
|
||||||
|
return self->defaultOperatingConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // LibertyLibrary methods
|
||||||
|
|
||||||
|
%extend LibertyCell {
|
||||||
|
const char *name() { return self->name(); }
|
||||||
|
bool is_leaf() { return self->isLeaf(); }
|
||||||
|
bool is_buffer() { return self->isBuffer(); }
|
||||||
|
bool is_inverter() { return self->isInverter(); }
|
||||||
|
LibertyLibrary *liberty_library() { return self->libertyLibrary(); }
|
||||||
|
Cell *cell() { return reinterpret_cast<Cell*>(self); }
|
||||||
|
LibertyPort *
|
||||||
|
find_liberty_port(const char *name)
|
||||||
|
{
|
||||||
|
return self->findLibertyPort(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyPortSeq
|
||||||
|
find_liberty_ports_matching(const char *pattern,
|
||||||
|
bool regexp,
|
||||||
|
bool nocase)
|
||||||
|
{
|
||||||
|
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
|
||||||
|
return self->findLibertyPortsMatching(&matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyCellPortIterator *
|
||||||
|
liberty_port_iterator() { return new LibertyCellPortIterator(self); }
|
||||||
|
|
||||||
|
const TimingArcSetSeq &
|
||||||
|
timing_arc_sets()
|
||||||
|
{
|
||||||
|
return self->timingArcSets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ensure_voltage_waveforms()
|
||||||
|
{
|
||||||
|
Corner *corner = Sta::sta()->cmdCorner();
|
||||||
|
DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max());
|
||||||
|
self->ensureVoltageWaveforms(dcalc_ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // LibertyCell methods
|
||||||
|
|
||||||
|
%extend LibertyPort {
|
||||||
|
const char *bus_name() { return self->busName(); }
|
||||||
|
Cell *cell() { return self->cell(); }
|
||||||
|
bool is_bus() { return self->isBus(); }
|
||||||
|
LibertyPortMemberIterator *
|
||||||
|
member_iterator() { return new LibertyPortMemberIterator(self); }
|
||||||
|
|
||||||
|
const char *
|
||||||
|
function()
|
||||||
|
{
|
||||||
|
FuncExpr *func = self->function();
|
||||||
|
if (func)
|
||||||
|
return func->asString();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
tristate_enable()
|
||||||
|
{
|
||||||
|
FuncExpr *enable = self->tristateEnable();
|
||||||
|
if (enable)
|
||||||
|
return enable->asString();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
capacitance(Corner *corner,
|
||||||
|
const MinMax *min_max)
|
||||||
|
{
|
||||||
|
Sta *sta = Sta::sta();
|
||||||
|
return sta->capacitance(self, corner, min_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_direction(const char *dir)
|
||||||
|
{
|
||||||
|
self->setDirection(PortDirection::find(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // LibertyPort methods
|
||||||
|
|
||||||
|
%extend TimingArcSet {
|
||||||
|
LibertyPort *from() { return self->from(); }
|
||||||
|
LibertyPort *to() { return self->to(); }
|
||||||
|
TimingRole *role() { return self->role(); }
|
||||||
|
const char *sdf_cond() { return self->sdfCond(); }
|
||||||
|
|
||||||
|
const char *
|
||||||
|
full_name()
|
||||||
|
{
|
||||||
|
const char *from = self->from()->name();
|
||||||
|
const char *to = self->to()->name();
|
||||||
|
const char *cell_name = self->libertyCell()->name();
|
||||||
|
return stringPrintTmp("%s %s -> %s",
|
||||||
|
cell_name,
|
||||||
|
from,
|
||||||
|
to);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingArcSeq &
|
||||||
|
timing_arcs() { return self->arcs(); }
|
||||||
|
|
||||||
|
} // TimingArcSet methods
|
||||||
|
|
||||||
|
%extend TimingArc {
|
||||||
|
LibertyPort *from() { return self->from(); }
|
||||||
|
LibertyPort *to() { return self->to(); }
|
||||||
|
Transition *from_edge() { return self->fromEdge(); }
|
||||||
|
const char *from_edge_name() { return self->fromEdge()->asRiseFall()->name(); }
|
||||||
|
Transition *to_edge() { return self->toEdge(); }
|
||||||
|
const char *to_edge_name() { return self->toEdge()->asRiseFall()->name(); }
|
||||||
|
TimingRole *role() { return self->role(); }
|
||||||
|
|
||||||
|
float
|
||||||
|
time_voltage(float in_slew,
|
||||||
|
float load_cap,
|
||||||
|
float time)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms)
|
||||||
|
return waveforms->timeVoltage(in_slew, load_cap, time);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
time_current(float in_slew,
|
||||||
|
float load_cap,
|
||||||
|
float time)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms)
|
||||||
|
return waveforms->timeCurrent(in_slew, load_cap, time);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
voltage_current(float in_slew,
|
||||||
|
float load_cap,
|
||||||
|
float voltage)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms)
|
||||||
|
return waveforms->voltageCurrent(in_slew, load_cap, voltage);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
voltage_time(float in_slew,
|
||||||
|
float load_cap,
|
||||||
|
float voltage)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms)
|
||||||
|
return waveforms->voltageTime(in_slew, load_cap, voltage);
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Table1
|
||||||
|
voltage_waveform(float in_slew,
|
||||||
|
float load_cap)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
Table1 waveform = waveforms->voltageWaveform(in_slew, load_cap);
|
||||||
|
return waveform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Table1();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Table1 *
|
||||||
|
voltage_waveform_raw(float in_slew,
|
||||||
|
float load_cap)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
const Table1 *waveform = waveforms->voltageWaveformRaw(in_slew, load_cap);
|
||||||
|
return waveform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Table1
|
||||||
|
current_waveform(float in_slew,
|
||||||
|
float load_cap)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
Table1 waveform = waveforms->currentWaveform(in_slew, load_cap);
|
||||||
|
return waveform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Table1();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Table1 *
|
||||||
|
current_waveform_raw(float in_slew,
|
||||||
|
float load_cap)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
const Table1 *waveform = waveforms->currentWaveformRaw(in_slew, load_cap);
|
||||||
|
return waveform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Table1
|
||||||
|
voltage_current_waveform(float in_slew,
|
||||||
|
float load_cap)
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
Table1 waveform = waveforms->voltageCurrentWaveform(in_slew, load_cap);
|
||||||
|
return waveform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Table1();
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
final_resistance()
|
||||||
|
{
|
||||||
|
GateTableModel *gate_model = self->gateTableModel();
|
||||||
|
if (gate_model) {
|
||||||
|
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||||
|
if (waveforms) {
|
||||||
|
return waveforms->finalResistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // TimingArc methods
|
||||||
|
|
||||||
|
%extend OperatingConditions {
|
||||||
|
float process() { return self->process(); }
|
||||||
|
float voltage() { return self->voltage(); }
|
||||||
|
float temperature() { return self->temperature(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
%extend LibertyLibraryIterator {
|
||||||
|
bool has_next() { return self->hasNext(); }
|
||||||
|
LibertyLibrary *next() { return self->next(); }
|
||||||
|
void finish() { delete self; }
|
||||||
|
} // LibertyLibraryIterator methods
|
||||||
|
|
||||||
|
%extend LibertyCellPortIterator {
|
||||||
|
bool has_next() { return self->hasNext(); }
|
||||||
|
LibertyPort *next() { return self->next(); }
|
||||||
|
void finish() { delete self; }
|
||||||
|
} // LibertyCellPortIterator methods
|
||||||
|
|
||||||
|
%extend LibertyPortMemberIterator {
|
||||||
|
bool has_next() { return self->hasNext(); }
|
||||||
|
LibertyPort *next() { return self->next(); }
|
||||||
|
void finish() { delete self; }
|
||||||
|
} // LibertyPortMemberIterator methods
|
||||||
|
|
|
||||||
206
sdc/Sdc.i
206
sdc/Sdc.i
|
|
@ -19,14 +19,77 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
|
#include "Clock.hh"
|
||||||
|
#include "PortDelay.hh"
|
||||||
#include "Sta.hh"
|
#include "Sta.hh"
|
||||||
|
|
||||||
using namespace sta;
|
using namespace sta;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Empty class definitions to make swig happy.
|
||||||
|
// Private constructor/destructor so swig doesn't emit them.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class Clock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Clock();
|
||||||
|
~Clock();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClockEdge
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ClockEdge();
|
||||||
|
~ClockEdge();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExceptionFrom
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ExceptionFrom();
|
||||||
|
~ExceptionFrom();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExceptionThru
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ExceptionThru();
|
||||||
|
~ExceptionThru();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExceptionTo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ExceptionTo();
|
||||||
|
~ExceptionTo();
|
||||||
|
};
|
||||||
|
|
||||||
|
class OperatingConditions
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
OperatingConditions();
|
||||||
|
~OperatingConditions();
|
||||||
|
};
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
|
void
|
||||||
|
write_sdc_cmd(const char *filename,
|
||||||
|
bool leaf,
|
||||||
|
bool compatible,
|
||||||
|
int digits,
|
||||||
|
bool gzip,
|
||||||
|
bool no_timestamp)
|
||||||
|
{
|
||||||
|
cmdLinkedNetwork();
|
||||||
|
Sta::sta()->writeSdc(filename, leaf, compatible, digits, gzip, no_timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_analysis_type_cmd(const char *analysis_type)
|
set_analysis_type_cmd(const char *analysis_type)
|
||||||
{
|
{
|
||||||
|
|
@ -627,6 +690,21 @@ unset_disable_clock_gating_check_pin(Pin *pin)
|
||||||
Sta::sta()->removeDisableClockGatingCheck(pin);
|
Sta::sta()->removeDisableClockGatingCheck(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeSeq
|
||||||
|
disabled_edges_sorted()
|
||||||
|
{
|
||||||
|
cmdLinkedNetwork();
|
||||||
|
return Sta::sta()->disabledEdgesSorted();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
timing_arc_disabled(Edge *edge,
|
||||||
|
TimingArc *arc)
|
||||||
|
{
|
||||||
|
Graph *graph = Sta::sta()->graph();
|
||||||
|
return !searchThru(edge, arc, graph);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
make_false_path(ExceptionFrom *from,
|
make_false_path(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
|
|
@ -767,6 +845,72 @@ check_exception_to_pins(ExceptionTo *to,
|
||||||
Sta::sta()->checkExceptionToPins(to, file, line);
|
Sta::sta()->checkExceptionToPins(to, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClockGroups *
|
||||||
|
make_clock_groups(const char *name,
|
||||||
|
bool logically_exclusive,
|
||||||
|
bool physically_exclusive,
|
||||||
|
bool asynchronous,
|
||||||
|
bool allow_paths,
|
||||||
|
const char *comment)
|
||||||
|
{
|
||||||
|
return Sta::sta()->makeClockGroups(name, logically_exclusive,
|
||||||
|
physically_exclusive, asynchronous,
|
||||||
|
allow_paths, comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clock_groups_make_group(ClockGroups *clk_groups,
|
||||||
|
ClockSet *clks)
|
||||||
|
{
|
||||||
|
Sta::sta()->makeClockGroup(clk_groups, clks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unset_clock_groups_logically_exclusive(const char *name)
|
||||||
|
{
|
||||||
|
Sta::sta()->removeClockGroupsLogicallyExclusive(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unset_clock_groups_physically_exclusive(const char *name)
|
||||||
|
{
|
||||||
|
Sta::sta()->removeClockGroupsPhysicallyExclusive(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unset_clock_groups_asynchronous(const char *name)
|
||||||
|
{
|
||||||
|
Sta::sta()->removeClockGroupsAsynchronous(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugging function.
|
||||||
|
bool
|
||||||
|
same_clk_group(Clock *clk1,
|
||||||
|
Clock *clk2)
|
||||||
|
{
|
||||||
|
Sta *sta = Sta::sta();
|
||||||
|
Sdc *sdc = sta->sdc();
|
||||||
|
return sdc->sameClockGroupExplicit(clk1, clk2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_clock_sense_cmd(PinSet *pins,
|
||||||
|
ClockSet *clks,
|
||||||
|
bool positive,
|
||||||
|
bool negative,
|
||||||
|
bool stop_propagation)
|
||||||
|
{
|
||||||
|
Sta *sta = Sta::sta();
|
||||||
|
if (positive)
|
||||||
|
sta->setClockSense(pins, clks, ClockSense::positive);
|
||||||
|
else if (negative)
|
||||||
|
sta->setClockSense(pins, clks, ClockSense::negative);
|
||||||
|
else if (stop_propagation)
|
||||||
|
sta->setClockSense(pins, clks, ClockSense::stop);
|
||||||
|
else
|
||||||
|
sta->report()->critical(1577, "unknown clock sense");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_input_slew_cmd(Port *port,
|
set_input_slew_cmd(Port *port,
|
||||||
const RiseFallBoth *rf,
|
const RiseFallBoth *rf,
|
||||||
|
|
@ -1073,4 +1217,66 @@ is_genclk_src(const Pin *pin)
|
||||||
return search->isGenClkSrc(vertex);
|
return search->isGenClkSrc(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
pin_is_constrained(Pin *pin)
|
||||||
|
{
|
||||||
|
return Sta::sta()->sdc()->isConstrained(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
instance_is_constrained(Instance *inst)
|
||||||
|
{
|
||||||
|
return Sta::sta()->sdc()->isConstrained(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
net_is_constrained(Net *net)
|
||||||
|
{
|
||||||
|
return Sta::sta()->sdc()->isConstrained(net);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
clk_thru_tristate_enabled()
|
||||||
|
{
|
||||||
|
return Sta::sta()->clkThruTristateEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_clk_thru_tristate_enabled(bool enabled)
|
||||||
|
{
|
||||||
|
Sta::sta()->setClkThruTristateEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
remove_constraints()
|
||||||
|
{
|
||||||
|
Sta::sta()->removeConstraints();
|
||||||
|
}
|
||||||
|
|
||||||
%} // inline
|
%} // inline
|
||||||
|
|
||||||
|
%extend Clock {
|
||||||
|
float period() { return self->period(); }
|
||||||
|
FloatSeq *waveform() { return self->waveform(); }
|
||||||
|
float time(RiseFall *rf) { return self->edge(rf)->time(); }
|
||||||
|
bool is_generated() { return self->isGenerated(); }
|
||||||
|
bool waveform_valid() { return self->waveformValid(); }
|
||||||
|
bool is_virtual() { return self->isVirtual(); }
|
||||||
|
bool is_propagated() { return self->isPropagated(); }
|
||||||
|
const PinSet &sources() { return self->pins(); }
|
||||||
|
|
||||||
|
float
|
||||||
|
slew(const RiseFall *rf,
|
||||||
|
const MinMax *min_max)
|
||||||
|
{
|
||||||
|
return self->slew(rf, min_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
%extend ClockEdge {
|
||||||
|
Clock *clock() { return self->clock(); }
|
||||||
|
RiseFall *transition() { return self->transition(); }
|
||||||
|
float time() { return self->time(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
598
tcl/StaTcl.i
598
tcl/StaTcl.i
|
|
@ -52,8 +52,6 @@
|
||||||
#include "Wireload.hh"
|
#include "Wireload.hh"
|
||||||
#include "PortDirection.hh"
|
#include "PortDirection.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
#include "Clock.hh"
|
|
||||||
#include "PortDelay.hh"
|
|
||||||
#include "ExceptionPath.hh"
|
#include "ExceptionPath.hh"
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
#include "Graph.hh"
|
#include "Graph.hh"
|
||||||
|
|
@ -172,13 +170,6 @@ private:
|
||||||
~CellPortIterator();
|
~CellPortIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibertyCellPortIterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyCellPortIterator();
|
|
||||||
~LibertyCellPortIterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Port
|
class Port
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -193,69 +184,6 @@ private:
|
||||||
~PortMemberIterator();
|
~PortMemberIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibertyLibrary
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyLibrary();
|
|
||||||
~LibertyLibrary();
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibertyLibraryIterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyLibraryIterator();
|
|
||||||
~LibertyLibraryIterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibertyCell
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyCell();
|
|
||||||
~LibertyCell();
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibertyPort
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyPort();
|
|
||||||
~LibertyPort();
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibertyPortMemberIterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyPortMemberIterator();
|
|
||||||
~LibertyPortMemberIterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TimingArcSet
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
TimingArcSet();
|
|
||||||
~TimingArcSet();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TimingArc
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
TimingArc();
|
|
||||||
~TimingArc();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Wireload
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Wireload();
|
|
||||||
~Wireload();
|
|
||||||
};
|
|
||||||
|
|
||||||
class WireloadSelection
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
WireloadSelection();
|
|
||||||
~WireloadSelection();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Transition
|
class Transition
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -347,20 +275,6 @@ private:
|
||||||
~PinConnectedPinIterator();
|
~PinConnectedPinIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Clock
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Clock();
|
|
||||||
~Clock();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClockEdge
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ClockEdge();
|
|
||||||
~ClockEdge();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Vertex
|
class Vertex
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -438,34 +352,6 @@ private:
|
||||||
~VertexPathIterator();
|
~VertexPathIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExceptionFrom
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ExceptionFrom();
|
|
||||||
~ExceptionFrom();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExceptionThru
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ExceptionThru();
|
|
||||||
~ExceptionThru();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExceptionTo
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ExceptionTo();
|
|
||||||
~ExceptionTo();
|
|
||||||
};
|
|
||||||
|
|
||||||
class OperatingConditions
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
OperatingConditions();
|
|
||||||
~OperatingConditions();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Corner
|
class Corner
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -657,36 +543,6 @@ fall_short_name()
|
||||||
return RiseFall::fall()->shortName();
|
return RiseFall::fall()->shortName();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
pin_is_constrained(Pin *pin)
|
|
||||||
{
|
|
||||||
return Sta::sta()->sdc()->isConstrained(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
instance_is_constrained(Instance *inst)
|
|
||||||
{
|
|
||||||
return Sta::sta()->sdc()->isConstrained(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
net_is_constrained(Net *net)
|
|
||||||
{
|
|
||||||
return Sta::sta()->sdc()->isConstrained(net);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
clk_thru_tristate_enabled()
|
|
||||||
{
|
|
||||||
return Sta::sta()->clkThruTristateEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_clk_thru_tristate_enabled(bool enabled)
|
|
||||||
{
|
|
||||||
Sta::sta()->setClkThruTristateEnabled(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
network_is_linked()
|
network_is_linked()
|
||||||
{
|
{
|
||||||
|
|
@ -1918,12 +1774,6 @@ delete_path_ref(PathRef *path)
|
||||||
delete path;
|
delete path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
remove_constraints()
|
|
||||||
{
|
|
||||||
Sta::sta()->removeConstraints();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
report_path_cmd(PathRef *path)
|
report_path_cmd(PathRef *path)
|
||||||
{
|
{
|
||||||
|
|
@ -2421,25 +2271,6 @@ report_capacitance_limit_verbose(Pin *pin,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
EdgeSeq
|
|
||||||
disabled_edges_sorted()
|
|
||||||
{
|
|
||||||
cmdLinkedNetwork();
|
|
||||||
return Sta::sta()->disabledEdgesSorted();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
write_sdc_cmd(const char *filename,
|
|
||||||
bool leaf,
|
|
||||||
bool compatible,
|
|
||||||
int digits,
|
|
||||||
bool gzip,
|
|
||||||
bool no_timestamp)
|
|
||||||
{
|
|
||||||
cmdLinkedNetwork();
|
|
||||||
Sta::sta()->writeSdc(filename, leaf, compatible, digits, gzip, no_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
write_timing_model_cmd(const char *lib_name,
|
write_timing_model_cmd(const char *lib_name,
|
||||||
const char *cell_name,
|
const char *cell_name,
|
||||||
|
|
@ -2502,80 +2333,6 @@ slow_drivers(int count)
|
||||||
return Sta::sta()->slowDrivers(count);
|
return Sta::sta()->slowDrivers(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
timing_arc_disabled(Edge *edge,
|
|
||||||
TimingArc *arc)
|
|
||||||
{
|
|
||||||
Graph *graph = Sta::sta()->graph();
|
|
||||||
return !searchThru(edge, arc, graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClockGroups *
|
|
||||||
make_clock_groups(const char *name,
|
|
||||||
bool logically_exclusive,
|
|
||||||
bool physically_exclusive,
|
|
||||||
bool asynchronous,
|
|
||||||
bool allow_paths,
|
|
||||||
const char *comment)
|
|
||||||
{
|
|
||||||
return Sta::sta()->makeClockGroups(name, logically_exclusive,
|
|
||||||
physically_exclusive, asynchronous,
|
|
||||||
allow_paths, comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clock_groups_make_group(ClockGroups *clk_groups,
|
|
||||||
ClockSet *clks)
|
|
||||||
{
|
|
||||||
Sta::sta()->makeClockGroup(clk_groups, clks);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unset_clock_groups_logically_exclusive(const char *name)
|
|
||||||
{
|
|
||||||
Sta::sta()->removeClockGroupsLogicallyExclusive(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unset_clock_groups_physically_exclusive(const char *name)
|
|
||||||
{
|
|
||||||
Sta::sta()->removeClockGroupsPhysicallyExclusive(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unset_clock_groups_asynchronous(const char *name)
|
|
||||||
{
|
|
||||||
Sta::sta()->removeClockGroupsAsynchronous(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugging function.
|
|
||||||
bool
|
|
||||||
same_clk_group(Clock *clk1,
|
|
||||||
Clock *clk2)
|
|
||||||
{
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
Sdc *sdc = sta->sdc();
|
|
||||||
return sdc->sameClockGroupExplicit(clk1, clk2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_clock_sense_cmd(PinSet *pins,
|
|
||||||
ClockSet *clks,
|
|
||||||
bool positive,
|
|
||||||
bool negative,
|
|
||||||
bool stop_propagation)
|
|
||||||
{
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
if (positive)
|
|
||||||
sta->setClockSense(pins, clks, ClockSense::positive);
|
|
||||||
else if (negative)
|
|
||||||
sta->setClockSense(pins, clks, ClockSense::negative);
|
|
||||||
else if (stop_propagation)
|
|
||||||
sta->setClockSense(pins, clks, ClockSense::stop);
|
|
||||||
else
|
|
||||||
sta->report()->critical(1577, "unknown clock sense");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
timing_role_is_check(TimingRole *role)
|
timing_role_is_check(TimingRole *role)
|
||||||
{
|
{
|
||||||
|
|
@ -3003,62 +2760,12 @@ find_cells_matching(const char *pattern,
|
||||||
|
|
||||||
} // Library methods
|
} // Library methods
|
||||||
|
|
||||||
%extend LibertyLibrary {
|
|
||||||
const char *name() { return self->name(); }
|
|
||||||
|
|
||||||
LibertyCell *
|
|
||||||
find_liberty_cell(const char *name)
|
|
||||||
{
|
|
||||||
return self->findLibertyCell(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
LibertyCellSeq
|
|
||||||
find_liberty_cells_matching(const char *pattern,
|
|
||||||
bool regexp,
|
|
||||||
bool nocase)
|
|
||||||
{
|
|
||||||
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
|
|
||||||
return self->findLibertyCellsMatching(&matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
Wireload *
|
|
||||||
find_wireload(const char *model_name)
|
|
||||||
{
|
|
||||||
return self->findWireload(model_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
WireloadSelection *
|
|
||||||
find_wireload_selection(const char *selection_name)
|
|
||||||
{
|
|
||||||
return self->findWireloadSelection(selection_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
OperatingConditions *
|
|
||||||
find_operating_conditions(const char *op_cond_name)
|
|
||||||
{
|
|
||||||
return self->findOperatingConditions(op_cond_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
OperatingConditions *
|
|
||||||
default_operating_conditions()
|
|
||||||
{
|
|
||||||
return self->defaultOperatingConditions();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // LibertyLibrary methods
|
|
||||||
|
|
||||||
%extend LibraryIterator {
|
%extend LibraryIterator {
|
||||||
bool has_next() { return self->hasNext(); }
|
bool has_next() { return self->hasNext(); }
|
||||||
Library *next() { return self->next(); }
|
Library *next() { return self->next(); }
|
||||||
void finish() { delete self; }
|
void finish() { delete self; }
|
||||||
} // LibraryIterator methods
|
} // LibraryIterator methods
|
||||||
|
|
||||||
%extend LibertyLibraryIterator {
|
|
||||||
bool has_next() { return self->hasNext(); }
|
|
||||||
LibertyLibrary *next() { return self->next(); }
|
|
||||||
void finish() { delete self; }
|
|
||||||
} // LibertyLibraryIterator methods
|
|
||||||
|
|
||||||
%extend Cell {
|
%extend Cell {
|
||||||
const char *name() { return cmdNetwork()->name(self); }
|
const char *name() { return cmdNetwork()->name(self); }
|
||||||
Library *library() { return cmdNetwork()->library(self); }
|
Library *library() { return cmdNetwork()->library(self); }
|
||||||
|
|
@ -3085,59 +2792,12 @@ find_ports_matching(const char *pattern,
|
||||||
|
|
||||||
} // Cell methods
|
} // Cell methods
|
||||||
|
|
||||||
%extend LibertyCell {
|
|
||||||
const char *name() { return self->name(); }
|
|
||||||
bool is_leaf() { return self->isLeaf(); }
|
|
||||||
bool is_buffer() { return self->isBuffer(); }
|
|
||||||
bool is_inverter() { return self->isInverter(); }
|
|
||||||
LibertyLibrary *liberty_library() { return self->libertyLibrary(); }
|
|
||||||
Cell *cell() { return reinterpret_cast<Cell*>(self); }
|
|
||||||
LibertyPort *
|
|
||||||
find_liberty_port(const char *name)
|
|
||||||
{
|
|
||||||
return self->findLibertyPort(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
LibertyPortSeq
|
|
||||||
find_liberty_ports_matching(const char *pattern,
|
|
||||||
bool regexp,
|
|
||||||
bool nocase)
|
|
||||||
{
|
|
||||||
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
|
|
||||||
return self->findLibertyPortsMatching(&matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
LibertyCellPortIterator *
|
|
||||||
liberty_port_iterator() { return new LibertyCellPortIterator(self); }
|
|
||||||
|
|
||||||
const TimingArcSetSeq &
|
|
||||||
timing_arc_sets()
|
|
||||||
{
|
|
||||||
return self->timingArcSets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ensure_voltage_waveforms()
|
|
||||||
{
|
|
||||||
Corner *corner = Sta::sta()->cmdCorner();
|
|
||||||
DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max());
|
|
||||||
self->ensureVoltageWaveforms(dcalc_ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // LibertyCell methods
|
|
||||||
|
|
||||||
%extend CellPortIterator {
|
%extend CellPortIterator {
|
||||||
bool has_next() { return self->hasNext(); }
|
bool has_next() { return self->hasNext(); }
|
||||||
Port *next() { return self->next(); }
|
Port *next() { return self->next(); }
|
||||||
void finish() { delete self; }
|
void finish() { delete self; }
|
||||||
} // CellPortIterator methods
|
} // CellPortIterator methods
|
||||||
|
|
||||||
%extend LibertyCellPortIterator {
|
|
||||||
bool has_next() { return self->hasNext(); }
|
|
||||||
LibertyPort *next() { return self->next(); }
|
|
||||||
void finish() { delete self; }
|
|
||||||
} // LibertyCellPortIterator methods
|
|
||||||
|
|
||||||
%extend Port {
|
%extend Port {
|
||||||
const char *bus_name() { return cmdNetwork()->busName(self); }
|
const char *bus_name() { return cmdNetwork()->busName(self); }
|
||||||
Cell *cell() { return cmdNetwork()->cell(self); }
|
Cell *cell() { return cmdNetwork()->cell(self); }
|
||||||
|
|
@ -3148,245 +2808,12 @@ member_iterator() { return cmdNetwork()->memberIterator(self); }
|
||||||
|
|
||||||
} // Port methods
|
} // Port methods
|
||||||
|
|
||||||
%extend LibertyPort {
|
|
||||||
const char *bus_name() { return self->busName(); }
|
|
||||||
Cell *cell() { return self->cell(); }
|
|
||||||
bool is_bus() { return self->isBus(); }
|
|
||||||
LibertyPortMemberIterator *
|
|
||||||
member_iterator() { return new LibertyPortMemberIterator(self); }
|
|
||||||
|
|
||||||
const char *
|
|
||||||
function()
|
|
||||||
{
|
|
||||||
FuncExpr *func = self->function();
|
|
||||||
if (func)
|
|
||||||
return func->asString();
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
tristate_enable()
|
|
||||||
{
|
|
||||||
FuncExpr *enable = self->tristateEnable();
|
|
||||||
if (enable)
|
|
||||||
return enable->asString();
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
capacitance(Corner *corner,
|
|
||||||
const MinMax *min_max)
|
|
||||||
{
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
return sta->capacitance(self, corner, min_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_direction(const char *dir)
|
|
||||||
{
|
|
||||||
self->setDirection(PortDirection::find(dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // LibertyPort methods
|
|
||||||
|
|
||||||
%extend OperatingConditions {
|
|
||||||
float process() { return self->process(); }
|
|
||||||
float voltage() { return self->voltage(); }
|
|
||||||
float temperature() { return self->temperature(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
%extend PortMemberIterator {
|
%extend PortMemberIterator {
|
||||||
bool has_next() { return self->hasNext(); }
|
bool has_next() { return self->hasNext(); }
|
||||||
Port *next() { return self->next(); }
|
Port *next() { return self->next(); }
|
||||||
void finish() { delete self; }
|
void finish() { delete self; }
|
||||||
} // PortMemberIterator methods
|
} // PortMemberIterator methods
|
||||||
|
|
||||||
%extend LibertyPortMemberIterator {
|
|
||||||
bool has_next() { return self->hasNext(); }
|
|
||||||
LibertyPort *next() { return self->next(); }
|
|
||||||
void finish() { delete self; }
|
|
||||||
} // LibertyPortMemberIterator methods
|
|
||||||
|
|
||||||
%extend TimingArcSet {
|
|
||||||
LibertyPort *from() { return self->from(); }
|
|
||||||
LibertyPort *to() { return self->to(); }
|
|
||||||
TimingRole *role() { return self->role(); }
|
|
||||||
const char *sdf_cond() { return self->sdfCond(); }
|
|
||||||
|
|
||||||
const char *
|
|
||||||
full_name()
|
|
||||||
{
|
|
||||||
const char *from = self->from()->name();
|
|
||||||
const char *to = self->to()->name();
|
|
||||||
const char *cell_name = self->libertyCell()->name();
|
|
||||||
return stringPrintTmp("%s %s -> %s",
|
|
||||||
cell_name,
|
|
||||||
from,
|
|
||||||
to);
|
|
||||||
}
|
|
||||||
|
|
||||||
TimingArcSeq &
|
|
||||||
timing_arcs() { return self->arcs(); }
|
|
||||||
|
|
||||||
} // TimingArcSet methods
|
|
||||||
|
|
||||||
%extend TimingArc {
|
|
||||||
LibertyPort *from() { return self->from(); }
|
|
||||||
LibertyPort *to() { return self->to(); }
|
|
||||||
Transition *from_edge() { return self->fromEdge(); }
|
|
||||||
const char *from_edge_name() { return self->fromEdge()->asRiseFall()->name(); }
|
|
||||||
Transition *to_edge() { return self->toEdge(); }
|
|
||||||
const char *to_edge_name() { return self->toEdge()->asRiseFall()->name(); }
|
|
||||||
TimingRole *role() { return self->role(); }
|
|
||||||
|
|
||||||
float
|
|
||||||
time_voltage(float in_slew,
|
|
||||||
float load_cap,
|
|
||||||
float time)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms)
|
|
||||||
return waveforms->timeVoltage(in_slew, load_cap, time);
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
time_current(float in_slew,
|
|
||||||
float load_cap,
|
|
||||||
float time)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms)
|
|
||||||
return waveforms->timeCurrent(in_slew, load_cap, time);
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
voltage_current(float in_slew,
|
|
||||||
float load_cap,
|
|
||||||
float voltage)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms)
|
|
||||||
return waveforms->voltageCurrent(in_slew, load_cap, voltage);
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
voltage_time(float in_slew,
|
|
||||||
float load_cap,
|
|
||||||
float voltage)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms)
|
|
||||||
return waveforms->voltageTime(in_slew, load_cap, voltage);
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Table1
|
|
||||||
voltage_waveform(float in_slew,
|
|
||||||
float load_cap)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
Table1 waveform = waveforms->voltageWaveform(in_slew, load_cap);
|
|
||||||
return waveform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Table1();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Table1 *
|
|
||||||
voltage_waveform_raw(float in_slew,
|
|
||||||
float load_cap)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
const Table1 *waveform = waveforms->voltageWaveformRaw(in_slew, load_cap);
|
|
||||||
return waveform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Table1
|
|
||||||
current_waveform(float in_slew,
|
|
||||||
float load_cap)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
Table1 waveform = waveforms->currentWaveform(in_slew, load_cap);
|
|
||||||
return waveform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Table1();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Table1 *
|
|
||||||
current_waveform_raw(float in_slew,
|
|
||||||
float load_cap)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
const Table1 *waveform = waveforms->currentWaveformRaw(in_slew, load_cap);
|
|
||||||
return waveform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Table1
|
|
||||||
voltage_current_waveform(float in_slew,
|
|
||||||
float load_cap)
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
Table1 waveform = waveforms->voltageCurrentWaveform(in_slew, load_cap);
|
|
||||||
return waveform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Table1();
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
final_resistance()
|
|
||||||
{
|
|
||||||
GateTableModel *gate_model = self->gateTableModel();
|
|
||||||
if (gate_model) {
|
|
||||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
|
||||||
if (waveforms) {
|
|
||||||
return waveforms->finalResistance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // TimingArc methods
|
|
||||||
|
|
||||||
%extend Instance {
|
%extend Instance {
|
||||||
Instance *parent() { return cmdLinkedNetwork()->parent(self); }
|
Instance *parent() { return cmdLinkedNetwork()->parent(self); }
|
||||||
Cell *cell() { return cmdLinkedNetwork()->cell(self); }
|
Cell *cell() { return cmdLinkedNetwork()->cell(self); }
|
||||||
|
|
@ -3550,31 +2977,6 @@ const Pin *next() { return self->next(); }
|
||||||
void finish() { delete self; }
|
void finish() { delete self; }
|
||||||
} // NetConnectedPinIterator methods
|
} // NetConnectedPinIterator methods
|
||||||
|
|
||||||
%extend Clock {
|
|
||||||
float period() { return self->period(); }
|
|
||||||
FloatSeq *waveform() { return self->waveform(); }
|
|
||||||
float time(RiseFall *rf) { return self->edge(rf)->time(); }
|
|
||||||
bool is_generated() { return self->isGenerated(); }
|
|
||||||
bool waveform_valid() { return self->waveformValid(); }
|
|
||||||
bool is_virtual() { return self->isVirtual(); }
|
|
||||||
bool is_propagated() { return self->isPropagated(); }
|
|
||||||
const PinSet &sources() { return self->pins(); }
|
|
||||||
|
|
||||||
float
|
|
||||||
slew(const RiseFall *rf,
|
|
||||||
const MinMax *min_max)
|
|
||||||
{
|
|
||||||
return self->slew(rf, min_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
%extend ClockEdge {
|
|
||||||
Clock *clock() { return self->clock(); }
|
|
||||||
RiseFall *transition() { return self->transition(); }
|
|
||||||
float time() { return self->time(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
%extend Vertex {
|
%extend Vertex {
|
||||||
Pin *pin() { return self->pin(); }
|
Pin *pin() { return self->pin(); }
|
||||||
bool is_bidirect_driver() { return self->isBidirectDriver(); }
|
bool is_bidirect_driver() { return self->isBidirectDriver(); }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue