Merge branch 'master' of https://github.com/parallaxsw/OpenSTA into update_sta

This commit is contained in:
Eder Monteiro 2024-12-23 11:47:33 -03:00
commit 20cfa91047
39 changed files with 1272 additions and 557 deletions

View File

@ -386,30 +386,7 @@ find_package(Threads)
find_package(Eigen3 REQUIRED)
################################################################
#
# Locate CUDD bdd package.
#
find_library(CUDD_LIB
NAME cudd
PATHS ${CUDD_DIR}
PATH_SUFFIXES lib lib/cudd cudd/.libs
)
if (CUDD_LIB)
message(STATUS "CUDD library: ${CUDD_LIB}")
get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH)
get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH)
find_file(CUDD_HEADER cudd.h
PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd)
if (CUDD_HEADER)
get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
message(STATUS "CUDD header: ${CUDD_HEADER}")
else()
message(STATUS "CUDD header: not found")
endif()
else()
message(STATUS "CUDD library: not found")
endif()
include(cmake/FindCUDD.cmake)
if("${SSTA}" STREQUAL "")
set(SSTA 0)
@ -477,7 +454,7 @@ set_source_files_properties(${STA_SWIG_CXX_FILE}
PROPERTIES
# No simple way to modify the swig template that emits code full of warnings
# so suppress them.
COMPILE_OPTIONS "-Wno-cast-qual;-Wno-missing-braces;-Wno-deprecated-declarations"
COMPILE_OPTIONS "-Wunused-variable;-Wno-cast-qual;-Wno-missing-braces;-Wno-deprecated-declarations"
)
target_link_libraries(sta_swig

25
cmake/FindCUDD.cmake Normal file
View File

@ -0,0 +1,25 @@
################################################################
#
# Locate CUDD bdd package.
#
################################################################
find_library(CUDD_LIB
NAME cudd
PATHS ${CUDD_DIR}
PATH_SUFFIXES lib lib/cudd cudd/.libs
)
if (CUDD_LIB)
message(STATUS "CUDD library: ${CUDD_LIB}")
get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH)
get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH)
find_file(CUDD_HEADER cudd.h
PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd)
if (CUDD_HEADER)
get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
message(STATUS "CUDD header: ${CUDD_HEADER}")
else()
message(STATUS "CUDD header: not found")
endif()
else()
message(STATUS "CUDD library: not found")
endif()

View File

@ -49,7 +49,7 @@ set_delay_calculator_cmd(const char *alg)
void
set_delay_calc_incremental_tolerance(float tol)
{
sta::Sta::sta()->setIncrementalDelayTolerance(tol);
Sta::sta()->setIncrementalDelayTolerance(tol);
}
string
@ -59,8 +59,8 @@ report_delay_calc_cmd(Edge *edge,
const MinMax *min_max,
int digits)
{
cmdLinkedNetwork();
return Sta::sta()->reportDelayCalc(edge, arc, corner, min_max, digits);
Sta *sta = Sta::sta();
return sta->reportDelayCalc(edge, arc, corner, min_max, digits);
}
void
@ -77,7 +77,6 @@ set_prima_reduce_order(size_t order)
void
find_delays()
{
cmdLinkedNetwork();
Sta::sta()->findDelays();
}

View File

@ -580,16 +580,17 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
if (network_->isLeaf(pin)) {
if (vertex->isDriver(network_)) {
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex);
DrvrLoadSlews prev_load_slews = loadSlews(load_pin_index_map);
DrvrLoadSlews load_slews_prev;
if (incremental_)
load_slews_prev = loadSlews(load_pin_index_map);
findDriverDelays(vertex, arc_delay_calc, load_pin_index_map);
if (propagate) {
if (network_->direction(pin)->isInternal())
enqueueTimingChecksEdges(vertex);
bool load_slews_changed = loadSlewsChanged(prev_load_slews,
load_pin_index_map);
// Enqueue adjacent vertices even if the load slews did not
// change when non-incremental to stride past annotations.
if (load_slews_changed || !incremental_)
if (!incremental_
|| loadSlewsChanged(load_slews_prev, load_pin_index_map))
iter_->enqueueAdjacentVertices(vertex);
}
}
@ -621,19 +622,15 @@ GraphDelayCalc::loadSlews(LoadPinIndexMap &load_pin_index_map)
}
bool
GraphDelayCalc::loadSlewsChanged(DrvrLoadSlews &prev_load_slews,
GraphDelayCalc::loadSlewsChanged(DrvrLoadSlews &load_slews_prev,
LoadPinIndexMap &load_pin_index_map)
{
for (auto const [pin, index] : load_pin_index_map) {
Vertex *load_vertex = graph_->pinLoadVertex(pin);
const SlewSeq load_slews = graph_->slews(load_vertex);
const SlewSeq &prev_slews = prev_load_slews[index];
for (size_t i = 0; i < load_slews.size(); i++) {
const Slew &slew = delayAsFloat(load_slews[i]);
const Slew &prev_slew = delayAsFloat(prev_slews[i]);
if ((prev_slew == 0.0 && slew != 0.0)
|| (prev_slew != 0.0
&& abs((slew - prev_slew) / prev_slew) > incremental_delay_tolerance_))
const SlewSeq slews = graph_->slews(load_vertex);
const SlewSeq &slews_prev = load_slews_prev[index];
for (size_t i = 0; i < slews.size(); i++) {
if (!delayEqual(slews[i], slews_prev[i]))
return true;
}
}
@ -1112,9 +1109,10 @@ GraphDelayCalc::annotateDelaySlew(Edge *edge,
float prev_gate_delay1 = delayAsFloat(prev_gate_delay);
if (prev_gate_delay1 == 0.0
|| (abs(gate_delay1 - prev_gate_delay1) / prev_gate_delay1
> incremental_delay_tolerance_))
> incremental_delay_tolerance_)) {
delay_changed = true;
graph_->setArcDelay(edge, arc, ap_index, gate_delay);
graph_->setArcDelay(edge, arc, ap_index, gate_delay);
}
}
return delay_changed;
}

View File

@ -75,7 +75,6 @@
0245 CheckTiming.cc:428 unknown print flag
0246 Corner.cc:377 unknown parasitic analysis point count
0247 Corner.cc:421 unknown analysis point count
0248 Crpr.cc:73 missing prev paths
0249 GatedClk.cc:247 illegal gated clock active value
0250 NetworkEdit.tcl:107 unsupported object type $object_type.
0252 NetworkEdit.tcl:174 unsupported object type $object_type.
@ -422,72 +421,72 @@
1240 LibertyReader.cc:3397 unknown port direction.
1241 LibertyReader.cc:3644 max_transition is 0.0.
1242 LibertyReader.cc:3750 pulse_latch unknown pulse type.
1243 LibertyReader.cc:4194 timing group missing related_pin/related_bus_pin.
1244 LibertyReader.cc:4293 unknown timing_type %s.
1245 LibertyReader.cc:4313 unknown timing_sense %s.
1246 LibertyReader.cc:4353 mode value is not a string.
1247 LibertyReader.cc:4356 missing mode value.
1248 LibertyReader.cc:4359 mode name is not a string.
1249 LibertyReader.cc:4362 mode missing values.
1250 LibertyReader.cc:4365 mode missing mode name and value.
1251 LibertyReader.cc:4441 unsupported model axis.
1252 LibertyReader.cc:4468 unsupported model axis.
1253 LibertyReader.cc:4497 unsupported model axis.
1254 LibertyReader.cc:4532 unsupported model axis.
1255 LibertyReader.cc:4548 %s group not in timing group.
1256 LibertyReader.cc:4587 table template %s not found.
1257 LibertyReader.cc:4671 %s is missing values.
1258 LibertyReader.cc:4694 %s is not a list of floats.
1259 LibertyReader.cc:4696 table row has %u columns but axis has %d.
1260 LibertyReader.cc:4706 table has %u rows but axis has %d.
1261 LibertyReader.cc:4757 lut output is not a string.
1262 LibertyReader.cc:4773 cell %s test_cell redefinition.
1263 LibertyReader.cc:4821 mode definition missing name.
1264 LibertyReader.cc:4838 mode value missing name.
1265 LibertyReader.cc:4852 when attribute inside table model.
1266 LibertyReader.cc:4901 %s attribute is not a string.
1267 LibertyReader.cc:4904 %s is not a simple attribute.
1268 LibertyReader.cc:4924 %s attribute is not an integer.
1269 LibertyReader.cc:4927 %s is not a simple attribute.
1270 LibertyReader.cc:4940 %s is not a simple attribute.
1271 LibertyReader.cc:4966 %s value %s is not a float.
1272 LibertyReader.cc:4995 %s missing values.
1273 LibertyReader.cc:4999 %s missing values.
1274 LibertyReader.cc:5002 %s is not a complex attribute.
1275 LibertyReader.cc:5028 %s is not a float.
1276 LibertyReader.cc:5051 %s is missing values.
1277 LibertyReader.cc:5054 %s has more than one string.
1278 LibertyReader.cc:5063 %s is missing values.
1279 LibertyReader.cc:5088 %s attribute is not boolean.
1280 LibertyReader.cc:5091 %s attribute is not boolean.
1281 LibertyReader.cc:5094 %s is not a simple attribute.
1282 LibertyReader.cc:5110 attribute %s value %s not recognized.
1283 LibertyReader.cc:5141 unknown early/late value.
1284 LibertyReader.cc:5361 OCV derate group named %s not found.
1285 LibertyReader.cc:5377 ocv_derate missing name.
1286 LibertyReader.cc:5430 unknown rise/fall.
1287 LibertyReader.cc:5450 unknown derate type.
1288 LibertyReader.cc:5482 unsupported model axis.
1289 LibertyReader.cc:5514 unsupported model axis.
1290 LibertyReader.cc:5546 unsupported model axis.
1291 LibertyReader.cc:5617 unknown pg_type.
1292 LibertyReader.cc:6031 port %s subscript out of range.
1293 LibertyReader.cc:6035 port range %s of non-bus port %s.
1294 LibertyReader.cc:6049 port %s not found.
1295 LibertyReader.cc:6119 port %s not found.
1243 LibertyReader.cc:4202 timing group missing related_pin/related_bus_pin.
1244 LibertyReader.cc:4301 unknown timing_type %s.
1245 LibertyReader.cc:4321 unknown timing_sense %s.
1246 LibertyReader.cc:4361 mode value is not a string.
1247 LibertyReader.cc:4364 missing mode value.
1248 LibertyReader.cc:4367 mode name is not a string.
1249 LibertyReader.cc:4370 mode missing values.
1250 LibertyReader.cc:4373 mode missing mode name and value.
1251 LibertyReader.cc:4449 unsupported model axis.
1252 LibertyReader.cc:4476 unsupported model axis.
1253 LibertyReader.cc:4505 unsupported model axis.
1254 LibertyReader.cc:4540 unsupported model axis.
1255 LibertyReader.cc:4556 %s group not in timing group.
1256 LibertyReader.cc:4595 table template %s not found.
1257 LibertyReader.cc:4679 %s is missing values.
1258 LibertyReader.cc:4702 %s is not a list of floats.
1259 LibertyReader.cc:4704 table row has %u columns but axis has %d.
1260 LibertyReader.cc:4714 table has %u rows but axis has %d.
1261 LibertyReader.cc:4765 lut output is not a string.
1262 LibertyReader.cc:4781 cell %s test_cell redefinition.
1263 LibertyReader.cc:4829 mode definition missing name.
1264 LibertyReader.cc:4846 mode value missing name.
1265 LibertyReader.cc:4860 when attribute inside table model.
1266 LibertyReader.cc:4909 %s attribute is not a string.
1267 LibertyReader.cc:4912 %s is not a simple attribute.
1268 LibertyReader.cc:4932 %s attribute is not an integer.
1269 LibertyReader.cc:4935 %s is not a simple attribute.
1270 LibertyReader.cc:4948 %s is not a simple attribute.
1271 LibertyReader.cc:4974 %s value %s is not a float.
1272 LibertyReader.cc:5003 %s missing values.
1273 LibertyReader.cc:5007 %s missing values.
1274 LibertyReader.cc:5010 %s is not a complex attribute.
1275 LibertyReader.cc:5036 %s is not a float.
1276 LibertyReader.cc:5059 %s is missing values.
1277 LibertyReader.cc:5062 %s has more than one string.
1278 LibertyReader.cc:5071 %s is missing values.
1279 LibertyReader.cc:5096 %s attribute is not boolean.
1280 LibertyReader.cc:5099 %s attribute is not boolean.
1281 LibertyReader.cc:5102 %s is not a simple attribute.
1282 LibertyReader.cc:5118 attribute %s value %s not recognized.
1283 LibertyReader.cc:5149 unknown early/late value.
1284 LibertyReader.cc:5369 OCV derate group named %s not found.
1285 LibertyReader.cc:5385 ocv_derate missing name.
1286 LibertyReader.cc:5438 unknown rise/fall.
1287 LibertyReader.cc:5458 unknown derate type.
1288 LibertyReader.cc:5490 unsupported model axis.
1289 LibertyReader.cc:5522 unsupported model axis.
1290 LibertyReader.cc:5554 unsupported model axis.
1291 LibertyReader.cc:5625 unknown pg_type.
1292 LibertyReader.cc:6039 port %s subscript out of range.
1293 LibertyReader.cc:6043 port range %s of non-bus port %s.
1294 LibertyReader.cc:6057 port %s not found.
1295 LibertyReader.cc:6127 port %s not found.
1297 LibertyReader.cc:1466 axis type %s not supported.
1298 LibertyReader.cc:2180 statetable input port %s not found.
1299 LibertyReader.cc:3809 unknown signal_type %s.
1300 LibertyReader.cc:4068 table row must have 3 groups separated by ':'.
1301 LibertyReader.cc:4073 table row has %zu input values but %zu are required.
1302 LibertyReader.cc:4080 table row has %zu current values but %zu are required.
1303 LibertyReader.cc:4087 table row has %zu next values but %zu are required.
1304 LibertyReader.cc:4133 table input value '%s' not recognized.
1305 LibertyReader.cc:4152 table internal value '%s' not recognized.
1340 LibertyWriter.cc:307 %s/%s bundled ports not supported.
1341 LibertyWriter.cc:455 %s/%s/%s timing model not supported.
1342 LibertyWriter.cc:475 3 axis table models not supported.
1343 LibertyWriter.cc:624 %s/%s/%s timing arc type %s not supported.
1300 LibertyReader.cc:4076 table row must have 3 groups separated by ':'.
1301 LibertyReader.cc:4081 table row has %zu input values but %zu are required.
1302 LibertyReader.cc:4088 table row has %zu current values but %zu are required.
1303 LibertyReader.cc:4095 table row has %zu next values but %zu are required.
1304 LibertyReader.cc:4141 table input value '%s' not recognized.
1305 LibertyReader.cc:4160 table internal value '%s' not recognized.
1340 LibertyWriter.cc:308 %s/%s bundled ports not supported.
1341 LibertyWriter.cc:456 %s/%s/%s timing model not supported.
1342 LibertyWriter.cc:476 3 axis table models not supported.
1343 LibertyWriter.cc:625 %s/%s/%s timing arc type %s not supported.
1350 LumpedCapDelayCalc.cc:138 gate delay input variable is NaN
1355 MakeTimingModel.cc:227 clock %s pin %s is inside model block.
1360 Vcd.cc:172 Unknown variable %s ID %s
@ -505,17 +504,15 @@
1525 SpefParse.yy:805 %d is not positive.
1526 SpefParse.yy:814 %.4f is not positive.
1527 SpefParse.yy:820 %.4f is not positive.
1550 Sta.cc:1999 '%s' is not a valid start point.
1551 Sta.cc:2072 '%s' is not a valid endpoint.
1552 Sta.cc:2075 '%s' is not a valid endpoint.
1553 Sta.cc:2391 maximum corner count exceeded
1554 Sta.cc:1996 '%s' is not a valid start point.
1570 Search.i:54 no network has been linked.
1571 Search.i:68 network does not support edits.
1574 Search.i:1121 POCV support requires compilation with SSTA=1.
1575 Search.i:530 unknown report path field %s
1576 Search.i:542 unknown report path field %s
1600 WritePathSpice.cc:165 No liberty libraries found,
1550 Sta.cc:2000 '%s' is not a valid start point.
1551 Sta.cc:2073 '%s' is not a valid endpoint.
1552 Sta.cc:2076 '%s' is not a valid endpoint.
1553 Sta.cc:2393 maximum corner count exceeded
1554 Sta.cc:1997 '%s' is not a valid start point.
1570 Sta.cc:3413 No network has been linked.
1574 Search.i:1026 POCV support requires compilation with SSTA=1.
1575 Search.i:465 unknown report path field %s
1576 Search.i:477 unknown report path field %s
1602 WriteSpice.cc:458 Liberty pg_port %s/%s missing voltage_name attribute,
1603 WriteSpice.cc:428 %s pg_port %s not found,
1604 WriteSpice.cc:1019 no register/latch found for path from %s to %s,
@ -575,7 +572,10 @@
2103 ArcDelayCalc.cc:97 %s not a valid rise/fall.
2104 ArcDelayCalc.cc:100 Pin %s/%s not found.
2105 ArcDelayCalc.cc:103 Instance %s not found.
2120 Network.i:252 unknown namespace
2121 Sdc.i:105 unknown analysis type
2122 Sdc.i:232 unknown wire load mode
2140 StaTclTypes.i:431 Delay calc arg requires 5 or 6 args.
2120 Network.i:255 unknown namespace
2121 Sdc.i:104 unknown analysis type
2122 Sdc.i:227 unknown wire load mode
2140 StaTclTypes.i:424 Delay calc arg requires 5 or 6 args.
2141 Sta.cc:3417 No liberty libraries found.
2200 Crpr.cc:62 missing prev paths
2201 Crpr.cc:73 missing prev paths

View File

@ -63,6 +63,12 @@ Delay::Delay(const Delay &delay) :
{
}
Delay::Delay(const DelayDbl &delay) :
mean_(delay.mean_),
sigma2_(delay.sigma2_)
{
}
Delay::Delay(float mean) :
mean_(mean),
sigma2_(0.0)
@ -173,6 +179,35 @@ Delay::operator==(const Delay &delay) const
////////////////////////////////////////////////////////////////
DelayDbl::DelayDbl() :
mean_(0.0),
sigma2_(0.0)
{
}
void
DelayDbl::operator=(float delay)
{
mean_ = delay;
sigma2_ = 0.0;
}
void
DelayDbl::operator+=(const Delay &delay)
{
mean_ += delay.mean_;
sigma2_ += delay.sigma2_;
}
void
DelayDbl::operator-=(const Delay &delay)
{
mean_ -= delay.mean_;
sigma2_ += delay.sigma2_;
}
////////////////////////////////////////////////////////////////
Delay
makeDelay(float delay,
float sigma,

View File

@ -64,6 +64,13 @@ Delay::Delay(const Delay &delay) :
sigma2_[EarlyLate::lateIndex()] = delay.sigma2_[EarlyLate::lateIndex()];
}
Delay::Delay(const DelayDbl &delay) :
mean_(delay.mean_)
{
sigma2_[EarlyLate::earlyIndex()] = delay.sigma2_[EarlyLate::earlyIndex()];
sigma2_[EarlyLate::lateIndex()] = delay.sigma2_[EarlyLate::lateIndex()];
}
Delay::Delay(float mean) :
mean_(mean),
sigma2_{0.0, 0.0}
@ -196,6 +203,38 @@ Delay::operator==(const Delay &delay) const
////////////////////////////////////////////////////////////////
DelayDbl::DelayDbl() :
mean_(0.0),
sigma2_{0.0, 0.0}
{
}
void
DelayDbl::operator=(float delay)
{
mean_ = delay;
sigma2_[early_index] = 0.0;
sigma2_[late_index] = 0.0;
}
void
DelayDbl::operator+=(const Delay &delay)
{
mean_ += delay.mean_;
sigma2_[early_index] += delay.sigma2_[early_index];
sigma2_[late_index] += delay.sigma2_[late_index];
}
void
DelayDbl::operator-=(const Delay &delay)
{
mean_ -= delay.mean_;
sigma2_[early_index] += delay.sigma2_[early_index];
sigma2_[late_index] += delay.sigma2_[late_index];
}
////////////////////////////////////////////////////////////////
Delay
makeDelay(float delay,
float sigma_early,

View File

@ -78,25 +78,26 @@ private:
int
graph_vertex_count()
{
return cmdGraph()->vertexCount();
return Sta::sta()->ensureGraph()->vertexCount();
}
int
graph_edge_count()
{
return cmdGraph()->edgeCount();
return Sta::sta()->ensureGraph()->edgeCount();
}
int
graph_arc_count()
{
return cmdGraph()->arcCount();
return Sta::sta()->ensureGraph()->arcCount();
}
VertexIterator *
vertex_iterator()
{
return new VertexIterator(cmdGraph());
Graph *graph = Sta::sta()->ensureGraph();
return new VertexIterator(graph);
}
void
@ -106,7 +107,6 @@ set_arc_delay(Edge *edge,
const MinMaxAll *min_max,
float delay)
{
cmdGraph();
Sta::sta()->setArcDelay(edge, arc, corner, min_max, delay);
}
@ -117,7 +117,6 @@ set_annotated_slew(Vertex *vertex,
const RiseFallBoth *rf,
float slew)
{
cmdGraph();
Sta::sta()->setAnnotatedSlew(vertex, corner, min_max, rf, slew);
}
@ -125,7 +124,6 @@ set_annotated_slew(Vertex *vertex,
void
remove_delay_slew_annotations()
{
cmdGraph();
Sta::sta()->removeDelaySlewAnnotations();
}
@ -415,7 +413,7 @@ latch_d_to_q_en()
{
if (self->role() == TimingRole::latchDtoQ()) {
Sta *sta = Sta::sta();
const Network *network = sta->cmdNetwork();
const Network *network = sta->ensureLinked();
const Graph *graph = sta->graph();
Pin *from_pin = self->from(graph)->pin();
Instance *inst = network->instance(from_pin);

View File

@ -25,6 +25,8 @@ namespace sta {
class StaState;
typedef float Delay;
// Delay double for accumulating Delays.
typedef double DelayDbl;
const Delay delay_zero = 0.0;

View File

@ -21,6 +21,7 @@
namespace sta {
class Delay;
class DelayDbl;
class StaState;
// Normal distribution with std deviation.
@ -29,6 +30,7 @@ class Delay
public:
Delay();
Delay(const Delay &delay);
Delay(const DelayDbl &delay);
Delay(float mean);
Delay(float mean,
float sigma2);
@ -53,6 +55,29 @@ private:
float mean_;
// Sigma^2
float sigma2_;
friend class DelayDbl;
};
// Dwlay with doubles for accumulating delays.
class DelayDbl
{
public:
DelayDbl();
float mean() const { return mean_; }
float sigma() const;
// sigma^2
float sigma2() const;
void operator=(float delay);
void operator+=(const Delay &delay);
void operator-=(const Delay &delay);
private:
double mean_;
// Sigma^2
double sigma2_;
friend class Delay;
};
const Delay delay_zero(0.0);

View File

@ -21,6 +21,7 @@
namespace sta {
class Delay;
class DelayDbl;
class StaState;
// Normal distribution with early(left)/late(right) std deviations.
@ -29,6 +30,7 @@ class Delay
public:
Delay();
Delay(const Delay &delay);
Delay(const DelayDbl &delay);
Delay(float mean);
Delay(float mean,
float sigma2_early,
@ -60,6 +62,33 @@ private:
float mean_;
// Sigma^2
float sigma2_[EarlyLate::index_count];
friend class DelayDbl;
};
// Dwlay with doubles for accumulating delays.
class DelayDbl
{
public:
DelayDbl();
float mean() const { return mean_; }
float sigma() const;
// sigma^2
float sigma2() const;
void operator=(float delay);
void operator+=(const Delay &delay);
void operator-=(const Delay &delay);
protected:
static const int early_index = 0;
static const int late_index = 1;
private:
double mean_;
// Sigma^2
double sigma2_[EarlyLate::index_count];
friend class Delay;
};
const Delay delay_zero(0.0);

View File

@ -123,7 +123,7 @@ public:
virtual void readLibertyAfter(LibertyLibrary *library);
// First liberty library read is used to look up defaults.
// This corresponds to a link_path of '*'.
LibertyLibrary *defaultLibertyLibrary() const;
virtual LibertyLibrary *defaultLibertyLibrary() const;
void setDefaultLibertyLibrary(LibertyLibrary *library);
// Check liberty cells used by the network to make sure they exist
// for all the defined corners.

View File

@ -34,6 +34,7 @@ public:
const char *name(const Library *library) const override;
ObjectId id(const Library *library) const override;
LibertyLibrary *defaultLibertyLibrary() const override;
LibraryIterator *libraryIterator() const override;
LibertyLibraryIterator *libertyLibraryIterator() const override;
Library *findLibrary(const char *name) override;

View File

@ -60,6 +60,7 @@ typedef UnorderedSet<TagGroup*, TagGroupHash, TagGroupEqual> TagGroupSet;
typedef Map<Vertex*, Slack> VertexSlackMap;
typedef Vector<VertexSlackMap> VertexSlackMapSeq;
typedef Vector<WorstSlacks> WorstSlacksSeq;
typedef vector<DelayDbl> DelayDblSeq;
class Search : public StaState
{
@ -570,7 +571,7 @@ protected:
// Endpoint vertices with slacks that have changed since tns was found.
VertexSet *invalid_tns_;
// Indexed by path_ap->index().
SlackSeq tns_;
DelayDblSeq tns_;
// Indexed by path_ap->index().
VertexSlackMapSeq tns_slacks_;
std::mutex tns_lock_;

View File

@ -1190,7 +1190,7 @@ public:
// disconnect_net
virtual void disconnectPin(Pin *pin);
virtual void makePortPin(const char *port_name,
const char *direction);
PortDirection *dir);
// Notify STA of network change.
void networkChanged();
void deleteLeafInstanceBefore(const Instance *inst);
@ -1230,6 +1230,8 @@ public:
void setTclInterp(Tcl_Interp *interp);
Tcl_Interp *tclInterp();
// Ensure a network has been read, linked and liberty libraries exist.
Network *ensureLinked();
void ensureLevelized();
// Ensure that the timing graph has been built.
Graph *ensureGraph();
@ -1287,24 +1289,6 @@ public:
const Corner *corner);
PwrActivity findClkedActivity(const Pin *pin);
void writeGateSpice(ArcDcalcArgSeq gates,
const char *spice_filename,
const char *subckt_filename,
const char *lib_subckt_filename,
const char *model_filename,
const char *power_name,
const char *gnd_name,
CircuitSim ckt_sim,
const Corner *corner,
const MinMax *min_max);
void writeGateGnuplot(ArcDcalcArgSeq gates,
PinSet plot_pins,
const char *spice_waveform_filename,
const char *csv_filename,
const char *gnuplot_filename,
const Corner *corner,
const MinMax *min_max);
void writeTimingModel(const char *lib_name,
const char *cell_name,
const char *filename,
@ -1316,6 +1300,15 @@ public:
LibertyLibrarySeq *map_libs);
LibertyCellSeq *equivCells(LibertyCell *cell);
void writePathSpice(PathRef *path,
const char *spice_filename,
const char *subckt_filename,
const char *lib_subckt_filename,
const char *model_filename,
const char *power_name,
const char *gnd_name,
CircuitSim ckt_sim);
protected:
// Default constructors that are called by makeComponents in the Sta
// constructor. These can be redefined by a derived class to

View File

@ -182,19 +182,19 @@ liberty_supply_exists(const char *supply_name)
LibertyLibraryIterator *
liberty_library_iterator()
{
return cmdNetwork()->libertyLibraryIterator();
return Sta::sta()->network()->libertyLibraryIterator();
}
LibertyLibrary *
find_liberty(const char *name)
{
return cmdNetwork()->findLiberty(name);
return Sta::sta()->network()->findLiberty(name);
}
LibertyCell *
find_liberty_cell(const char *name)
{
return cmdNetwork()->findLibertyCell(name);
return Sta::sta()->network()->findLibertyCell(name);
}
bool

View File

@ -3975,21 +3975,29 @@ LibertyReader::seqPortNames(LibertyGroup *group,
bool &has_size,
int &size)
{
int i = 0;
out_name = nullptr;
out_inv_name = nullptr;
size = 1;
has_size = false;
for (LibertyAttrValue *value : *group->params()) {
if (i == 0)
out_name = value->stringValue();
else if (i == 1)
out_inv_name = value->stringValue();
else if (i == 2) {
size = static_cast<int>(value->floatValue());
if (group->params()->size() == 2) {
// out_port, out_port_inv
out_name = group->firstName();
out_inv_name = group->secondName();
}
else if (group->params()->size() == 3) {
LibertyAttrValue *third_value = (*group->params())[2];
if (third_value->isFloat()) {
// out_port, out_port_inv, bus_size
out_name = group->firstName();
out_inv_name = group->secondName();
size = static_cast<int>(third_value->floatValue());
has_size = true;
}
i++;
else {
// in_port (ignored), out_port, out_port_inv
out_name = group->secondName();
out_inv_name = third_value->stringValue();
}
}
}

View File

@ -158,13 +158,14 @@ private:
bool
network_is_linked()
{
return Sta::sta()->cmdNetwork()->isLinked();
return Sta::sta()->network()->isLinked();
}
void
set_path_divider(char divider)
{
cmdNetwork()->setPathDivider(divider);
Network *network = Sta::sta()->network();
network->setPathDivider(divider);
}
void
@ -177,48 +178,50 @@ set_current_instance(Instance *inst)
int
network_instance_count()
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->instanceCount();
}
int
network_pin_count()
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->pinCount();
}
int
network_net_count()
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->netCount();
}
int
network_leaf_instance_count()
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->leafInstanceCount();
}
int
network_leaf_pin_count()
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->leafPinCount();
}
Library *
find_library(const char *name)
{
return cmdNetwork()->findLibrary(name);
Network *network = Sta::sta()->ensureLinked();
return network->findLibrary(name);
}
LibraryIterator *
library_iterator()
{
return cmdNetwork()->libraryIterator();
Network *network = Sta::sta()->ensureLinked();
return network->libraryIterator();
}
CellSeq
@ -226,7 +229,7 @@ find_cells_matching(const char *pattern,
bool regexp,
bool nocase)
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
CellSeq matches;
LibraryIterator *lib_iter = network->libraryIterator();
@ -262,25 +265,27 @@ link_design_cmd(const char *top_cell_name,
Instance *
top_instance()
{
return cmdLinkedNetwork()->topInstance();
Network *network = Sta::sta()->ensureLinked();
return network->topInstance();
}
LeafInstanceIterator *
leaf_instance_iterator()
{
return cmdLinkedNetwork()->leafInstanceIterator();
Network *network = Sta::sta()->ensureLinked();
return network->leafInstanceIterator();
}
const char *
port_direction(const Port *port)
{
return cmdLinkedNetwork()->direction(port)->name();
return Sta::sta()->ensureLinked()->direction(port)->name();
}
const char *
pin_direction(const Pin *pin)
{
return cmdLinkedNetwork()->direction(pin)->name();
return Sta::sta()->ensureLinked()->direction(pin)->name();
}
PortSeq
@ -288,8 +293,9 @@ find_ports_matching(const char *pattern,
bool regexp,
bool nocase)
{
Network *network = cmdLinkedNetwork();
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
Cell *top_cell = network->cell(network->topInstance());
PortSeq matches1 = network->findPortsMatching(top_cell, &matcher);
// Expand bus/bundle ports.
@ -315,8 +321,9 @@ find_port_pins_matching(const char *pattern,
bool regexp,
bool nocase)
{
Network *network = cmdLinkedNetwork();
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
Instance *top_inst = network->topInstance();
Cell *top_cell = network->cell(top_inst);
PortSeq ports = network->findPortsMatching(top_cell, &matcher);
@ -345,13 +352,14 @@ find_port_pins_matching(const char *pattern,
Pin *
find_pin(const char *path_name)
{
return cmdLinkedNetwork()->findPin(path_name);
Network *network = Sta::sta()->ensureLinked();
return network->findPin(path_name);
}
Pin *
get_port_pin(const Port *port)
{
Network *network = cmdLinkedNetwork();
Network *network = Sta::sta()->ensureLinked();
return network->findPin(network->topInstance(), port);
}
@ -361,8 +369,8 @@ find_pins_matching(const char *pattern,
bool nocase)
{
Sta *sta = Sta::sta();
Network *network = cmdLinkedNetwork();
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
Network *network = sta->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
Instance *current_instance = sta->currentInstance();
PinSeq matches = network->findPinsMatching(current_instance, &matcher);
return matches;
@ -374,9 +382,9 @@ find_pins_hier_matching(const char *pattern,
bool nocase)
{
Sta *sta = Sta::sta();
Network *network = cmdLinkedNetwork();
Network *network = sta->ensureLinked();
Instance *current_instance = sta->currentInstance();
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
PinSeq matches = network->findPinsHierMatching(current_instance, &matcher);
return matches;
}
@ -384,13 +392,13 @@ find_pins_hier_matching(const char *pattern,
Instance *
find_instance(char *path_name)
{
return cmdLinkedNetwork()->findInstance(path_name);
return Sta::sta()->ensureLinked()->findInstance(path_name);
}
InstanceSeq
network_leaf_instances()
{
return cmdLinkedNetwork()->leafInstances();
return Sta::sta()->ensureLinked()->leafInstances();
}
InstanceSeq
@ -399,9 +407,9 @@ find_instances_matching(const char *pattern,
bool nocase)
{
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
Instance *current_instance = sta->currentInstance();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
Network *network = cmdLinkedNetwork();
InstanceSeq matches = network->findInstancesMatching(current_instance, &matcher);
return matches;
}
@ -412,7 +420,7 @@ find_instances_hier_matching(const char *pattern,
bool nocase)
{
Sta *sta = Sta::sta();
Network *network = cmdLinkedNetwork();
Network *network = sta->ensureLinked();
Instance *current_instance = sta->currentInstance();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
InstanceSeq matches = network->findInstancesHierMatching(current_instance, &matcher);
@ -425,10 +433,10 @@ find_register_instances(ClockSet *clks,
bool edge_triggered,
bool latches)
{
cmdLinkedNetwork();
InstanceSet insts = Sta::sta()->findRegisterInstances(clks, clk_tr,
edge_triggered,
latches);
Sta *sta = Sta::sta();
InstanceSet insts = sta->findRegisterInstances(clks, clk_tr,
edge_triggered,
latches);
delete clks;
return insts;
}
@ -439,9 +447,9 @@ find_register_data_pins(ClockSet *clks,
bool edge_triggered,
bool latches)
{
cmdLinkedNetwork();
PinSet pins = Sta::sta()->findRegisterDataPins(clks, clk_tr,
edge_triggered, latches);
Sta *sta = Sta::sta();
PinSet pins = sta->findRegisterDataPins(clks, clk_tr,
edge_triggered, latches);
delete clks;
return pins;
}
@ -452,9 +460,9 @@ find_register_clk_pins(ClockSet *clks,
bool edge_triggered,
bool latches)
{
cmdLinkedNetwork();
PinSet pins = Sta::sta()->findRegisterClkPins(clks, clk_tr,
edge_triggered, latches);
Sta *sta = Sta::sta();
PinSet pins = sta->findRegisterClkPins(clks, clk_tr,
edge_triggered, latches);
delete clks;
return pins;
}
@ -465,9 +473,9 @@ find_register_async_pins(ClockSet *clks,
bool edge_triggered,
bool latches)
{
cmdLinkedNetwork();
PinSet pins = Sta::sta()->findRegisterAsyncPins(clks, clk_tr,
edge_triggered, latches);
Sta *sta = Sta::sta();
PinSet pins = sta->findRegisterAsyncPins(clks, clk_tr,
edge_triggered, latches);
delete clks;
return pins;
}
@ -478,9 +486,9 @@ find_register_output_pins(ClockSet *clks,
bool edge_triggered,
bool latches)
{
cmdLinkedNetwork();
PinSet pins = Sta::sta()->findRegisterOutputPins(clks, clk_tr,
edge_triggered, latches);
Sta *sta = Sta::sta();
PinSet pins = sta->findRegisterOutputPins(clks, clk_tr,
edge_triggered, latches);
delete clks;
return pins;
}
@ -488,7 +496,7 @@ find_register_output_pins(ClockSet *clks,
Net *
find_net(char *path_name)
{
return cmdLinkedNetwork()->findNet(path_name);
return Sta::sta()->ensureLinked()->findNet(path_name);
}
NetSeq
@ -496,9 +504,10 @@ 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());
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
Instance *current_instance = sta->currentInstance();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
NetSeq matches = network->findNetsMatching(current_instance, &matcher);
return matches;
}
@ -508,9 +517,10 @@ 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());
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
Instance *current_instance = sta->currentInstance();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
NetSeq matches = network->findNetsHierMatching(current_instance, &matcher);
return matches;
}
@ -518,7 +528,7 @@ find_nets_hier_matching(const char *pattern,
PinSet
net_driver_pins(Net *net)
{
Network *network = cmdLinkedNetwork();
Network *network = Sta::sta()->ensureLinked();
PinSet pins(network);
NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
while (pin_iter->hasNext()) {
@ -533,7 +543,7 @@ net_driver_pins(Net *net)
PinSet
net_load_pins(Net *net)
{
Network *network = cmdLinkedNetwork();
Network *network = Sta::sta()->ensureLinked();
PinSet pins(network);
NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
while (pin_iter->hasNext()) {
@ -548,7 +558,7 @@ net_load_pins(Net *net)
const char *
pin_location(const Pin *pin)
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
double x, y;
bool exists;
network->location(pin, x, y, exists);
@ -562,7 +572,7 @@ pin_location(const Pin *pin)
const char *
port_location(const Port *port)
{
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
const Pin *pin = network->findPin(network->topInstance(), port);
return pin_location(pin);
}
@ -578,13 +588,13 @@ port_location(const Port *port)
%extend Library {
const char *name()
{
return cmdNetwork()->name(self);
return Sta::sta()->ensureLinked()->name(self);
}
Cell *
find_cell(const char *name)
{
return cmdNetwork()->findCell(self, name);
return Sta::sta()->ensureLinked()->findCell(self, name);
}
CellSeq
@ -592,8 +602,10 @@ find_cells_matching(const char *pattern,
bool regexp,
bool nocase)
{
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
CellSeq matches = cmdNetwork()->findCellsMatching(self, &matcher);
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
CellSeq matches = network->findCellsMatching(self, &matcher);
return matches;
}
@ -606,18 +618,18 @@ 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); }
const char *name() { return Sta::sta()->ensureLinked()->name(self); }
Library *library() { return Sta::sta()->ensureLinked()->library(self); }
LibertyCell *liberty_cell() { return Sta::sta()->ensureLinked()->libertyCell(self); }
bool is_leaf() { return Sta::sta()->ensureLinked()->isLeaf(self); }
CellPortIterator *
port_iterator() { return cmdNetwork()->portIterator(self); }
string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); }
port_iterator() { return Sta::sta()->ensureLinked()->portIterator(self); }
string get_attribute(const char *key) { return Sta::sta()->ensureLinked()->getAttribute(self, key); }
Port *
find_port(const char *name)
{
return cmdNetwork()->findPort(self, name);
return Sta::sta()->ensureLinked()->findPort(self, name);
}
PortSeq
@ -625,8 +637,10 @@ find_ports_matching(const char *pattern,
bool regexp,
bool nocase)
{
PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
return cmdNetwork()->findPortsMatching(self, &matcher);
Sta *sta = Sta::sta();
Network *network = sta->ensureLinked();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
return network->findPortsMatching(self, &matcher);
}
} // Cell methods
@ -638,12 +652,12 @@ 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); }
const char *bus_name() { return Sta::sta()->ensureLinked()->busName(self); }
Cell *cell() { return Sta::sta()->ensureLinked()->cell(self); }
LibertyPort *liberty_port() { return Sta::sta()->ensureLinked()->libertyPort(self); }
bool is_bus() { return Sta::sta()->ensureLinked()->isBus(self); }
PortMemberIterator *
member_iterator() { return cmdNetwork()->memberIterator(self); }
member_iterator() { return Sta::sta()->ensureLinked()->memberIterator(self); }
} // Port methods
@ -654,22 +668,22 @@ 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); }
Instance *parent() { return Sta::sta()->ensureLinked()->parent(self); }
Cell *cell() { return Sta::sta()->ensureLinked()->cell(self); }
LibertyCell *liberty_cell() { return Sta::sta()->ensureLinked()->libertyCell(self); }
bool is_leaf() { return Sta::sta()->ensureLinked()->isLeaf(self); }
InstanceChildIterator *
child_iterator() { return cmdLinkedNetwork()->childIterator(self); }
child_iterator() { return Sta::sta()->ensureLinked()->childIterator(self); }
InstancePinIterator *
pin_iterator() { return cmdLinkedNetwork()->pinIterator(self); }
pin_iterator() { return Sta::sta()->ensureLinked()->pinIterator(self); }
InstanceNetIterator *
net_iterator() { return cmdLinkedNetwork()->netIterator(self); }
net_iterator() { return Sta::sta()->ensureLinked()->netIterator(self); }
Pin *
find_pin(const char *name)
{
return cmdLinkedNetwork()->findPin(self, name);
return Sta::sta()->ensureLinked()->findPin(self, name);
}
string get_attribute(const char *key) { return cmdNetwork()->getAttribute(self, key); }
string get_attribute(const char *key) { return Sta::sta()->ensureLinked()->getAttribute(self, key); }
} // Instance methods
%extend InstanceChildIterator {
@ -697,19 +711,19 @@ 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); }
const char *port_name() { return Sta::sta()->ensureLinked()->portName(self); }
Instance *instance() { return Sta::sta()->ensureLinked()->instance(self); }
Net *net() { return Sta::sta()->ensureLinked()->net(self); }
Port *port() { return Sta::sta()->ensureLinked()->port(self); }
Term *term() { return Sta::sta()->ensureLinked()->term(self); }
LibertyPort *liberty_port() { return Sta::sta()->ensureLinked()->libertyPort(self); }
bool is_driver() { return Sta::sta()->ensureLinked()->isDriver(self); }
bool is_load() { return Sta::sta()->ensureLinked()->isLoad(self); }
bool is_leaf() { return Sta::sta()->ensureLinked()->isLeaf(self); }
bool is_hierarchical() { return Sta::sta()->ensureLinked()->isHierarchical(self); }
bool is_top_level_port() { return Sta::sta()->ensureLinked()->isTopLevelPort(self); }
PinConnectedPinIterator *connected_pin_iterator()
{ return cmdLinkedNetwork()->connectedPinIterator(self); }
{ return Sta::sta()->ensureLinked()->connectedPinIterator(self); }
Vertex **
vertices()
@ -717,7 +731,8 @@ vertices()
Vertex *vertex, *vertex_bidirect_drvr;
static Vertex *vertices[3];
cmdGraph()->pinVertices(self, vertex, vertex_bidirect_drvr);
Graph *graph = Sta::sta()->ensureGraph();
graph->pinVertices(self, vertex, vertex_bidirect_drvr);
vertices[0] = vertex;
vertices[1] = vertex_bidirect_drvr;
vertices[2] = nullptr;
@ -733,28 +748,29 @@ void finish() { delete self; }
} // PinConnectedPinIterator methods
%extend Term {
Net *net() { return cmdLinkedNetwork()->net(self); }
Pin *pin() { return cmdLinkedNetwork()->pin(self); }
Net *net() { return Sta::sta()->ensureLinked()->net(self); }
Pin *pin() { return Sta::sta()->ensureLinked()->pin(self); }
} // Term methods
%extend Net {
Instance *instance() { return cmdLinkedNetwork()->instance(self); }
Instance *instance() { return Sta::sta()->ensureLinked()->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);}
{ return Sta::sta()->ensureLinked()->highestConnectedNet(self); }
NetPinIterator *pin_iterator() { return Sta::sta()->ensureLinked()->pinIterator(self);}
NetTermIterator *term_iterator() {return Sta::sta()->ensureLinked()->termIterator(self);}
NetConnectedPinIterator *connected_pin_iterator()
{ return cmdLinkedNetwork()->connectedPinIterator(self); }
bool is_power() { return cmdLinkedNetwork()->isPower(self);}
bool is_ground() { return cmdLinkedNetwork()->isGround(self);}
{ return Sta::sta()->ensureLinked()->connectedPinIterator(self); }
bool is_power() { return Sta::sta()->ensureLinked()->isPower(self);}
bool is_ground() { return Sta::sta()->ensureLinked()->isGround(self);}
float
capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
sta->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return pin_cap + wire_cap;
}
@ -762,9 +778,10 @@ float
pin_capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
sta->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return pin_cap;
}
@ -772,9 +789,10 @@ float
wire_capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
sta->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return wire_cap;
}
@ -782,7 +800,7 @@ wire_capacitance(Corner *corner,
PortSeq
ports()
{
Network *network = cmdLinkedNetwork();
Network *network = Sta::sta()->ensureLinked();
PortSeq ports;
if (network->isTopInstance(network->instance(self))) {
NetTermIterator *term_iter = network->termIterator(self);

View File

@ -24,11 +24,6 @@ using sta::Port;
using sta::Pin;
using sta::NetworkEdit;
namespace sta {
NetworkEdit *
cmdEditNetwork();
}
%}
////////////////////////////////////////////////////////////////
@ -64,16 +59,14 @@ Net *
make_net_cmd(const char *name,
Instance *parent)
{
Net *net = sta::cmdEditNetwork()->makeNet(name, parent);
// Sta notification unnecessary.
return net;
return Sta::sta()->makeNet(name, parent);
}
void
make_port_pin_cmd(const char *port_name,
const char *direction)
PortDirection *dir)
{
Sta::sta()->makePortPin(port_name, direction);
Sta::sta()->makePortPin(port_name, dir);
}
void

View File

@ -52,6 +52,12 @@ NetworkNameAdapter::topInstance() const
return network_->topInstance();
}
LibertyLibrary *
NetworkNameAdapter::defaultLibertyLibrary() const
{
return network_->defaultLibertyLibrary();
}
LibraryIterator *
NetworkNameAdapter::libraryIterator() const
{

View File

@ -180,7 +180,7 @@ verilogToSta(const char *verilog_name)
// Ignore leading '\'.
verilog_name = &verilog_name[1];
size_t verilog_name_length = strlen(verilog_name);
if (verilog_name[verilog_name_length - 1] == ' ')
if (isspace(verilog_name[verilog_name_length - 1]))
verilog_name_length--;
string sta_name;
for (size_t i = 0; i < verilog_name_length; i++) {

View File

@ -20,7 +20,6 @@
#include "Sta.hh"
using sta::Sta;
using sta::cmdLinkedNetwork;
using sta::Instance;
using sta::MinMaxAll;
using sta::RiseFall;
@ -40,7 +39,6 @@ read_spef_cmd(const char *filename,
float coupling_cap_factor,
bool reduce)
{
cmdLinkedNetwork();
return Sta::sta()->readSpef(filename, instance, corner, min_max,
pin_cap_included, keep_coupling_caps,
coupling_cap_factor, reduce);
@ -50,7 +48,6 @@ void
report_parasitic_annotation_cmd(bool report_unannotated,
const Corner *corner)
{
cmdLinkedNetwork();
Sta::sta()->reportParasiticAnnotation(report_unannotated, corner);
}

View File

@ -168,7 +168,12 @@ SpefReader::findInstanceRelative(const char *name)
Net *
SpefReader::findNetRelative(const char *name)
{
return network_->findNetRelative(instance_, name);
Net *net = network_->findNetRelative(instance_, name);
// Relax spef escaping requirement because some commercial tools
// don't follow the rules.
if (net == nullptr)
net = sdc_network_->findNetRelative(instance_, name);
return net;
}
Pin *

View File

@ -42,7 +42,6 @@ pushPowerResultFloats(PowerResult &power,
FloatSeq
design_power(const Corner *corner)
{
cmdLinkedNetwork();
PowerResult total, sequential, combinational, clock, macro, pad;
Sta::sta()->power(corner, total, sequential, combinational, clock, macro, pad);
FloatSeq powers;
@ -59,7 +58,6 @@ FloatSeq
instance_power(Instance *inst,
const Corner *corner)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
PowerResult power = sta->power(inst, corner);
FloatSeq powers;
@ -111,7 +109,7 @@ read_vcd_file(const char *filename,
const char *scope)
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
sta->ensureLinked();
readVcdActivities(filename, scope, sta);
}
@ -138,7 +136,7 @@ read_saif_file(const char *filename,
const char *scope)
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
sta->ensureLinked();
return readSaif(filename, scope, sta);
}

View File

@ -87,7 +87,6 @@ write_sdc_cmd(const char *filename,
bool gzip,
bool no_timestamp)
{
cmdLinkedNetwork();
Sta::sta()->writeSdc(filename, leaf, compatible, digits, gzip, no_timestamp);
}
@ -143,7 +142,6 @@ set_instance_pvt(Instance *inst,
float voltage,
float temperature)
{
cmdLinkedNetwork();
Pvt pvt(process, voltage, temperature);
Sta::sta()->setPvt(inst, min_max, pvt);
}
@ -153,7 +151,6 @@ port_ext_pin_cap(const Port *port,
const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, corner, min_max, pin_cap, wire_cap, fanout);
@ -175,7 +172,6 @@ port_ext_wire_cap(const Port *port,
const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, corner, min_max, pin_cap, wire_cap, fanout);
@ -207,7 +203,6 @@ port_ext_fanout(const Port *port,
const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, corner, min_max, pin_cap, wire_cap, fanout);
@ -264,7 +259,6 @@ make_clock(const char *name,
FloatSeq *waveform,
char *comment)
{
cmdLinkedNetwork();
Sta::sta()->makeClock(name, pins, add_to_pins, period, waveform, comment);
}
@ -283,7 +277,6 @@ make_generated_clock(const char *name,
FloatSeq *edge_shifts,
char *comment)
{
cmdLinkedNetwork();
Sta::sta()->makeGeneratedClock(name, pins, add_to_pins,
src_pin, master_clk,
divide_by, multiply_by, duty_cycle, invert,
@ -294,35 +287,30 @@ make_generated_clock(const char *name,
void
remove_clock_cmd(Clock *clk)
{
cmdLinkedNetwork();
Sta::sta()->removeClock(clk);
}
void
set_propagated_clock_cmd(Clock *clk)
{
cmdLinkedNetwork();
Sta::sta()->setPropagatedClock(clk);
}
void
set_propagated_clock_pin_cmd(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->setPropagatedClock(pin);
}
void
unset_propagated_clock_cmd(Clock *clk)
{
cmdLinkedNetwork();
Sta::sta()->removePropagatedClock(clk);
}
void
unset_propagated_clock_pin_cmd(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->removePropagatedClock(pin);
}
@ -332,14 +320,12 @@ set_clock_slew_cmd(Clock *clk,
const MinMaxAll *min_max,
float slew)
{
cmdLinkedNetwork();
Sta::sta()->setClockSlew(clk, rf, min_max, slew);
}
void
unset_clock_slew_cmd(Clock *clk)
{
cmdLinkedNetwork();
Sta::sta()->removeClockSlew(clk);
}
@ -349,7 +335,6 @@ set_clock_latency_cmd(Clock *clk,
const RiseFallBoth *rf,
MinMaxAll *min_max, float delay)
{
cmdLinkedNetwork();
Sta::sta()->setClockLatency(clk, pin, rf, min_max, delay);
}
@ -361,7 +346,6 @@ set_clock_insertion_cmd(Clock *clk,
const EarlyLateAll *early_late,
float delay)
{
cmdLinkedNetwork();
Sta::sta()->setClockInsertion(clk, pin, rf, min_max, early_late, delay);
}
@ -369,7 +353,6 @@ void
unset_clock_latency_cmd(Clock *clk,
Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->removeClockLatency(clk, pin);
}
@ -377,7 +360,6 @@ void
unset_clock_insertion_cmd(Clock *clk,
Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->removeClockInsertion(clk, pin);
}
@ -386,7 +368,6 @@ set_clock_uncertainty_clk(Clock *clk,
const SetupHoldAll *setup_hold,
float uncertainty)
{
cmdLinkedNetwork();
Sta::sta()->setClockUncertainty(clk, setup_hold, uncertainty);
}
@ -394,7 +375,6 @@ void
unset_clock_uncertainty_clk(Clock *clk,
const SetupHoldAll *setup_hold)
{
cmdLinkedNetwork();
Sta::sta()->removeClockUncertainty(clk, setup_hold);
}
@ -403,7 +383,6 @@ set_clock_uncertainty_pin(Pin *pin,
const MinMaxAll *min_max,
float uncertainty)
{
cmdLinkedNetwork();
Sta::sta()->setClockUncertainty(pin, min_max, uncertainty);
}
@ -411,7 +390,6 @@ void
unset_clock_uncertainty_pin(Pin *pin,
const MinMaxAll *min_max)
{
cmdLinkedNetwork();
Sta::sta()->removeClockUncertainty(pin, min_max);
}
@ -423,7 +401,6 @@ set_inter_clock_uncertainty(Clock *from_clk,
const MinMaxAll *min_max,
float uncertainty)
{
cmdLinkedNetwork();
Sta::sta()->setClockUncertainty(from_clk, from_tr, to_clk, to_tr, min_max,
uncertainty);
}
@ -435,7 +412,6 @@ unset_inter_clock_uncertainty(Clock *from_clk,
const RiseFallBoth *to_tr,
const MinMaxAll *min_max)
{
cmdLinkedNetwork();
Sta::sta()->removeClockUncertainty(from_clk, from_tr, to_clk, to_tr, min_max);
}
@ -511,7 +487,6 @@ set_input_delay_cmd(Pin *pin,
bool add,
float delay)
{
cmdLinkedNetwork();
Sta::sta()->setInputDelay(pin, rf, clk, clk_rf, ref_pin,
source_latency_included, network_latency_included,
min_max, add, delay);
@ -524,7 +499,6 @@ unset_input_delay_cmd(Pin *pin,
RiseFall *clk_rf,
MinMaxAll *min_max)
{
cmdLinkedNetwork();
Sta::sta()->removeInputDelay(pin, rf, clk, clk_rf, min_max);
}
@ -540,7 +514,6 @@ set_output_delay_cmd(Pin *pin,
bool add,
float delay)
{
cmdLinkedNetwork();
Sta::sta()->setOutputDelay(pin, rf, clk, clk_rf, ref_pin,
source_latency_included, network_latency_included,
min_max, add, delay);
@ -553,7 +526,6 @@ unset_output_delay_cmd(Pin *pin,
RiseFall *clk_rf,
MinMaxAll *min_max)
{
cmdLinkedNetwork();
Sta::sta()->removeOutputDelay(pin, rf, clk, clk_rf, min_max);
}
@ -562,7 +534,6 @@ disable_cell(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to)
{
cmdLinkedNetwork();
Sta::sta()->disable(cell, from, to);
}
@ -571,35 +542,30 @@ unset_disable_cell(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(cell, from, to);
}
void
disable_lib_port(LibertyPort *port)
{
cmdLinkedNetwork();
Sta::sta()->disable(port);
}
void
unset_disable_lib_port(LibertyPort *port)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(port);
}
void
disable_port(Port *port)
{
cmdLinkedNetwork();
Sta::sta()->disable(port);
}
void
unset_disable_port(Port *port)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(port);
}
@ -608,7 +574,6 @@ disable_instance(Instance *instance,
LibertyPort *from,
LibertyPort *to)
{
cmdLinkedNetwork();
Sta::sta()->disable(instance, from, to);
}
@ -617,84 +582,72 @@ unset_disable_instance(Instance *instance,
LibertyPort *from,
LibertyPort *to)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(instance, from, to);
}
void
disable_pin(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->disable(pin);
}
void
unset_disable_pin(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(pin);
}
void
disable_edge(Edge *edge)
{
cmdLinkedNetwork();
Sta::sta()->disable(edge);
}
void
unset_disable_edge(Edge *edge)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(edge);
}
void
disable_timing_arc_set(TimingArcSet *arc_set)
{
cmdLinkedNetwork();
Sta::sta()->disable(arc_set);
}
void
unset_disable_timing_arc_set(TimingArcSet *arc_set)
{
cmdLinkedNetwork();
Sta::sta()->removeDisable(arc_set);
}
void
disable_clock_gating_check_inst(Instance *inst)
{
cmdLinkedNetwork();
Sta::sta()->disableClockGatingCheck(inst);
}
void
disable_clock_gating_check_pin(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->disableClockGatingCheck(pin);
}
void
unset_disable_clock_gating_check_inst(Instance *inst)
{
cmdLinkedNetwork();
Sta::sta()->removeDisableClockGatingCheck(inst);
}
void
unset_disable_clock_gating_check_pin(Pin *pin)
{
cmdLinkedNetwork();
Sta::sta()->removeDisableClockGatingCheck(pin);
}
EdgeSeq
disabled_edges_sorted()
{
cmdLinkedNetwork();
return Sta::sta()->disabledEdgesSorted();
}
@ -713,7 +666,6 @@ make_false_path(ExceptionFrom *from,
const MinMaxAll *min_max,
const char *comment)
{
cmdLinkedNetwork();
Sta::sta()->makeFalsePath(from, thrus, to, min_max, comment);
}
@ -726,7 +678,6 @@ make_multicycle_path(ExceptionFrom *from,
int path_multiplier,
const char *comment)
{
cmdLinkedNetwork();
Sta::sta()->makeMulticyclePath(from, thrus, to, min_max, use_end_clk,
path_multiplier, comment);
}
@ -740,7 +691,6 @@ make_path_delay(ExceptionFrom *from,
float delay,
const char *comment)
{
cmdLinkedNetwork();
Sta::sta()->makePathDelay(from, thrus, to, min_max,
ignore_clk_latency, delay, comment);
}
@ -751,7 +701,6 @@ reset_path_cmd(ExceptionFrom *
ExceptionTo *to,
const MinMaxAll *min_max)
{
cmdLinkedNetwork();
Sta::sta()->resetPath(from, thrus, to, min_max);
// from/to and thru are owned and deleted by the caller.
// ExceptionThruSeq thrus arg is made by TclListSeqExceptionThru
@ -767,7 +716,6 @@ make_group_path(const char *name,
ExceptionTo *to,
const char *comment)
{
cmdLinkedNetwork();
if (name[0] == '\0')
name = nullptr;
Sta::sta()->makeGroupPath(name, is_default, from, thrus, to, comment);
@ -776,7 +724,6 @@ make_group_path(const char *name,
bool
is_path_group_name(const char *name)
{
cmdLinkedNetwork();
return Sta::sta()->isGroupPathName(name);
}
@ -786,7 +733,6 @@ make_exception_from(PinSet *from_pins,
InstanceSet *from_insts,
const RiseFallBoth *from_tr)
{
cmdLinkedNetwork();
return Sta::sta()->makeExceptionFrom(from_pins, from_clks, from_insts,
from_tr);
}
@ -811,7 +757,6 @@ make_exception_thru(PinSet *pins,
InstanceSet *insts,
const RiseFallBoth *rf)
{
cmdLinkedNetwork();
return Sta::sta()->makeExceptionThru(pins, nets, insts, rf);
}
@ -828,7 +773,6 @@ make_exception_to(PinSet *to_pins,
const RiseFallBoth *rf,
RiseFallBoth *end_rf)
{
cmdLinkedNetwork();
return Sta::sta()->makeExceptionTo(to_pins, to_clks, to_insts, rf, end_rf);
}
@ -918,7 +862,6 @@ set_input_slew_cmd(Port *port,
const MinMaxAll *min_max,
float slew)
{
cmdLinkedNetwork();
Sta::sta()->setInputSlew(port, rf, min_max, slew);
}
@ -946,7 +889,6 @@ set_drive_resistance_cmd(Port *port,
const MinMaxAll *min_max,
float res)
{
cmdLinkedNetwork();
Sta::sta()->setDriveResistance(port, rf, min_max, res);
}
@ -957,7 +899,6 @@ set_slew_limit_clk(Clock *clk,
const MinMax *min_max,
float slew)
{
cmdLinkedNetwork();
Sta::sta()->setSlewLimit(clk, rf, clk_data, min_max, slew);
}
@ -966,7 +907,6 @@ set_slew_limit_port(Port *port,
const MinMax *min_max,
float slew)
{
cmdLinkedNetwork();
Sta::sta()->setSlewLimit(port, min_max, slew);
}
@ -975,7 +915,6 @@ set_slew_limit_cell(Cell *cell,
const MinMax *min_max,
float slew)
{
cmdLinkedNetwork();
Sta::sta()->setSlewLimit(cell, min_max, slew);
}
@ -1147,7 +1086,6 @@ unset_timing_derate_cmd()
Clock *
find_clock(const char *name)
{
cmdLinkedNetwork();
return Sta::sta()->sdc()->findClock(name);
}
@ -1168,7 +1106,6 @@ find_clocks_matching(const char *pattern,
bool regexp,
bool nocase)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
Sdc *sdc = sta->sdc();
PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
@ -1178,22 +1115,19 @@ find_clocks_matching(const char *pattern,
void
update_generated_clks()
{
cmdLinkedNetwork();
Sta::sta()->updateGeneratedClks();
}
bool
is_clock(Pin *pin)
{
Sta *sta = Sta::sta();
return sta->isClock(pin);
return Sta::sta()->isClock(pin);
}
bool
is_ideal_clock(Pin *pin)
{
Sta *sta = Sta::sta();
return sta->isIdealClock(pin);
return Sta::sta()->isIdealClock(pin);
}
bool
@ -1258,7 +1192,7 @@ PortSeq
all_inputs_cmd(bool no_clocks)
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
sta->ensureLinked();
return sta->sdc()->allInputs(no_clocks);
}
@ -1266,7 +1200,7 @@ PortSeq
all_outputs_cmd()
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
sta->ensureLinked();
return sta->sdc()->allOutputs();
}

View File

@ -24,7 +24,6 @@
#include "Sta.hh"
using sta::Sta;
using sta::cmdLinkedNetwork;
using sta::AnalysisType;
using sta::MinMax;
using sta::MinMaxAllNull;
@ -51,8 +50,8 @@ read_sdf_file(const char *filename,
bool incremental_only,
MinMaxAllNull *cond_use)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
sta->ensureGraph();
if (stringEq(path, ""))
path = NULL;
@ -72,8 +71,8 @@ report_annotated_delay_cmd(bool report_cells,
bool list_not_annotated,
bool report_constant_arcs)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
sta->ensureGraph();
reportAnnotatedDelay(report_cells, report_nets,
report_in_ports, report_out_ports,
@ -95,8 +94,8 @@ report_annotated_check_cmd(bool report_setup,
bool list_not_annotated,
bool report_constant_arcs)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
sta->ensureGraph();
reportAnnotatedCheck(report_setup, report_hold,
report_recovery, report_removal,
@ -116,8 +115,8 @@ write_sdf_cmd(char *filename,
bool no_timestamp,
bool no_version)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
sta->ensureLinked();
sta->writeSdf(filename, corner, divider, include_typ, digits, gzip,
no_timestamp, no_version);
}

View File

@ -94,7 +94,6 @@ MakeTimingModel::makeTimingModel()
makePorts();
sta_->searchPreamble();
graph_ = sta_->graph();
findTimingFromInputs();
findClkedOutputPaths();
@ -137,12 +136,7 @@ MakeTimingModel::makeLibrary()
{
library_ = network_->makeLibertyLibrary(lib_name_, filename_);
LibertyLibrary *default_lib = network_->defaultLibertyLibrary();
*library_->units()->timeUnit() = *default_lib->units()->timeUnit();
*library_->units()->capacitanceUnit() = *default_lib->units()->capacitanceUnit();
*library_->units()->voltageUnit() = *default_lib->units()->voltageUnit();
*library_->units()->resistanceUnit() = *default_lib->units()->resistanceUnit();
*library_->units()->powerUnit() = *default_lib->units()->powerUnit();
*library_->units()->distanceUnit() = *default_lib->units()->distanceUnit();
*library_->units() = *default_lib->units();
for (RiseFall *rf : RiseFall::range()) {
library_->setInputThreshold(rf, default_lib->inputThreshold(rf));

View File

@ -395,9 +395,7 @@ PrevPathVisitor::visitFromToPath(const Pin *,
PathAPIndex path_ap_index = path_ap->index();
if (to_rf->index() == path_rf_index_
&& path_ap_index == path_ap_index_
&& (dcalc_tol_ > 0.0
? std::abs(delayAsFloat(to_arrival - path_arrival_)) < dcalc_tol_
: delayEqual(to_arrival, path_arrival_))
&& delayEqual(to_arrival, path_arrival_)
&& (tagMatch(to_tag, path_tag_, this)
// If the filter exception became active searching from
// from_path to to_path the tag includes the filter, but

View File

@ -680,7 +680,7 @@ getProperty(const Library *lib,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
if (stringEqual(property, "name")
|| stringEqual(property, "full_name"))
return PropertyValue(network->name(lib));
@ -711,7 +711,7 @@ getProperty(const LibertyCell *cell,
|| stringEqual(property, "base_name"))
return PropertyValue(cell->name());
else if (stringEqual(property, "full_name")) {
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
auto lib = cell->libertyLibrary();
string lib_name = lib->name();
string cell_name = cell->name();
@ -741,7 +741,7 @@ getProperty(const Cell *cell,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
if (stringEqual(property, "name")
|| stringEqual(property, "base_name"))
return PropertyValue(network->name(cell));
@ -767,7 +767,7 @@ getProperty(const Port *port,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
if (stringEqual(property, "name")
|| stringEqual(property, "full_name"))
return PropertyValue(network->name(port));
@ -819,7 +819,7 @@ portSlewProperty(const Port *port,
const MinMax *min_max,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
Instance *top_inst = network->topInstance();
Pin *pin = network->findPin(top_inst, port);
return pinSlewProperty(pin, min_max, sta);
@ -831,7 +831,7 @@ portSlewProperty(const Port *port,
const MinMax *min_max,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
Instance *top_inst = network->topInstance();
Pin *pin = network->findPin(top_inst, port);
return pinSlewProperty(pin, rf, min_max, sta);
@ -842,7 +842,7 @@ portSlackProperty(const Port *port,
const MinMax *min_max,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
Instance *top_inst = network->topInstance();
Pin *pin = network->findPin(top_inst, port);
return pinSlackProperty(pin, min_max, sta);
@ -854,7 +854,7 @@ portSlackProperty(const Port *port,
const MinMax *min_max,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
Instance *top_inst = network->topInstance();
Pin *pin = network->findPin(top_inst, port);
return pinSlackProperty(pin, rf, min_max, sta);
@ -937,7 +937,7 @@ getProperty(const Instance *inst,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
LibertyCell *liberty_cell = network->libertyCell(inst);
if (stringEqual(property, "name"))
return PropertyValue(network->name(inst));
@ -972,7 +972,7 @@ getProperty(const Pin *pin,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
if (stringEqual(property, "name")
|| stringEqual(property, "lib_pin_name"))
return PropertyValue(network->portName(pin));
@ -1122,7 +1122,7 @@ getProperty(const Net *net,
const char *property,
Sta *sta)
{
auto network = sta->cmdNetwork();
Network *network = sta->ensureLinked();
if (stringEqual(property, "name"))
return PropertyValue(network->name(net));
else if (stringEqual(property, "full_name"))
@ -1139,8 +1139,8 @@ getProperty(Edge *edge,
Sta *sta)
{
if (stringEqual(property, "full_name")) {
auto network = sta->cmdNetwork();
auto graph = sta->graph();
Network *network = sta->ensureLinked();
Graph *graph = sta->ensureGraph();
const char *from = edge->from(graph)->name(network);
const char *to = edge->to(graph)->name(network);
string full_name;

View File

@ -25,62 +25,6 @@
#include "search/ReportPath.hh"
#include "Sta.hh"
namespace sta {
////////////////////////////////////////////////////////////////
//
// C++ helper functions used by the interface functions.
// These are not visible in the TCL API.
//
////////////////////////////////////////////////////////////////
// Get the network for commands.
Network *
cmdNetwork()
{
return Sta::sta()->cmdNetwork();
}
// Make sure the network has been read and linked.
// Throwing an error means the caller doesn't have to check the result.
Network *
cmdLinkedNetwork()
{
Network *network = cmdNetwork();
if (network->isLinked())
return network;
else {
Report *report = Sta::sta()->report();
report->error(1570, "no network has been linked.");
return nullptr;
}
}
// Make sure an editable network has been read and linked.
NetworkEdit *
cmdEditNetwork()
{
Network *network = cmdLinkedNetwork();
if (network->isEditable())
return dynamic_cast<NetworkEdit*>(network);
else {
Report *report = Sta::sta()->report();
report->error(1571, "network does not support edits.");
return nullptr;
}
}
// Get the graph for commands.
// Throw to cmd level on failure.
Graph *
cmdGraph()
{
cmdLinkedNetwork();
return Sta::sta()->ensureGraph();
}
} // namespace
using namespace sta;
%}
@ -194,7 +138,6 @@ delete_all_memory()
void
find_timing_cmd(bool full)
{
cmdLinkedNetwork();
Sta::sta()->updateTiming(full);
}
@ -226,46 +169,37 @@ endpoint_path_count()
void
find_requireds()
{
cmdLinkedNetwork();
Sta::sta()->findRequireds();
}
Slack
total_negative_slack_cmd(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
return sta->totalNegativeSlack(min_max);
return Sta::sta()->totalNegativeSlack(min_max);
}
Slack
total_negative_slack_corner_cmd(const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
return sta->totalNegativeSlack(corner, min_max);
return Sta::sta()->totalNegativeSlack(corner, min_max);
}
Slack
worst_slack_cmd(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
Slack worst_slack;
Vertex *worst_vertex;
sta->worstSlack(min_max, worst_slack, worst_vertex);
Sta::sta()->worstSlack(min_max, worst_slack, worst_vertex);
return worst_slack;
}
Vertex *
worst_slack_vertex(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
Slack worst_slack;
Vertex *worst_vertex;
sta->worstSlack(min_max, worst_slack, worst_vertex);
Sta::sta()->worstSlack(min_max, worst_slack, worst_vertex);
return worst_vertex;;
}
@ -273,11 +207,9 @@ Slack
worst_slack_corner(const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
Slack worst_slack;
Vertex *worst_vertex;
sta->worstSlack(corner, min_max, worst_slack, worst_vertex);
Sta::sta()->worstSlack(corner, min_max, worst_slack, worst_vertex);
return worst_slack;
}
@ -286,6 +218,7 @@ vertex_worst_arrival_path(Vertex *vertex,
const MinMax *min_max)
{
Sta *sta = Sta::sta();
sta->ensureLinked();
PathRef path = sta->vertexWorstArrivalPath(vertex, min_max);
if (!path.isNull())
return new PathRef(path);
@ -299,6 +232,7 @@ vertex_worst_arrival_path_rf(Vertex *vertex,
MinMax *min_max)
{
Sta *sta = Sta::sta();
sta->ensureLinked();
PathRef path = sta->vertexWorstArrivalPath(vertex, rf, min_max);
if (!path.isNull())
return new PathRef(path);
@ -311,6 +245,7 @@ vertex_worst_slack_path(Vertex *vertex,
const MinMax *min_max)
{
Sta *sta = Sta::sta();
sta->ensureLinked();
PathRef path = sta->vertexWorstSlackPath(vertex, min_max);
if (!path.isNull())
return new PathRef(path);
@ -400,8 +335,8 @@ void
report_loops()
{
Sta *sta = Sta::sta();
Network *network = cmdLinkedNetwork();
Graph *graph = cmdGraph();
Network *network = sta->ensureLinked();
Graph *graph = sta->ensureGraph();
Report *report = sta->report();
for (GraphLoop *loop : *sta->graphLoops()) {
loop->report(report, network, graph);
@ -444,7 +379,6 @@ find_path_ends(ExceptionFrom *from,
bool clk_gating_setup,
bool clk_gating_hold)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
PathEndSeq ends = sta->findPathEnds(from, thrus, to, unconstrained,
corner, delay_min_max,
@ -582,7 +516,6 @@ report_clk_skew(ConstClockSeq clks,
bool include_internal_latency,
int digits)
{
cmdLinkedNetwork();
Sta::sta()->reportClkSkew(clks, corner, setup_hold,
include_internal_latency, digits);
}
@ -593,7 +526,6 @@ report_clk_latency(ConstClockSeq clks,
bool include_internal_latency,
int digits)
{
cmdLinkedNetwork();
Sta::sta()->reportClkLatency(clks, corner, include_internal_latency, digits);
}
@ -601,7 +533,6 @@ float
worst_clk_skew_cmd(const SetupHold *setup_hold,
bool include_internal_latency)
{
cmdLinkedNetwork();
return Sta::sta()->findWorstClkSkew(setup_hold, include_internal_latency);
}
@ -610,7 +541,6 @@ worst_clk_skew_cmd(const SetupHold *setup_hold,
MinPulseWidthCheckSeq &
min_pulse_width_violations(const Corner *corner)
{
cmdLinkedNetwork();
return Sta::sta()->minPulseWidthViolations(corner);
}
@ -618,7 +548,6 @@ MinPulseWidthCheckSeq &
min_pulse_width_check_pins(PinSeq *pins,
const Corner *corner)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
MinPulseWidthCheckSeq &checks = sta->minPulseWidthChecks(pins, corner);
delete pins;
@ -628,14 +557,12 @@ min_pulse_width_check_pins(PinSeq *pins,
MinPulseWidthCheckSeq &
min_pulse_width_checks(const Corner *corner)
{
cmdLinkedNetwork();
return Sta::sta()->minPulseWidthChecks(corner);
}
MinPulseWidthCheck *
min_pulse_width_check_slack(const Corner *corner)
{
cmdLinkedNetwork();
return Sta::sta()->minPulseWidthSlack(corner);
}
@ -658,14 +585,12 @@ report_mpw_check(MinPulseWidthCheck *check,
MinPeriodCheckSeq &
min_period_violations()
{
cmdLinkedNetwork();
return Sta::sta()->minPeriodViolations();
}
MinPeriodCheck *
min_period_check_slack()
{
cmdLinkedNetwork();
return Sta::sta()->minPeriodSlack();
}
@ -688,14 +613,12 @@ report_min_period_check(MinPeriodCheck *check,
MaxSkewCheckSeq &
max_skew_violations()
{
cmdLinkedNetwork();
return Sta::sta()->maxSkewViolations();
}
MaxSkewCheck *
max_skew_check_slack()
{
cmdLinkedNetwork();
return Sta::sta()->maxSkewSlack();
}
@ -719,9 +642,7 @@ Slack
find_clk_min_period(const Clock *clk,
bool ignore_port_paths)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
return sta->findClkMinPeriod(clk, ignore_port_paths);
return Sta::sta()->findClkMinPeriod(clk, ignore_port_paths);
}
////////////////////////////////////////////////////////////////
@ -732,21 +653,18 @@ check_slew_limits(Net *net,
const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->checkSlewLimits(net, violators, corner, min_max);
}
size_t
max_slew_violation_count()
{
cmdLinkedNetwork();
return Sta::sta()->checkSlewLimits(nullptr, true, nullptr, MinMax::max()).size();
}
float
max_slew_check_slack()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
Slew slew;
@ -759,7 +677,6 @@ max_slew_check_slack()
float
max_slew_check_limit()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
Slew slew;
@ -798,21 +715,18 @@ check_fanout_limits(Net *net,
bool violators,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->checkFanoutLimits(net, violators, min_max);
}
size_t
max_fanout_violation_count()
{
cmdLinkedNetwork();
return Sta::sta()->checkFanoutLimits(nullptr, true, MinMax::max()).size();
}
float
max_fanout_check_slack()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
float fanout;
@ -825,7 +739,6 @@ max_fanout_check_slack()
float
max_fanout_check_limit()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
float fanout;
@ -863,21 +776,18 @@ check_capacitance_limits(Net *net,
const Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->checkCapacitanceLimits(net, violators, corner, min_max);
}
size_t
max_capacitance_violation_count()
{
cmdLinkedNetwork();
return Sta::sta()->checkCapacitanceLimits(nullptr, true,nullptr,MinMax::max()).size();
}
float
max_capacitance_check_slack()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
float capacitance;
@ -890,7 +800,6 @@ max_capacitance_check_slack()
float
max_capacitance_check_limit()
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
const Pin *pin;
float capacitance;
@ -984,7 +893,6 @@ check_timing_cmd(bool no_input_delay,
bool loops,
bool generated_clks)
{
cmdLinkedNetwork();
return Sta::sta()->checkTiming(no_input_delay, no_output_delay,
reg_multiple_clks, reg_no_clks,
unconstrained_endpoints,
@ -1002,7 +910,6 @@ find_fanin_pins(PinSeq *to,
bool thru_disabled,
bool thru_constants)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
PinSet fanin = sta->findFaninPins(to, flat, startpoints_only,
inst_levels, pin_levels,
@ -1020,7 +927,6 @@ find_fanin_insts(PinSeq *to,
bool thru_disabled,
bool thru_constants)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
InstanceSet fanin = sta->findFaninInstances(to, flat, startpoints_only,
inst_levels, pin_levels,
@ -1038,7 +944,6 @@ find_fanout_pins(PinSeq *from,
bool thru_disabled,
bool thru_constants)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
PinSet fanout = sta->findFanoutPins(from, flat, endpoints_only,
inst_levels, pin_levels,
@ -1056,7 +961,6 @@ find_fanout_insts(PinSeq *from,
bool thru_disabled,
bool thru_constants)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
InstanceSet fanout = sta->findFanoutInstances(from, flat, endpoints_only,
inst_levels, pin_levels,
@ -1254,7 +1158,6 @@ PropertyValue
pin_property(const Pin *pin,
const char *property)
{
cmdLinkedNetwork();
return getProperty(pin, property, Sta::sta());
}
@ -1262,7 +1165,6 @@ PropertyValue
instance_property(const Instance *inst,
const char *property)
{
cmdLinkedNetwork();
return getProperty(inst, property, Sta::sta());
}
@ -1270,7 +1172,6 @@ PropertyValue
net_property(const Net *net,
const char *property)
{
cmdLinkedNetwork();
return getProperty(net, property, Sta::sta());
}
@ -1321,7 +1222,6 @@ PropertyValue
edge_property(Edge *edge,
const char *property)
{
cmdGraph();
return getProperty(edge, property, Sta::sta());
}
@ -1329,7 +1229,6 @@ PropertyValue
clock_property(Clock *clk,
const char *property)
{
cmdLinkedNetwork();
return getProperty(clk, property, Sta::sta());
}
@ -1337,7 +1236,6 @@ PropertyValue
path_end_property(PathEnd *end,
const char *property)
{
cmdLinkedNetwork();
return getProperty(end, property, Sta::sta());
}
@ -1345,7 +1243,6 @@ PropertyValue
path_ref_property(PathRef *path,
const char *property)
{
cmdLinkedNetwork();
return getProperty(path, property, Sta::sta());
}
@ -1353,7 +1250,6 @@ PropertyValue
timing_arc_set_property(TimingArcSet *arc_set,
const char *property)
{
cmdLinkedNetwork();
return getProperty(arc_set, property, Sta::sta());
}

View File

@ -73,6 +73,7 @@
#include "VisitPathEnds.hh"
#include "PathExpanded.hh"
#include "MakeTimingModel.hh"
#include "spice/WritePathSpice.hh"
namespace sta {
@ -2108,6 +2109,7 @@ Sta::writeSdc(const char *filename,
bool gzip,
bool no_timestamp)
{
ensureLinked();
sta::writeSdc(network_->topInstance(), filename, "write_sdc",
leaf, native, digits, gzip, no_timestamp, sdc_);
}
@ -3308,6 +3310,7 @@ Sta::findDelays(Level level)
void
Sta::delayCalcPreamble()
{
ensureLinked();
ensureClkNetwork();
}
@ -3401,9 +3404,25 @@ Sta::vertexSlew(Vertex *vertex,
////////////////////////////////////////////////////////////////
// Make sure the network has been read and linked.
// Throwing an error means the caller doesn't have to check the result.
Network *
Sta::ensureLinked()
{
if (network_ == nullptr || !network_->isLinked())
report_->error(1570, "No network has been linked.");
// OpenROAD db is inherently linked but may not have associated
// liberty files so check for them here.
if (network_->defaultLibertyLibrary() == nullptr)
report_->error(2141, "No liberty libraries found.");
// Return cmd/sdc network.
return cmd_network_;
}
Graph *
Sta::ensureGraph()
{
ensureLinked();
if (graph_ == nullptr && network_) {
makeGraph();
// Update pointers to graph.
@ -3556,6 +3575,7 @@ Sta::setArcDelay(Edge *edge,
const MinMaxAll *min_max,
ArcDelay delay)
{
ensureGraph();
for (MinMax *mm : min_max->range()) {
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(mm);
DcalcAPIndex ap_index = dcalc_ap->index();
@ -3578,6 +3598,7 @@ Sta::setAnnotatedSlew(Vertex *vertex,
const RiseFallBoth *rf,
float slew)
{
ensureGraph();
for (MinMax *mm : min_max->range()) {
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(mm);
DcalcAPIndex ap_index = dcalc_ap->index();
@ -3608,8 +3629,10 @@ Sta::writeSdf(const char *filename,
void
Sta::removeDelaySlewAnnotations()
{
graph_->removeDelaySlewAnnotations();
delaysInvalid();
if (graph_) {
graph_->removeDelaySlewAnnotations();
delaysInvalid();
}
}
LogicValue
@ -3863,6 +3886,7 @@ Sta::readSpef(const char *filename,
float coupling_cap_factor,
bool reduce)
{
ensureLinked();
setParasiticAnalysisPts(corner != nullptr);
const MinMax *ap_min_max = (min_max == MinMaxAll::all())
? MinMax::max()
@ -3897,6 +3921,7 @@ void
Sta::reportParasiticAnnotation(bool report_unannotated,
const Corner *corner)
{
ensureLinked();
ensureGraph();
sta::reportParasiticAnnotation(report_unannotated, corner, this);
}
@ -4109,19 +4134,18 @@ Sta::disconnectPin(Pin *pin)
void
Sta::makePortPin(const char *port_name,
const char *direction)
PortDirection *dir)
{
ensureLinked();
NetworkReader *network = dynamic_cast<NetworkReader*>(network_);
Instance *top_inst = network->topInstance();
Cell *top_cell = network->cell(top_inst);
Port *port = network->makePort(top_cell, port_name);
PortDirection *dir = PortDirection::find(direction);
if (dir)
network->setDirection(port, dir);
network->setDirection(port, dir);
Pin *pin = network->makePin(top_inst, port, nullptr);
makePortPinAfter(pin);
}
////////////////////////////////////////////////////////////////
//
// Network edit before/after methods.
@ -4744,6 +4768,7 @@ Sta::findRegisterOutputPins(ClockSet *clks,
void
Sta::findRegisterPreamble()
{
ensureLinked();
ensureGraph();
ensureGraphSdcAnnotated();
sim_->ensureConstantsPropagated();
@ -5600,9 +5625,8 @@ Sta::writeTimingModel(const char *lib_name,
const char *filename,
const Corner *corner)
{
if (network()->defaultLibertyLibrary() == nullptr) {
report_->error(2141, "No liberty libraries found.");
}
ensureLinked();
ensureGraph();
LibertyLibrary *library = makeTimingModel(lib_name, cell_name, filename,
corner, this);
writeLiberty(library, filename, this);
@ -5613,6 +5637,7 @@ Sta::writeTimingModel(const char *lib_name,
void
Sta::powerPreamble()
{
ensureLinked();
// Use arrivals to find clocking info.
searchPreamble();
search_->findAllArrivals();
@ -5650,6 +5675,24 @@ Sta::findClkedActivity(const Pin *pin)
////////////////////////////////////////////////////////////////
void
Sta::writePathSpice(PathRef *path,
const char *spice_filename,
const char *subckt_filename,
const char *lib_subckt_filename,
const char *model_filename,
const char *power_name,
const char *gnd_name,
CircuitSim ckt_sim)
{
ensureLinked();
sta::writePathSpice(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename,
power_name, gnd_name, ckt_sim, this);
}
////////////////////////////////////////////////////////////////
void
Sta::ensureClkNetwork()
{

View File

@ -265,32 +265,34 @@ WorstSlack::updateWorstSlack(Vertex *vertex,
SlackSeq &slacks,
PathAPIndex path_ap_index)
{
Slack slack = slacks[path_ap_index];
// Do not touch the state unless queue has been initialized
if (!queue_->empty()) {
Slack slack = slacks[path_ap_index];
// Locking is required because ArrivalVisitor is called by multiple
// threads.
LockGuard lock(lock_);
if (worst_vertex_
&& delayLess(slack, worst_slack_, this))
setWorstSlack(vertex, slack);
else if (vertex == worst_vertex_)
// Mark worst slack as unknown (updated by findWorstSlack().
worst_vertex_ = nullptr;
// Locking is required because ArrivalVisitor is called by multiple
// threads.
LockGuard lock(lock_);
if (worst_vertex_
&& delayLess(slack, worst_slack_, this))
setWorstSlack(vertex, slack);
else if (vertex == worst_vertex_)
// Mark worst slack as unknown (updated by findWorstSlack().
worst_vertex_ = nullptr;
if (!delayEqual(slack, slack_init_)
&& delayLessEqual(slack, slack_threshold_, this)) {
debugPrint(debug_, "wns", 3, "insert %s %s",
vertex->name(network_),
delayAsString(slack, this));
queue_->insert(vertex);
if (!delayEqual(slack, slack_init_)
&& delayLessEqual(slack, slack_threshold_, this)) {
debugPrint(debug_, "wns", 3, "insert %s %s",
vertex->name(network_),
delayAsString(slack, this));
queue_->insert(vertex);
}
else {
debugPrint(debug_, "wns", 3, "delete %s %s",
vertex->name(network_),
delayAsString(slack, this));
queue_->erase(vertex);
}
//checkQueue(path_ap_index);
}
else {
debugPrint(debug_, "wns", 3, "delete %s %s",
vertex->name(network_),
delayAsString(slack, this));
queue_->erase(vertex);
}
// checkQueue();
}
void

View File

@ -161,8 +161,6 @@ writePathSpice(Path *path,
CircuitSim ckt_sim,
StaState *sta)
{
if (sta->network()->defaultLibertyLibrary() == nullptr)
sta->report()->error(1600, "No liberty libraries found,");
WritePathSpice writer(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename,
power_name, gnd_name, ckt_sim, sta);

View File

@ -35,9 +35,9 @@ write_path_spice_cmd(PathRef *path,
CircuitSim ckt_sim)
{
Sta *sta = Sta::sta();
writePathSpice(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename,
power_name, gnd_name, ckt_sim, sta);
sta->writePathSpice(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename,
power_name, gnd_name, ckt_sim);
}
%} // inline

View File

@ -48,13 +48,6 @@ namespace sta {
typedef MinPulseWidthCheckSeq::Iterator MinPulseWidthCheckSeqIterator;
typedef MinMaxAll MinMaxAllNull;
Network *
cmdNetwork();
Network *
cmdLinkedNetwork();
Graph *
cmdGraph();
template <class TYPE>
Vector<TYPE> *
tclListSeqPtr(Tcl_Obj *const source,
@ -671,6 +664,19 @@ using namespace sta;
Tcl_SetResult(interp, const_cast<char*>(str), TCL_STATIC);
}
%typemap(in) PortDirection* {
int length;
const char *arg = Tcl_GetStringFromObj($input, &length);
PortDirection *dir = PortDirection::find(arg);
if (dir == nullptr) {
Tcl_SetResult(interp,const_cast<char*>("Error: port direction not found."),
TCL_STATIC);
return TCL_ERROR;
}
else
$1 = dir;
}
%typemap(in) TimingRole* {
int length;
const char *arg = Tcl_GetStringFromObj($input, &length);
@ -851,12 +857,12 @@ using namespace sta;
}
%typemap(in) PinSet {
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
$1 = tclListNetworkSet1<PinSet, Pin>($input, SWIGTYPE_p_Pin, interp, network);
}
%typemap(in) PinSet* {
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
$1 = tclListNetworkSet<PinSet, Pin>($input, SWIGTYPE_p_Pin, interp, network);
}
@ -892,7 +898,7 @@ using namespace sta;
}
%typemap(in) InstanceSet* {
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
$1 = tclListNetworkSet<InstanceSet, Instance>($input, SWIGTYPE_p_Instance,
interp, network);
}
@ -902,7 +908,7 @@ using namespace sta;
}
%typemap(in) NetSet* {
Network *network = cmdNetwork();
Network *network = Sta::sta()->ensureLinked();
$1 = tclListNetworkSet<NetSet, Net>($input, SWIGTYPE_p_Net, interp, network);
}

695
test/liberty_latch3.lib Normal file
View File

@ -0,0 +1,695 @@
/*
BSD 3-Clause License
Copyright 2020 Lawrence T. Clark, Vinay Vashishtha, or Arizona State
University
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
library (asap7sc7p5t_lvt_ff) {
/* Models written by Liberate 18.1.0.293 from Cadence Design Systems, Inc. on Wed Dec 2 15:24:06 MST 2020 */
comment : "";
date : "$Date: Wed Dec 2 11:09:27 2020 $";
revision : "1.0";
delay_model : table_lookup;
capacitive_load_unit (1,ff);
current_unit : "1mA";
leakage_power_unit : "1pW";
pulling_resistance_unit : "1kohm";
time_unit : "1ps";
voltage_unit : "1V";
voltage_map (VDD, 0.77);
voltage_map (VSS, 0);
voltage_map (GND, 0);
default_cell_leakage_power : 0;
default_fanout_load : 1;
default_max_transition : 320;
default_output_pin_cap : 0;
in_place_swap_mode : match_footprint;
input_threshold_pct_fall : 50;
input_threshold_pct_rise : 50;
nom_process : 1;
nom_temperature : 0;
nom_voltage : 0.77;
output_threshold_pct_fall : 50;
output_threshold_pct_rise : 50;
slew_derate_from_library : 1;
slew_lower_threshold_pct_fall : 10;
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
operating_conditions (PVT_0P77V_0C) {
process : 1;
temperature : 0;
voltage : 0.77;
}
default_operating_conditions : PVT_0P77V_0C;
lu_table_template (constraint_template_7x7) {
variable_1 : constrained_pin_transition;
variable_2 : related_pin_transition;
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("5, 10, 20, 40, 80, 160, 320");
}
lu_table_template (delay_template_7x7) {
variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance;
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
}
lu_table_template (mpw_constraint_template_7x7) {
variable_1 : constrained_pin_transition;
index_1 ("5, 10, 20, 40, 80, 160, 320");
}
power_lut_template (passive_power_template_7x1) {
variable_1 : input_transition_time;
index_1 ("5, 10, 20, 40, 80, 160, 320");
}
power_lut_template (power_template_7x7) {
variable_1 : input_transition_time;
variable_2 : total_output_net_capacitance;
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
}
lu_table_template (waveform_template_name) {
variable_1 : input_net_transition;
variable_2 : normalized_voltage;
index_1 ("0, 1000, 2000, 3000, 4000, 5000, 6000");
index_2 ("0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16");
}
input_voltage (default_VDD_VSS_input) {
vil : 0;
vih : 0.77;
vimin : 0;
vimax : 0.77;
}
output_voltage (default_VDD_VSS_output) {
vol : 0;
voh : 0.77;
vomin : 0;
vomax : 0.77;
}
normalized_driver_waveform (waveform_template_name) {
driver_waveform_name : "PreDriver20.5:rise";
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0, 0.03, 0.1, 0.158744, 0.221271, 0.279374, 0.333513, 0.3841, 0.437223, 0.533203, 0.58153, 0.626864, 0.717883, 0.806555, 0.9, 0.958983, 1");
values ( \
"0, 0.375, 0.625, 0.84375, 1.09375, 1.34375, 1.59375, 1.84375, 2.125, 2.6875, 3, 3.3125, 4, 4.75, 5.625, 6.21875, 6.65625", \
"0, 0.75, 1.25, 1.6875, 2.1875, 2.6875, 3.1875, 3.6875, 4.25, 5.375, 6, 6.625, 8, 9.5, 11.25, 12.4375, 13.3125", \
"0, 1.5, 2.5, 3.375, 4.375, 5.375, 6.375, 7.375, 8.5, 10.75, 12, 13.25, 16, 19, 22.5, 24.875, 26.625", \
"0, 3, 5, 6.75, 8.75, 10.75, 12.75, 14.75, 17, 21.5, 24, 26.5, 32, 38, 45, 49.75, 53.25", \
"0, 6, 10, 13.5, 17.5, 21.5, 25.5, 29.5, 34, 43, 48, 53, 64, 76, 90, 99.5, 106.5", \
"0, 12, 20, 27, 35, 43, 51, 59, 68, 86, 96, 106, 128, 152, 180, 199, 213", \
"0, 24, 40, 54, 70, 86, 102, 118, 136, 172, 192, 212, 256, 304, 360, 398, 426" \
);
}
normalized_driver_waveform (waveform_template_name) {
driver_waveform_name : "PreDriver20.5:fall";
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0, 0.03, 0.1, 0.158744, 0.221271, 0.279374, 0.333513, 0.3841, 0.437223, 0.533203, 0.58153, 0.626864, 0.717883, 0.806555, 0.9, 0.958983, 1");
values ( \
"0, 0.375, 0.625, 0.84375, 1.09375, 1.34375, 1.59375, 1.84375, 2.125, 2.6875, 3, 3.3125, 4, 4.75, 5.625, 6.21875, 6.65625", \
"0, 0.75, 1.25, 1.6875, 2.1875, 2.6875, 3.1875, 3.6875, 4.25, 5.375, 6, 6.625, 8, 9.5, 11.25, 12.4375, 13.3125", \
"0, 1.5, 2.5, 3.375, 4.375, 5.375, 6.375, 7.375, 8.5, 10.75, 12, 13.25, 16, 19, 22.5, 24.875, 26.625", \
"0, 3, 5, 6.75, 8.75, 10.75, 12.75, 14.75, 17, 21.5, 24, 26.5, 32, 38, 45, 49.75, 53.25", \
"0, 6, 10, 13.5, 17.5, 21.5, 25.5, 29.5, 34, 43, 48, 53, 64, 76, 90, 99.5, 106.5", \
"0, 12, 20, 27, 35, 43, 51, 59, 68, 86, 96, 106, 128, 152, 180, 199, 213", \
"0, 24, 40, 54, 70, 86, 102, 118, 136, 172, 192, 212, 256, 304, 360, 398, 426" \
);
}
normalized_driver_waveform (waveform_template_name) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0, 0.03, 0.1, 0.158744, 0.221271, 0.279374, 0.333513, 0.3841, 0.437223, 0.533203, 0.58153, 0.626864, 0.717883, 0.806555, 0.9, 0.958983, 1");
values ( \
"0, 0.375, 0.625, 0.84375, 1.09375, 1.34375, 1.59375, 1.84375, 2.125, 2.6875, 3, 3.3125, 4, 4.75, 5.625, 6.21875, 6.65625", \
"0, 0.75, 1.25, 1.6875, 2.1875, 2.6875, 3.1875, 3.6875, 4.25, 5.375, 6, 6.625, 8, 9.5, 11.25, 12.4375, 13.3125", \
"0, 1.5, 2.5, 3.375, 4.375, 5.375, 6.375, 7.375, 8.5, 10.75, 12, 13.25, 16, 19, 22.5, 24.875, 26.625", \
"0, 3, 5, 6.75, 8.75, 10.75, 12.75, 14.75, 17, 21.5, 24, 26.5, 32, 38, 45, 49.75, 53.25", \
"0, 6, 10, 13.5, 17.5, 21.5, 25.5, 29.5, 34, 43, 48, 53, 64, 76, 90, 99.5, 106.5", \
"0, 12, 20, 27, 35, 43, 51, 59, 68, 86, 96, 106, 128, 152, 180, 199, 213", \
"0, 24, 40, 54, 70, 86, 102, 118, 136, 172, 192, 212, 256, 304, 360, 398, 426" \
);
}
cell (DHLx1_ASAP7_75t_L) {
area : 0.2187;
pg_pin (VDD) {
pg_type : primary_power;
voltage_name : "VDD";
}
pg_pin (VSS) {
pg_type : primary_ground;
voltage_name : "VSS";
}
leakage_power () {
value : 1031.33;
when : "(CLK * D * Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(CLK * D * Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 1017.31;
when : "(CLK * !D * !Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(CLK * !D * !Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 925.49;
when : "(!CLK * D * Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(!CLK * D * Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 1096.56;
when : "(!CLK * D * !Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(!CLK * D * !Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 1092.29;
when : "(!CLK * !D * Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(!CLK * !D * Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 885.023;
when : "(!CLK * !D * !Q)";
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
when : "(!CLK * !D * !Q)";
related_pg_pin : VSS;
}
leakage_power () {
value : 1008;
related_pg_pin : VDD;
}
leakage_power () {
value : 0;
related_pg_pin : VSS;
}
pin (Q) {
direction : output;
function : "IQ";
power_down_function : "(!VDD) + (VSS)";
related_ground_pin : VSS;
related_power_pin : VDD;
max_capacitance : 46.08;
output_voltage : default_VDD_VSS_output;
timing () {
related_pin : "CLK";
timing_sense : non_unate;
timing_type : rising_edge;
cell_rise (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"21.1614, 23.2981, 27.0988, 34.0405, 47.3581, 73.7725, 126.523", \
"22.3511, 24.4872, 28.2888, 35.2281, 48.5477, 74.9598, 127.712", \
"23.9037, 26.0392, 29.8406, 36.7801, 50.0973, 76.5092, 129.257", \
"25.9511, 28.082, 31.883, 38.8236, 52.1375, 78.5463, 131.299", \
"28.4362, 30.5682, 34.3672, 41.3168, 54.6827, 81.0632, 133.774", \
"31.0428, 33.1711, 36.963, 43.8923, 57.1961, 83.6099, 136.463", \
"32.686, 34.8008, 38.5938, 45.5238, 58.8681, 85.2399, 138.087" \
);
}
rise_transition (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"7.79414, 11.5368, 18.8099, 33.4824, 63.3579, 123.731, 245.205", \
"7.79154, 11.5361, 18.8108, 33.4875, 63.3577, 123.732, 245.205", \
"7.78371, 11.5305, 18.8064, 33.4819, 63.3573, 123.727, 245.203", \
"7.81739, 11.5513, 18.7957, 33.484, 63.3557, 123.744, 245.209", \
"7.76026, 11.5284, 18.7893, 33.788, 63.4404, 123.764, 245.206", \
"7.7172, 11.4809, 18.7629, 33.5017, 63.3555, 124.925, 245.291", \
"7.6747, 11.4316, 18.7229, 33.4319, 63.5063, 124.325, 246.41" \
);
}
cell_fall (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"19.2917, 21.4734, 25.1301, 31.5476, 43.4978, 66.9883, 113.878", \
"20.405, 22.5842, 26.2424, 32.6594, 44.6112, 68.1023, 114.985", \
"22.0696, 24.2459, 27.9059, 34.327, 46.2791, 69.7709, 116.661", \
"24.1533, 26.3402, 30.0076, 36.4381, 48.3961, 71.8967, 118.791", \
"26.8017, 28.997, 32.689, 39.1409, 51.1122, 74.6251, 121.512", \
"29.6897, 31.918, 35.6586, 42.146, 54.139, 77.6484, 124.538", \
"31.6237, 33.9307, 37.7467, 44.3197, 56.3913, 79.8808, 126.8" \
);
}
fall_transition (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"7.5992, 10.738, 16.7849, 28.8078, 53.3304, 103.254, 204.112", \
"7.60649, 10.7381, 16.7879, 28.8078, 53.3308, 103.252, 204.114", \
"7.65929, 10.788, 16.8235, 28.8253, 53.3388, 103.263, 204.113", \
"7.75423, 10.8792, 16.8944, 28.8873, 53.383, 103.276, 204.122", \
"7.97139, 11.0657, 17.0653, 29.0032, 53.6124, 103.329, 204.137", \
"8.4066, 11.5057, 17.4152, 29.2575, 53.6898, 103.694, 204.176", \
"9.2738, 12.3052, 18.1273, 29.9595, 54.0074, 103.843, 205.394" \
);
}
}
timing () {
related_pin : "D";
timing_sense : positive_unate;
timing_type : combinational;
cell_rise (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"13.0805, 15.2373, 19.0634, 26.0004, 39.3102, 65.7145, 118.459", \
"13.6094, 15.7536, 19.5646, 26.4962, 39.8027, 66.2071, 118.937", \
"14.47, 16.6406, 20.4889, 27.4374, 40.747, 67.1471, 119.893", \
"15.6199, 17.8513, 21.7354, 28.7155, 42.0934, 68.5213, 121.256", \
"17.1638, 19.462, 23.4316, 30.4716, 43.8797, 70.4827, 123.182", \
"18.6062, 21.0546, 25.2719, 32.6, 46.1541, 72.7053, 125.573", \
"18.7828, 21.5173, 26.1115, 33.8529, 47.9358, 75.0976, 128.217" \
);
}
rise_transition (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"7.83278, 11.5576, 18.8116, 33.4858, 63.3484, 123.722, 245.184", \
"7.87592, 11.5929, 18.8433, 33.5, 63.3568, 123.732, 245.199", \
"8.12202, 11.8139, 19.0161, 33.6163, 63.4113, 123.747, 245.187", \
"8.47385, 12.165, 19.3565, 33.946, 63.59, 123.853, 245.244", \
"9.33921, 13.0301, 20.0752, 34.5193, 64.3371, 124.172, 245.422", \
"10.9973, 14.7228, 21.7216, 35.9278, 65.1203, 125.053, 245.796", \
"13.7433, 17.5871, 24.6877, 38.8749, 67.8104, 127.878, 249.248" \
);
}
cell_fall (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"14.4902, 16.6726, 20.3596, 26.753, 38.6907, 62.1895, 109.08", \
"15.2678, 17.4289, 21.1145, 27.5065, 39.4421, 62.942, 109.835", \
"16.771, 18.9591, 22.6487, 29.0671, 40.9947, 64.4924, 111.382", \
"19.3014, 21.5359, 25.3291, 31.801, 43.7872, 67.288, 114.178", \
"23.7807, 26.1218, 30.0544, 36.6397, 48.6928, 72.2703, 119.191", \
"31.2324, 33.8095, 38.0345, 44.9265, 57.1922, 80.8379, 127.784", \
"43.4742, 46.3871, 51.1215, 58.6543, 71.5239, 95.7484, 142.984" \
);
}
fall_transition (delay_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"7.6312, 10.7998, 16.8166, 28.8144, 53.316, 103.224, 204.097", \
"7.64623, 10.8132, 16.8296, 28.8256, 53.3201, 103.225, 204.099", \
"7.91922, 11.05, 17.0303, 28.9311, 53.3711, 103.24, 204.101", \
"8.39805, 11.5495, 17.5097, 29.352, 53.6431, 103.388, 204.146", \
"9.35239, 12.4863, 18.3299, 30.2475, 54.1693, 103.618, 204.311", \
"11.1644, 14.3558, 20.1693, 31.5851, 55.4, 104.531, 204.621", \
"14.2488, 17.5918, 23.4309, 34.7782, 58.5932, 106.96, 208.593" \
);
}
}
internal_power () {
related_pin : "CLK";
related_pg_pin : VDD;
rise_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.578788, 0.57942, 0.581732, 0.584543, 0.588114, 0.590559, 0.592046", \
"0.57882, 0.579166, 0.581755, 0.584608, 0.58796, 0.59042, 0.591955", \
"0.586975, 0.587723, 0.589885, 0.592977, 0.596353, 0.598771, 0.600331", \
"0.615104, 0.615243, 0.617064, 0.620391, 0.623449, 0.625478, 0.626966", \
"0.683734, 0.685593, 0.686595, 0.69796, 0.697604, 0.697512, 0.696506", \
"0.836576, 0.837734, 0.839903, 0.847748, 0.856263, 0.890643, 0.856754", \
"1.16065, 1.16126, 1.16401, 1.16979, 1.17857, 1.19042, 1.21555" \
);
}
fall_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.639863, 0.639925, 0.641473, 0.643613, 0.644662, 0.645462, 0.645554", \
"0.63914, 0.638897, 0.640432, 0.6424, 0.64365, 0.644319, 0.64462", \
"0.64715, 0.646396, 0.647927, 0.649884, 0.651195, 0.651958, 0.652203", \
"0.673937, 0.672444, 0.673547, 0.67558, 0.677106, 0.677968, 0.678376", \
"0.745676, 0.743536, 0.743869, 0.745129, 0.746644, 0.747919, 0.748522", \
"0.912701, 0.907547, 0.905917, 0.906592, 0.90789, 0.908756, 0.909274", \
"1.2764, 1.26755, 1.26309, 1.26148, 1.26171, 1.26187, 1.26293" \
);
}
}
internal_power () {
related_pin : "CLK";
related_pg_pin : VSS;
rise_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.751901, 0.752522, 0.754812, 0.757538, 0.761059, 0.763475, 0.765012", \
"0.752102, 0.752432, 0.755073, 0.757919, 0.761216, 0.763706, 0.765239", \
"0.759948, 0.76073, 0.76289, 0.765942, 0.769233, 0.771638, 0.773213", \
"0.787275, 0.787465, 0.789673, 0.793189, 0.796495, 0.798533, 0.800108", \
"0.85727, 0.858365, 0.859292, 0.863811, 0.866123, 0.867989, 0.869071", \
"1.00985, 1.01181, 1.01431, 1.01715, 1.01924, 1.02162, 1.02262", \
"1.33379, 1.3346, 1.33736, 1.3399, 1.34252, 1.34456, 1.34679" \
);
}
fall_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.780412, 0.780417, 0.781942, 0.784013, 0.785067, 0.785785, 0.785952", \
"0.779691, 0.779472, 0.781023, 0.783, 0.784266, 0.784911, 0.785204", \
"0.786502, 0.785637, 0.787094, 0.788993, 0.790287, 0.791025, 0.791228", \
"0.813647, 0.811719, 0.812081, 0.814379, 0.815751, 0.816546, 0.816902", \
"0.885505, 0.883031, 0.883766, 0.885544, 0.894934, 0.888152, 0.88737", \
"1.0527, 1.04748, 1.04583, 1.04751, 1.05386, 1.05646, 1.05261", \
"1.41702, 1.40814, 1.40479, 1.40924, 1.40901, 1.42282, 1.43401" \
);
}
}
internal_power () {
related_pin : "D";
related_pg_pin : VDD;
rise_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.340604, 0.342144, 0.345282, 0.349072, 0.351857, 0.353603, 0.3545", \
"0.33928, 0.339758, 0.342172, 0.345222, 0.347782, 0.349387, 0.35028", \
"0.347422, 0.34526, 0.347506, 0.350398, 0.352578, 0.353949, 0.355076", \
"0.37198, 0.371453, 0.372159, 0.376085, 0.374868, 0.377249, 0.377875", \
"0.455181, 0.452029, 0.449999, 0.446395, 0.466058, 0.456956, 0.45484", \
"0.663305, 0.652269, 0.641248, 0.636488, 0.634141, 0.637032, 0.63845", \
"1.11351, 1.09258, 1.07466, 1.06295, 1.04961, 1.07328, 1.09299" \
);
}
fall_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.512588, 0.511827, 0.513046, 0.514539, 0.516051, 0.516882, 0.517322", \
"0.511356, 0.510022, 0.510964, 0.512737, 0.514143, 0.514909, 0.515587", \
"0.519653, 0.517543, 0.518142, 0.518794, 0.520526, 0.521599, 0.52233", \
"0.55558, 0.550232, 0.548113, 0.54897, 0.550118, 0.551448, 0.551978", \
"0.650955, 0.642207, 0.637436, 0.63479, 0.63452, 0.636494, 0.63755", \
"0.875889, 0.861922, 0.849879, 0.841621, 0.837306, 0.835961, 0.835724", \
"1.34508, 1.32013, 1.29802, 1.28001, 1.26814, 1.26115, 1.25828" \
);
}
}
internal_power () {
related_pin : "D";
related_pg_pin : VSS;
rise_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.535823, 0.537345, 0.540452, 0.544199, 0.546907, 0.548704, 0.549491", \
"0.535989, 0.537126, 0.540088, 0.543488, 0.546201, 0.54791, 0.548866", \
"0.541746, 0.541136, 0.54326, 0.547444, 0.549643, 0.551945, 0.552443", \
"0.567238, 0.565072, 0.565115, 0.568158, 0.570997, 0.573725, 0.57516", \
"0.651683, 0.647209, 0.642535, 0.641334, 0.643201, 0.644801, 0.646903", \
"0.85895, 0.848177, 0.836791, 0.830028, 0.827457, 0.827283, 0.828263", \
"1.30852, 1.28748, 1.26868, 1.25579, 1.2412, 1.23464, 1.23044" \
);
}
fall_power (power_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("0.72, 1.44, 2.88, 5.76, 11.52, 23.04, 46.08");
values ( \
"0.317699, 0.31696, 0.31823, 0.319788, 0.321364, 0.322222, 0.322691", \
"0.316541, 0.315002, 0.31584, 0.317611, 0.318989, 0.319777, 0.320545", \
"0.326067, 0.32281, 0.321602, 0.32475, 0.324398, 0.324543, 0.324946", \
"0.36164, 0.355317, 0.353927, 0.354813, 0.354849, 0.354666, 0.354358", \
"0.457044, 0.447502, 0.443701, 0.446478, 0.445304, 0.440467, 0.440408", \
"0.680425, 0.667646, 0.654159, 0.645821, 0.652126, 0.646507, 0.643844", \
"1.15082, 1.12762, 1.10333, 1.08712, 1.08636, 1.08704, 1.13991" \
);
}
}
}
pin (CLK) {
driver_waveform_fall : "PreDriver20.5:fall";
driver_waveform_rise : "PreDriver20.5:rise";
clock : true;
direction : input;
input_signal_level : VDD;
related_ground_pin : VSS;
related_power_pin : VDD;
max_transition : 320;
capacitance : 0.536816;
rise_capacitance : 0.536816;
rise_capacitance_range (0.44002, 0.536816);
fall_capacitance : 0.536716;
fall_capacitance_range (0.4323, 0.536716);
input_voltage : default_VDD_VSS_input;
timing () {
related_pin : "CLK";
sdf_cond : "D";
timing_type : min_pulse_width;
when : "D";
rise_constraint (mpw_constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"13.4277, 13.4277, 20.752, 40.2832, 80.5664, 161.133, 321.045" \
);
}
}
timing () {
related_pin : "CLK";
sdf_cond : "~D";
timing_type : min_pulse_width;
when : "!D";
rise_constraint (mpw_constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"13.4277, 15.8691, 20.752, 40.2832, 80.5664, 161.133, 321.045" \
);
}
}
internal_power () {
when : "(D * Q)";
related_pg_pin : VDD;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.225261, 0.225169, 0.233039, 0.257545, 0.32299, 0.472231, 0.791592" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.387303, 0.38607, 0.395977, 0.427343, 0.499634, 0.66167, 1.00104" \
);
}
}
internal_power () {
when : "(D * Q)";
related_pg_pin : VSS;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.39248, 0.392277, 0.399956, 0.423881, 0.489922, 0.639662, 0.958902" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.219796, 0.219348, 0.229369, 0.26039, 0.332204, 0.494297, 0.834116" \
);
}
}
internal_power () {
when : "(!D * !Q)";
related_pg_pin : VDD;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.242325, 0.241434, 0.249807, 0.274778, 0.3412, 0.492285, 0.814514" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.373311, 0.372586, 0.381887, 0.412922, 0.485723, 0.647358, 0.98763" \
);
}
}
internal_power () {
when : "(!D * !Q)";
related_pg_pin : VSS;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.402001, 0.401299, 0.408964, 0.434029, 0.500575, 0.651956, 0.974197" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.213136, 0.212637, 0.222604, 0.253057, 0.326356, 0.487469, 0.827705" \
);
}
}
}
pin (D) {
driver_waveform_fall : "PreDriver20.5:fall";
driver_waveform_rise : "PreDriver20.5:rise";
direction : input;
input_signal_level : VDD;
related_ground_pin : VSS;
related_power_pin : VDD;
max_transition : 320;
capacitance : 0.654168;
rise_capacitance : 0.654168;
rise_capacitance_range (0.527218, 0.654168);
fall_capacitance : 0.650172;
fall_capacitance_range (0.529507, 0.650172);
input_voltage : default_VDD_VSS_input;
timing () {
related_pin : "CLK";
timing_type : hold_falling;
rise_constraint (constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"1.94092, 7.12938, 9.44704, 10.8789, 17.5566, 24.9045, 35.1453", \
"1.62363, 2.81459, 5.13226, 9.5106, 17.2393, 24.5873, 34.828", \
"1.01565, 2.20661, 4.52427, 8.90261, 16.6313, 23.9793, 34.22", \
"0.937499, 1.09696, 3.41463, 8.90625, 15.5217, 22.8696, 34.2285", \
"-0.186769, 1.00419, 3.32186, 7.70019, 15.4289, 22.7769, 37.0151", \
"-0.372317, 0.81864, 3.13631, 7.51465, 15.2433, 22.5913, 36.8295", \
"3.25409, 4.44504, 6.76271, 8.26171, 14.8722, 26.2177, 40.4559" \
);
}
fall_constraint (constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"-0.653379, -0.148157, 0.835406, -0.231933, 1.98663, 6.84453, 13.6765", \
"-1.02394, -0.51872, 0.464843, -1.67305, 1.61607, 6.47397, 13.3059", \
"-1.76089, -1.25567, -0.272104, -2.41, 0.879123, 5.73702, 12.569", \
"-6.16455, -2.71286, -1.72929, -2.73438, -0.578065, 4.27984, 8.24219", \
"-10.0631, -9.5579, -8.57434, -6.71473, -3.42561, 1.43229, 8.26422", \
"-15.4909, -14.9857, -14.0021, -12.1425, -8.85337, -3.99547, -1.16104", \
"-25.2771, -20.7744, -23.7883, -20.8106, -18.6396, -17.7792, -10.9473" \
);
}
}
timing () {
related_pin : "CLK";
timing_type : setup_falling;
rise_constraint (constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"2.06055, 0.576188, -2.30622, -6.67481, -9.18917, -18.5849, -31.2723", \
"2.39349, 0.909133, -1.97328, -3.39539, -8.85623, -18.2519, -30.9393", \
"3.03493, 1.55057, -1.33185, -2.75395, -8.21479, -17.6105, -30.2979", \
"5.25147, 2.73561, -0.1468, -4.45312, -7.02975, -16.4254, -31.9922", \
"6.19877, 4.71441, 1.832, 0.409896, -9.04844, -14.4466, -31.1316", \
"9.45841, 7.97405, 5.09163, -0.327972, -5.78881, -15.1845, -27.8719", \
"7.11548, 5.63113, 2.74871, -1.55273, -4.13423, -13.5299, -30.2148" \
);
}
fall_constraint (constraint_template_7x7) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
index_2 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"10.4623, 9.99238, 9.09082, 4.51416, 7.20987, 6.74739, 9.81994", \
"11.1994, 10.7294, 9.82784, 8.17813, 7.94689, 7.48441, 10.557", \
"12.6442, 12.1743, 11.2727, 9.62298, 5.39424, 8.92927, 8.00432", \
"12.4707, 10.9497, 10.0482, 9.53125, 8.1672, 7.70473, 7.97948", \
"16.4986, 16.0286, 15.127, 13.4773, 13.2461, 8.78612, 7.86117", \
"24.7883, 24.3183, 23.4167, 21.767, 17.5383, 17.0758, 12.1534", \
"37.8928, 37.4228, 36.5212, 31.9922, 30.6428, 26.1828, 25.2579" \
);
}
}
internal_power () {
when : "!CLK";
related_pg_pin : VDD;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"-0.0567798, -0.0577731, -0.0586042, -0.0591243, -0.0593412, -0.0596455, -0.0599353" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.0642583, 0.064148, 0.0643755, 0.0640553, 0.0644328, 0.0638341, 0.0633937" \
);
}
}
internal_power () {
when : "!CLK";
related_pg_pin : VSS;
rise_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"0.103555, 0.102645, 0.102255, 0.101774, 0.100733, 0.0999289, 0.0993267" \
);
}
fall_power (passive_power_template_7x1) {
index_1 ("5, 10, 20, 40, 80, 160, 320");
values ( \
"-0.0949566, -0.0949741, -0.0955851, -0.0960081, -0.0970478, -0.0965245, -0.0960774" \
);
}
}
}
latch ("D",IQ,IQN) {
data_in : "D";
enable : "CLK";
power_down_function : "(!VDD) + (VSS)";
}
}
}

0
test/liberty_latch3.ok Normal file
View File

2
test/liberty_latch3.tcl Normal file
View File

@ -0,0 +1,2 @@
# Read Liberty latch group with data inputs as first parameter
read_liberty liberty_latch3.lib

View File

@ -132,6 +132,7 @@ record_sta_tests {
get_objrefs
get_lib_pins_of_objects
report_checks_src_attr
liberty_latch3
}
define_test_group fast [group_tests all]