diff --git a/configure.ac b/configure.ac
index ac18ea6e..08625c15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,6 +148,15 @@ AC_ARG_ENABLE(asan,
esac],
[asan=false])
+AC_ARG_ENABLE(ssta,
+ [AS_HELP_STRING([--enable-ssta],[enable ssta])],
+ [case "${enableval}" in
+ yes) ssta=true ;;
+ no) ssta=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-ssta) ;;
+ esac],
+ [ssta=false])
+
AC_ARG_WITH(include,
[AS_HELP_STRING([--with-include=dirs],[directories to search for include files])],
[INCLUDE_DIRS="${withval}"],
@@ -188,6 +197,14 @@ AC_ARG_WITH(optimize,
[],
[])
+#--------------------------------------------------------------------
+
+if test x$ssta = xtrue; then
+ AC_DEFINE(SSTA, 1, "SSTA support")
+else
+ AC_DEFINE(SSTA, 0, "SSTA support")
+fi
+
#--------------------------------------------------------------------
# Locate the Tcl package
#--------------------------------------------------------------------
@@ -411,8 +428,8 @@ AC_FUNC_ERROR_AT_LINE
#--------------------------------------------------------------------
if test $CXX = clang++; then
- # -Wno-deprecated-register to suppress warnings in flex files
- CXXFLAGS="-std=c++11 -Wall -Wno-deprecated-register -Wcast-qual"
+ # suppress deprecated-register warnings in flex files.
+ CXXFLAGS="-std=c++11 -Wall -Wcast-qual -Wunused-parameter -Wno-deprecated-register"
CXX_OPT="-O3"
CXX_DEBUG="-g"
CXX_ASAN="-fsanitize=address -O1 -fno-omit-frame-pointer"
diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc
index c8a1ad75..f350bfed 100644
--- a/dcalc/GraphDelayCalc1.cc
+++ b/dcalc/GraphDelayCalc1.cc
@@ -739,9 +739,9 @@ GraphDelayCalc1::driveCellDefaultFromPort(LibertyCell *cell,
{
LibertyPort *from_port = 0;
int from_port_index = 0;
- CellTimingArcSetIterator *set_iter = cell->timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *arc_set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell);
+ while (set_iter.hasNext()) {
+ TimingArcSet *arc_set = set_iter.next();
if (arc_set->to() == to_port) {
LibertyPort *set_from_port = arc_set->from();
int set_from_port_index = findPortIndex(cell, set_from_port);
@@ -752,7 +752,6 @@ GraphDelayCalc1::driveCellDefaultFromPort(LibertyCell *cell,
}
}
}
- delete set_iter;
return from_port;
}
@@ -762,16 +761,13 @@ GraphDelayCalc1::findPortIndex(LibertyCell *cell,
LibertyPort *port)
{
int index = 0;
- LibertyCellPortIterator *port_iter = cell->libertyPortIterator();
- while (port_iter->hasNext()) {
- LibertyPort *cell_port = port_iter->next();
- if (cell_port == port) {
- delete port_iter;
+ LibertyCellPortIterator port_iter(cell);
+ while (port_iter.hasNext()) {
+ LibertyPort *cell_port = port_iter.next();
+ if (cell_port == port)
return index;
- }
index++;
}
- delete port_iter;
internalError("port not found in cell");
return 0;
}
@@ -789,24 +785,22 @@ GraphDelayCalc1::findInputDriverDelay(LibertyCell *drvr_cell,
debugPrint2(debug_, "delay_calc", 2, " driver cell %s %s\n",
drvr_cell->name(),
tr->asString());
- CellTimingArcSetIterator *set_iter = drvr_cell->timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *arc_set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(drvr_cell);
+ while (set_iter.hasNext()) {
+ TimingArcSet *arc_set = set_iter.next();
if (arc_set->from() == from_port
&& arc_set->to() == to_port) {
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
if (arc->toTrans()->asRiseFall() == tr) {
float from_slew = from_slews[arc->fromTrans()->index()];
findInputArcDelay(drvr_cell, drvr_pin, drvr_vertex,
arc, from_slew, dcalc_ap);
}
}
- delete arc_iter;
}
}
- delete set_iter;
}
// Driving cell delay is the load dependent delay, which is the gate
@@ -1026,9 +1020,9 @@ GraphDelayCalc1::findDriverEdgeDelays(LibertyCell *drvr_cell,
const Pvt *pvt = sdc_->pvt(drvr_inst, dcalc_ap->constraintMinMax());
if (pvt == NULL)
pvt = dcalc_ap->operatingConditions();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
const TransRiseFall *tr = arc->toTrans()->asRiseFall();
Parasitic *parasitic;
bool delete_parasitic;
@@ -1054,7 +1048,6 @@ GraphDelayCalc1::findDriverEdgeDelays(LibertyCell *drvr_cell,
arc_delay_calc->finish(drvr_pin, tr, dcalc_ap,
parasitic, delete_parasitic);
}
- delete arc_iter;
}
if (delay_changed && observer_) {
@@ -1369,9 +1362,9 @@ GraphDelayCalc1::findMultiDrvrGateDelay(MultiDrvrNet *multi_drvr,
Edge *edge1 = edge_iter.next();
TimingArcSet *arc_set1 = edge1->timingArcSet();
const LibertyPort *related_out_port = arc_set1->relatedOut();
- TimingArcSetArcIterator *arc_iter = arc_set1->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc1 = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set1);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc1 = arc_iter.next();
TransRiseFall *drvr_tr1 = arc1->toTrans()->asRiseFall();
if (drvr_tr1 == drvr_tr) {
Vertex *from_vertex1 = edge1->from(graph_);
@@ -1420,7 +1413,6 @@ GraphDelayCalc1::findMultiDrvrGateDelay(MultiDrvrNet *multi_drvr,
parasitic1, delete_parasitic1);
}
}
- delete arc_iter;
}
}
}
@@ -1570,9 +1562,9 @@ GraphDelayCalc1::findCheckEdgeDelays(Edge *edge,
Instance *inst = network_->instance(to_pin);
const LibertyCell *cell = network_->libertyCell(inst);
bool delay_changed = false;
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
TransRiseFall *from_tr = arc->fromTrans()->asRiseFall();
TransRiseFall *to_tr = arc->toTrans()->asRiseFall();
if (from_tr && to_tr) {
@@ -1631,7 +1623,6 @@ GraphDelayCalc1::findCheckEdgeDelays(Edge *edge,
}
}
}
- delete arc_iter;
if (delay_changed && observer_)
observer_->checkDelayChangedTo(to_vertex);
}
diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt
index 048d53af..bc0eec26 100644
Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ
diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf
index 7572462c..98f5b22a 100644
Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ
diff --git a/graph/Delay.hh b/graph/Delay.hh
index 159ca218..49111487 100644
--- a/graph/Delay.hh
+++ b/graph/Delay.hh
@@ -14,32 +14,20 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include "config.h"
+
#ifndef STA_DELAY_H
#define STA_DELAY_H
-// Define one of the following:
-
-// Define DELAY_FLOAT to use the float definitions.
-#define DELAY_FLOAT
-
-// Define DELAY_FLOAT_CLASS to use the DelayClass definitions.
-//#define DELAY_FLOAT_CLASS
-
-// Define DELAY_NORMAL2 to use the DelayNormal2 definitions.
-//#define DELAY_NORMAL2
-
-#ifdef DELAY_FLOAT
+#if SSTA
+ // Delays are Normal PDFs with early/late sigma.
+ #include "DelayNormal2.hh"
+#else
+ // Delays are floats.
#include "DelayFloat.hh"
#endif
-#ifdef DELAY_FLOAT_CLASS
- #include "DelayFloatClass.hh"
-#endif
-
-#ifdef DELAY_NORMAL2
- #include "DelayNormal2.hh"
-#endif
-
+// API common to DelayFloat and DelayNormal2.
namespace sta {
class Units;
@@ -59,6 +47,13 @@ makeDelay(float delay,
float sigma_late);
float
delayAsFloat(const Delay &delay);
+// mean late+/early- sigma
+float
+delayAsFloat(const Delay &delay,
+ const EarlyLate *early_late);
+float
+delaySigma(const Delay &delay,
+ const EarlyLate *early_late);
const char *
delayAsString(const Delay &delay,
const Units *units);
@@ -69,16 +64,11 @@ const char *
delayAsString(const Delay &delay,
const Units *units,
int digits);
-// mean late+/early- sigma
-// early_late = NULL returns mean.
-float
-delayMeanSigma(const Delay &delay,
- const EarlyLate *early_late);
const char *
-delayMeanSigmaString(const Delay &delay,
- const EarlyLate *early_late,
- const Units *units,
- int digits);
+delayAsString(const Delay &delay,
+ const EarlyLate *early_late,
+ const Units *units,
+ int digits);
const Delay &
delayInitValue(const MinMax *min_max);
bool
diff --git a/graph/DelayFloat.cc b/graph/DelayFloat.cc
index 1ab8b4b2..cca8198c 100644
--- a/graph/DelayFloat.cc
+++ b/graph/DelayFloat.cc
@@ -14,14 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include "config.h"
#include "Machine.hh"
#include "Fuzzy.hh"
#include "Units.hh"
#include "StaState.hh"
#include "Delay.hh"
-// Conditional compilation based on delay abstraction from Delay.hh.
-#ifdef DELAY_FLOAT
+// Non-SSTA compilation.
+#if !SSTA
namespace sta {
@@ -154,21 +155,28 @@ delayAsString(const Delay &delay,
}
float
-delayMeanSigma(const Delay &delay,
- const EarlyLate *)
+delayAsFloat(const Delay &delay,
+ const EarlyLate *)
{
return delay;
}
const char *
-delayMeanSigmaString(const Delay &delay,
- const EarlyLate *,
- const Units *units,
- int digits)
+delayAsString(const Delay &delay,
+ const EarlyLate *,
+ const Units *units,
+ int digits)
{
const Unit *unit = units->timeUnit();
return unit->asString(delay, digits);
}
+float
+delaySigma(const Delay &,
+ const EarlyLate *)
+{
+ return 0.0;
+}
+
} // namespace
#endif
diff --git a/graph/DelayNormal2.cc b/graph/DelayNormal2.cc
index 7a5218a9..b58af8bc 100644
--- a/graph/DelayNormal2.cc
+++ b/graph/DelayNormal2.cc
@@ -14,16 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+#include "config.h"
#include // sqrt
#include "Machine.hh"
+#include "Error.hh"
#include "StringUtil.hh"
#include "Fuzzy.hh"
#include "Units.hh"
#include "StaState.hh"
#include "Delay.hh"
-// Conditional compilation based on delay abstraction from Delay.hh.
-#ifdef DELAY_NORMAL2
+// SSTA compilation.
+#if SSTA
namespace sta {
@@ -338,6 +340,25 @@ delayRatio(const Delay &delay1,
return delay1.mean() / delay2.mean();
}
+float
+delayAsFloat(const Delay &delay,
+ const EarlyLate *early_late)
+{
+ if (early_late == EarlyLate::early())
+ return delay.mean() - delay.sigmaEarly();
+ else if (early_late == EarlyLate::late())
+ return delay.mean() + delay.sigmaLate();
+ else
+ internalError("unknown early/late value.");
+}
+
+float
+delaySigma(const Delay &delay,
+ const EarlyLate *early_late)
+{
+ return delay.sigma(early_late);
+}
+
const char *
delayAsString(const Delay &delay,
const Units *units,
@@ -360,10 +381,10 @@ delayAsString(const Delay &delay,
}
const char *
-delayMeanSigmaString(const Delay &delay,
- const EarlyLate *early_late,
- const Units *units,
- int digits)
+delayAsString(const Delay &delay,
+ const EarlyLate *early_late,
+ const Units *units,
+ int digits)
{
float mean_sigma = delay.mean();
if (early_late == EarlyLate::early())
@@ -373,17 +394,5 @@ delayMeanSigmaString(const Delay &delay,
return units->timeUnit()->asString(mean_sigma, digits);
}
-float
-delayMeanSigma(const Delay &delay,
- const EarlyLate *early_late)
-{
- if (early_late == EarlyLate::early())
- return delay.mean() - delay.sigmaEarly();
- else if (early_late == EarlyLate::late())
- return delay.mean() + delay.sigmaLate();
- else
- return delay.mean();
-}
-
} // namespace
#endif
diff --git a/graph/Graph.cc b/graph/Graph.cc
index 53b91b00..2490a156 100644
--- a/graph/Graph.cc
+++ b/graph/Graph.cc
@@ -144,10 +144,9 @@ Graph::vertexAndEdgeCounts(const Instance *inst,
vertex_count++;
if (cell) {
LibertyPort *port = network_->libertyPort(pin);
- CellTimingArcSetIterator *set_iter =
- cell->timingArcSetFromIterator(port);
- while (set_iter->hasNext()) {
- TimingArcSet *arc_set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, port, NULL);
+ while (set_iter.hasNext()) {
+ TimingArcSet *arc_set = set_iter.next();
LibertyPort *to_port = arc_set->to();
if (network_->findPin(inst, to_port)) {
if (dir->isBidirect()) {
@@ -161,7 +160,6 @@ Graph::vertexAndEdgeCounts(const Instance *inst,
}
}
}
- delete set_iter;
}
// Count wire edges from driver pins.
if (network_->isDriver(pin))
@@ -284,9 +282,9 @@ Graph::makePortInstanceEdges(const Instance *inst,
LibertyCell *cell,
LibertyPort *from_to_port)
{
- CellTimingArcSetIterator *timing_iter = cell->timingArcSetIterator();
- while (timing_iter->hasNext()) {
- TimingArcSet *arc_set = timing_iter->next();
+ LibertyCellTimingArcSetIterator timing_iter(cell);
+ while (timing_iter.hasNext()) {
+ TimingArcSet *arc_set = timing_iter.next();
LibertyPort *from_port = arc_set->from();
LibertyPort *to_port = arc_set->to();
if (from_to_port == NULL
@@ -327,7 +325,6 @@ Graph::makePortInstanceEdges(const Instance *inst,
}
}
}
- delete timing_iter;
}
void
@@ -915,31 +912,27 @@ Graph::removeDelayAnnotated(Edge *edge)
{
edge->setDelayAnnotationIsIncremental(false);
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
for (DcalcAPIndex ap_index = 0; ap_index < ap_count_; ap_index++) {
setArcDelayAnnotated(edge, arc, ap_index, false);
}
}
- delete arc_iter;
}
bool
Graph::delayAnnotated(Edge *edge)
{
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
for (DcalcAPIndex ap_index = 0; ap_index < ap_count_; ap_index++) {
- if (arcDelayAnnotated(edge, arc, ap_index)) {
- delete arc_iter;
+ if (arcDelayAnnotated(edge, arc, ap_index))
return true;
- }
}
}
- delete arc_iter;
return false;
}
diff --git a/graph/Makefile.am b/graph/Makefile.am
index 9825a8fc..2ffc4ba5 100644
--- a/graph/Makefile.am
+++ b/graph/Makefile.am
@@ -19,7 +19,6 @@ lib_LTLIBRARIES = libgraph.la
include_HEADERS = \
Delay.hh \
DelayFloat.hh \
- DelayFloatClass.hh \
DelayNormal2.hh \
Graph.hh \
GraphClass.hh \
@@ -28,7 +27,6 @@ include_HEADERS = \
libgraph_la_SOURCES = \
Delay.cc \
DelayFloat.cc \
- DelayFloatClass.cc \
DelayNormal2.cc \
Graph.cc \
GraphCmp.cc
diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc
index 19e95e59..bbb44131 100644
--- a/liberty/EquivCells.cc
+++ b/liberty/EquivCells.cc
@@ -87,9 +87,9 @@ findEquivCells1(const LibertyLibrary *library)
{
LibertyCellHashMap cell_hash;
LibertyCellEquivMap *cell_equivs = new LibertyCellEquivMap;
- LibertyLibraryCellIterator *cell_iter = library->libertyCellIterator();
- while (cell_iter->hasNext()) {
- LibertyCell *cell = cell_iter->next();
+ LibertyCellIterator cell_iter(library);
+ while (cell_iter.hasNext()) {
+ LibertyCell *cell = cell_iter.next();
if (!cell->dontUse()) {
bool found_equiv = false;
unsigned hash = hashCell(cell);
@@ -121,7 +121,6 @@ findEquivCells1(const LibertyLibrary *library)
}
}
}
- delete cell_iter;
LibertyCellHashMap::Iterator hash_iter(cell_hash);
while (hash_iter.hasNext()) {
@@ -159,13 +158,13 @@ float
cellDriveResistance(const LibertyCell *cell)
{
float max_drive = 0.0;
- CellTimingArcSetIterator *set_iter = cell->timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
if (!set->role()->isTimingCheck()) {
- TimingArcSetArcIterator *arc_iter = set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
GateTimingModel *model = dynamic_cast(arc->model());
if (model) {
float drive = model->driveResistance(cell, NULL);
@@ -173,10 +172,8 @@ cellDriveResistance(const LibertyCell *cell)
max_drive = drive;
}
}
- delete arc_iter;
}
}
- delete set_iter;
return max_drive;
}
@@ -190,14 +187,13 @@ static unsigned
hashCellPorts(const LibertyCell *cell)
{
unsigned hash = 0;
- LibertyCellPortIterator *port_iter = cell->libertyPortIterator();
- while (port_iter->hasNext()) {
- LibertyPort *port = port_iter->next();
+ LibertyCellPortIterator port_iter(cell);
+ while (port_iter.hasNext()) {
+ LibertyPort *port = port_iter.next();
hash += hashPort(port);
hash += hashFuncExpr(port->function()) * 3;
hash += hashFuncExpr(port->tristateEnable()) * 5;
}
- delete port_iter;
return hash;
}
@@ -212,9 +208,9 @@ static unsigned
hashCellSequentials(const LibertyCell *cell)
{
unsigned hash = 0;
- CellSequentialIterator *seq_iter = cell->sequentialIterator();
- while (seq_iter->hasNext()) {
- Sequential *seq = seq_iter->next();
+ LibertyCellSequentialIterator seq_iter(cell);
+ while (seq_iter.hasNext()) {
+ Sequential *seq = seq_iter.next();
hash += hashFuncExpr(seq->clock()) * 3;
hash += hashFuncExpr(seq->data()) * 5;
hash += hashPort(seq->output()) * 7;
@@ -224,7 +220,6 @@ hashCellSequentials(const LibertyCell *cell)
hash += seq->clearPresetOutput() * 17;
hash += seq->clearPresetOutputInv() * 19;
}
- delete seq_iter;
return hash;
}
@@ -275,9 +270,9 @@ equivCellPortsAndFuncs(const LibertyCell *cell1,
if (cell1->portCount() != cell2->portCount())
return false;
else {
- LibertyCellPortIterator *port_iter1 = cell1->libertyPortIterator();
- while (port_iter1->hasNext()) {
- LibertyPort *port1 = port_iter1->next();
+ LibertyCellPortIterator port_iter1(cell1);
+ while (port_iter1.hasNext()) {
+ LibertyPort *port1 = port_iter1.next();
const char *name = port1->name();
LibertyPort *port2 = cell2->findLibertyPort(name);
if (!(port2
@@ -285,11 +280,9 @@ equivCellPortsAndFuncs(const LibertyCell *cell1,
&& FuncExpr::equiv(port1->function(), port2->function())
&& FuncExpr::equiv(port1->tristateEnable(),
port2->tristateEnable()))){
- delete port_iter1;
return false;
}
}
- delete port_iter1;
return true;
}
}
@@ -301,17 +294,14 @@ equivCellPorts(const LibertyCell *cell1,
if (cell1->portCount() != cell2->portCount())
return false;
else {
- LibertyCellPortIterator *port_iter1 = cell1->libertyPortIterator();
- while (port_iter1->hasNext()) {
- LibertyPort *port1 = port_iter1->next();
+ LibertyCellPortIterator port_iter1(cell1);
+ while (port_iter1.hasNext()) {
+ LibertyPort *port1 = port_iter1.next();
const char* name = port1->name();
LibertyPort *port2 = cell2->findLibertyPort(name);
- if (!(port2 && LibertyPort::equiv(port1, port2))) {
- delete port_iter1;
+ if (!(port2 && LibertyPort::equiv(port1, port2)))
return false;
- }
}
- delete port_iter1;
return true;
}
}
@@ -320,27 +310,20 @@ static bool
equivCellSequentials(const LibertyCell *cell1,
const LibertyCell *cell2)
{
- bool eq = true;
- CellSequentialIterator *seq_iter1 = cell1->sequentialIterator();
- CellSequentialIterator *seq_iter2 = cell2->sequentialIterator();
- while (seq_iter1->hasNext() && seq_iter2->hasNext()) {
- Sequential *seq1 = seq_iter1->next();
- Sequential *seq2 = seq_iter2->next();
+ LibertyCellSequentialIterator seq_iter1(cell1);
+ LibertyCellSequentialIterator seq_iter2(cell2);
+ while (seq_iter1.hasNext() && seq_iter2.hasNext()) {
+ Sequential *seq1 = seq_iter1.next();
+ Sequential *seq2 = seq_iter2.next();
if (!(FuncExpr::equiv(seq1->clock(), seq2->clock())
&& FuncExpr::equiv(seq1->data(), seq2->data())
&& LibertyPort::equiv(seq1->output(), seq2->output())
&& LibertyPort::equiv(seq1->outputInv(), seq2->outputInv())
&& FuncExpr::equiv(seq1->clear(), seq2->clear())
- && FuncExpr::equiv(seq1->preset(), seq2->preset()))) {
- eq = false;
- break;
- }
+ && FuncExpr::equiv(seq1->preset(), seq2->preset())))
+ return false;
}
- if (seq_iter1->hasNext() || seq_iter2->hasNext())
- eq = false;
- delete seq_iter1;
- delete seq_iter2;
- return eq;
+ return !seq_iter1.hasNext() && !seq_iter2.hasNext();
}
bool
@@ -350,16 +333,13 @@ equivCellTimingArcSets(const LibertyCell *cell1,
if (cell1->timingArcSetCount() != cell2->timingArcSetCount())
return false;
else {
- CellTimingArcSetIterator *set_iter1 = cell1->timingArcSetIterator();
- while (set_iter1->hasNext()) {
- TimingArcSet *set1 = set_iter1->next();
+ LibertyCellTimingArcSetIterator set_iter1(cell1);
+ while (set_iter1.hasNext()) {
+ TimingArcSet *set1 = set_iter1.next();
TimingArcSet *set2 = cell2->findTimingArcSet(set1);
- if (!(set2 && TimingArcSet::equiv(set1, set2))) {
- delete set_iter1;
+ if (!(set2 && TimingArcSet::equiv(set1, set2)))
return false;
- }
}
- delete set_iter1;
return true;
}
}
diff --git a/liberty/InternalPower.cc b/liberty/InternalPower.cc
index 2caadaf7..2f131df1 100644
--- a/liberty/InternalPower.cc
+++ b/liberty/InternalPower.cc
@@ -31,6 +31,21 @@ InternalPowerAttrs::InternalPowerAttrs() :
InternalPowerAttrs::~InternalPowerAttrs()
{
+}
+
+void
+InternalPowerAttrs::deleteContents()
+{
+ TransRiseFallIterator tr_iter;
+ while (tr_iter.hasNext()) {
+ TransRiseFall *tr = tr_iter.next();
+ int tr_index = tr->index();
+ InternalPowerModel *model = models_[tr_index];
+ if (model)
+ delete model;
+ }
+ if (when_)
+ when_->deleteSubexprs();
stringDelete(related_pg_pin_);
}
@@ -63,7 +78,7 @@ InternalPower::InternalPower(LibertyCell *cell,
port_(port),
related_port_(related_port),
when_(attrs->when()),
- related_pg_pin_(stringCopy(attrs->relatedPgPin()))
+ related_pg_pin_(attrs->relatedPgPin())
{
TransRiseFallIterator tr_iter;
while (tr_iter.hasNext()) {
@@ -76,17 +91,7 @@ InternalPower::InternalPower(LibertyCell *cell,
InternalPower::~InternalPower()
{
- TransRiseFallIterator tr_iter;
- while (tr_iter.hasNext()) {
- TransRiseFall *tr = tr_iter.next();
- int tr_index = tr->index();
- InternalPowerModel *model = models_[tr_index];
- if (model)
- delete model;
- }
- if (when_)
- when_->deleteSubexprs();
- stringDelete(related_pg_pin_);
+ // models_, when_ and related_pg_pin_ are owned by InternalPowerAttrs.
}
LibertyCell *
diff --git a/liberty/InternalPower.hh b/liberty/InternalPower.hh
index 9310d52d..efa86b53 100644
--- a/liberty/InternalPower.hh
+++ b/liberty/InternalPower.hh
@@ -30,7 +30,8 @@ class InternalPowerAttrs
{
public:
InternalPowerAttrs();
- ~InternalPowerAttrs();
+ virtual ~InternalPowerAttrs();
+ void deleteContents();
FuncExpr *when() const { return when_; }
FuncExpr *&whenRef() { return when_; }
void setModel(TransRiseFall *tr,
diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc
index 9a1cb5bf..68dba11c 100644
--- a/liberty/Liberty.cc
+++ b/liberty/Liberty.cc
@@ -117,7 +117,7 @@ LibertyLibrary::LibertyLibrary(const char *name,
LibertyLibrary::~LibertyLibrary()
{
bus_dcls_.deleteContents();
- templates_.deleteContents();
+ template_map_.deleteContents();
scale_factors_map_.deleteContents();
delete scale_factors_;
@@ -147,7 +147,7 @@ void
LibertyLibrary::findLibertyCellsMatching(PatternMatch *pattern,
LibertyCellSeq *cells)
{
- LibertyLibraryCellIterator cell_iter(this);
+ LibertyCellIterator cell_iter(this);
while (cell_iter.hasNext()) {
LibertyCell *cell = cell_iter.next();
if (pattern->match(cell->name()))
@@ -155,12 +155,6 @@ LibertyLibrary::findLibertyCellsMatching(PatternMatch *pattern,
}
}
-LibertyLibraryCellIterator *
-LibertyLibrary::libertyCellIterator() const
-{
- return new LibertyLibraryCellIterator(this);
-}
-
void
LibertyLibrary::setDelayModelType(DelayModelType type)
{
@@ -182,25 +176,19 @@ LibertyLibrary::findBusDcl(const char *name) const
void
LibertyLibrary::addTableTemplate(TableTemplate *tbl_template)
{
- templates_[tbl_template->name()] = tbl_template;
+ template_map_[tbl_template->name()] = tbl_template;
}
void
LibertyLibrary::deleteTableTemplate(TableTemplate *tbl_template)
{
- templates_.eraseKey(tbl_template->name());
+ template_map_.eraseKey(tbl_template->name());
}
TableTemplate *
LibertyLibrary::findTableTemplate(const char *name)
{
- return templates_[name];
-}
-
-TableTemplateIterator *
-LibertyLibrary::tableTemplateIterator()
-{
- return new TableTemplateIterator(templates_);
+ return template_map_[name];
}
void
@@ -600,12 +588,6 @@ LibertyLibrary::findOperatingConditions(const char *name)
return operating_conditions_.findKey(name);
}
-OperatingConditionsIterator *
-LibertyLibrary::operatingConditionsIterator()
-{
- return new OperatingConditionsIterator(operating_conditions_);
-}
-
OperatingConditions *
LibertyLibrary::defaultOperatingConditions() const
{
@@ -697,15 +679,14 @@ LibertyLibrary::makeCornerMap(LibertyLibrary *lib,
int ap_index,
Network *network)
{
- LibertyLibraryCellIterator *cell_iter = lib->libertyCellIterator();
- while (cell_iter->hasNext()) {
- LibertyCell *cell = cell_iter->next();
+ LibertyCellIterator cell_iter(lib);
+ while (cell_iter.hasNext()) {
+ LibertyCell *cell = cell_iter.next();
const char *name = cell->name();
LibertyCell *link_cell = network->findLibertyCell(name);
if (link_cell)
makeCornerMap(link_cell, cell, ap_index);
}
- delete cell_iter;
}
// Map a cell linked in the network to the corresponding liberty cell
@@ -717,35 +698,30 @@ LibertyLibrary::makeCornerMap(LibertyCell *link_cell,
{
link_cell->setCornerCell(corner_cell, ap_index);
- LibertyCellPortBitIterator *port_iter = link_cell->libertyPortBitIterator();
- while (port_iter->hasNext()) {
- LibertyPort *link_port = port_iter->next();
+ LibertyCellPortBitIterator port_iter(link_cell);
+ while (port_iter.hasNext()) {
+ LibertyPort *link_port = port_iter.next();
const char *port_name = link_port->name();
LibertyPort *corner_port = corner_cell->findLibertyPort(port_name);
if (corner_port)
link_port->setCornerPort(corner_port, ap_index);
}
- delete port_iter;
- CellTimingArcSetIterator *set_iter = link_cell->timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *link_arc_set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(link_cell);
+ while (set_iter.hasNext()) {
+ TimingArcSet *link_arc_set = set_iter.next();
TimingArcSet *corner_arc_set = corner_cell->findTimingArcSet(link_arc_set);
if (corner_arc_set) {
- TimingArcSetArcIterator *arc_iter = link_arc_set->timingArcIterator();
- TimingArcSetArcIterator *corner_arc_iter =
- corner_arc_set->timingArcIterator();
- while (arc_iter->hasNext() && corner_arc_iter->hasNext()) {
- TimingArc *link_arc = arc_iter->next();
- TimingArc *corner_arc = corner_arc_iter->next();
+ TimingArcSetArcIterator arc_iter(link_arc_set);
+ TimingArcSetArcIterator corner_arc_iter(corner_arc_set);
+ while (arc_iter.hasNext() && corner_arc_iter.hasNext()) {
+ TimingArc *link_arc = arc_iter.next();
+ TimingArc *corner_arc = corner_arc_iter.next();
if (TimingArc::equiv(link_arc, corner_arc))
link_arc->setCornerArc(corner_arc, ap_index);
}
- delete arc_iter;
- delete corner_arc_iter;
}
}
- delete set_iter;
}
////////////////////////////////////////////////////////////////
@@ -788,20 +764,20 @@ LibertyLibrary::addOcvDerate(OcvDerate *derate)
////////////////////////////////////////////////////////////////
-LibertyLibraryCellIterator::LibertyLibraryCellIterator(const LibertyLibrary *
+LibertyCellIterator::LibertyCellIterator(const LibertyLibrary *
library):
iter_(library->cell_map_)
{
}
bool
-LibertyLibraryCellIterator::hasNext()
+LibertyCellIterator::hasNext()
{
return iter_.hasNext();
}
LibertyCell *
-LibertyLibraryCellIterator::next()
+LibertyCellIterator::next()
{
return dynamic_cast(iter_.next());
}
@@ -849,13 +825,13 @@ LibertyCell::~LibertyCell()
latch_d_to_q_map_.deleteContents();
+ deleteTimingArcAttrs();
if (timing_arc_sets_) {
- deleteTimingModels();
timing_arc_sets_->deleteContents();
delete timing_arc_sets_;
delete timing_arc_set_map_;
- LibertyPortTimingArcSetMap::Iterator port_map_iter(port_timing_arc_set_map_);
+ LibertyPortPairTimingArcMap::Iterator port_map_iter(port_timing_arc_set_map_);
while (port_map_iter.hasNext()) {
LibertyPortPair *port_pair;
TimingArcSetSeq *sets;
@@ -872,6 +848,7 @@ LibertyCell::~LibertyCell()
delete timing_arc_set_to_map_;
}
+ deleteInternalPowerAttrs();
if (internal_powers_) {
internal_powers_->deleteContents();
delete internal_powers_;
@@ -900,68 +877,17 @@ LibertyCell::~LibertyCell()
}
// Multiple timing arc sets (buses bits or a related_ports list)
-// can share the same model, cond, and sdf_conds, so collect them
-// into a set so they are only deleted once.
+// can share the same TimingAttrs values (model, cond, and sdf_conds),
+// so collect them into a set so they are only deleted once.
void
-LibertyCell::deleteTimingModels()
+LibertyCell::deleteTimingArcAttrs()
{
- TimingModelSet models;
- FuncExprSet exprs;
- StringSetEq strings;
-
- TimingArcSetSeq::Iterator set_iter(timing_arc_sets_);
- while (set_iter.hasNext()) {
- TimingArcSet *set = set_iter.next();
- TimingArcSetArcIterator *arc_iter = set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
- TimingModel *model = arc->model();
- if (model)
- models.insert(model);
- }
- delete arc_iter;
-
- FuncExpr *cond = set->cond();
- if (cond)
- exprs.insert(cond);
-
- const char *str = set->sdfCondStart();
- if (str)
- strings.insert(str);
-
- str = set->sdfCondEnd();
- if (str)
- strings.insert(str);
-
- str = set->modeName();
- if (str)
- strings.insert(str);
-
- str = set->modeValue();
- if (str)
- strings.insert(str);
-
+ TimingArcAttrsSeq::Iterator attr_iter(timing_arc_attrs_);
+ while (attr_iter.hasNext()) {
+ TimingArcAttrs *attrs = attr_iter.next();
+ attrs->deleteContents();
+ delete attrs;
}
- models.deleteContents();
-
- FuncExprSet::Iterator expr_iter(exprs);
- while (expr_iter.hasNext()) {
- FuncExpr *expr = expr_iter.next();
- expr->deleteSubexprs();
- }
- deleteContents(&strings);
-}
-
-LibertyCellPortIterator *
-LibertyCell::libertyPortIterator() const
-{
- return new LibertyCellPortIterator(this);
-}
-
-LibertyCellPortBitIterator *
-LibertyCell::libertyPortBitIterator() const
-{
- return new LibertyCellPortBitIterator(this);
}
LibertyPort *
@@ -1097,9 +1023,9 @@ LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
if (timing_arc_sets_ == NULL) {
timing_arc_sets_ = new TimingArcSetSeq;
timing_arc_set_map_ = new TimingArcSetMap;
- port_timing_arc_set_map_ = new LibertyPortTimingArcSetMap;
- timing_arc_set_from_map_ = new LibertyPortTimingArcSetSeqMap;
- timing_arc_set_to_map_ = new LibertyPortTimingArcSetSeqMap;
+ port_timing_arc_set_map_ = new LibertyPortPairTimingArcMap;
+ timing_arc_set_from_map_ = new LibertyPortTimingArcMap;
+ timing_arc_set_to_map_ = new LibertyPortTimingArcMap;
}
int set_index = timing_arc_sets_->size();
if (set_index > timing_arc_set_index_max)
@@ -1142,6 +1068,12 @@ LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
return set_index;
}
+void
+LibertyCell::addTimingArcAttrs(TimingArcAttrs *attrs)
+{
+ timing_arc_attrs_.push_back(attrs);
+}
+
void
LibertyCell::addInternalPower(InternalPower *power)
{
@@ -1150,10 +1082,22 @@ LibertyCell::addInternalPower(InternalPower *power)
internal_powers_->push_back(power);
}
-LibertyCellInternalPowerIterator *
-LibertyCell::internalPowerIterator()
-{
- return new LibertyCellInternalPowerIterator(internal_powers_);
+void
+LibertyCell::addInternalPowerAttrs(InternalPowerAttrs *attrs)
+{
+ internal_power_attrs_.push_back(attrs);
+}
+
+void
+LibertyCell::deleteInternalPowerAttrs()
+{
+ InternalPowerAttrsSeq::Iterator attr_iter(internal_power_attrs_);
+ while (attr_iter.hasNext()) {
+ InternalPowerAttrs *attrs = attr_iter.next();
+ attrs->deleteContents();
+ delete attrs;
+ }
+
}
void
@@ -1164,18 +1108,6 @@ LibertyCell::addLeakagePower(LeakagePower *power)
leakage_powers_->push_back(power);
}
-LibertyCellLeakagePowerIterator *
-LibertyCell::leakagePowerIterator()
-{
- return new LibertyCellLeakagePowerIterator(leakage_powers_);
-}
-
-float
-LibertyCell::leakagePower() const
-{
- return leakage_power_;
-}
-
void
LibertyCell::setLeakagePower(float leakage)
{
@@ -1198,7 +1130,7 @@ LibertyCell::finish(bool infer_latches,
void
LibertyCell::findDefaultCondArcs()
{
- LibertyPortTimingArcSetMap::Iterator set_iter1(port_timing_arc_set_map_);
+ LibertyPortPairTimingArcMap::Iterator set_iter1(port_timing_arc_set_map_);
while (set_iter1.hasNext()) {
LibertyPortPair *port_pair;
TimingArcSetSeq *sets;
@@ -1230,18 +1162,17 @@ void
LibertyCell::translatePresetClrCheckRoles()
{
LibertyPortSet pre_clr_ports;
- CellTimingArcSetIterator *set_iter = timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(this);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
if (set->role() == TimingRole::regSetClr())
pre_clr_ports.insert(set->from());
}
- delete set_iter;
if (!pre_clr_ports.empty()) {
- set_iter = timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(this);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
if (pre_clr_ports.findKey(set->to())) {
if (set->role() == TimingRole::setup())
set->setRole(TimingRole::recovery());
@@ -1249,10 +1180,26 @@ LibertyCell::translatePresetClrCheckRoles()
set->setRole(TimingRole::removal());
}
}
- delete set_iter;
}
}
+TimingArcSetSeq *
+LibertyCell::timingArcSets(const LibertyPort *from,
+ const LibertyPort *to) const
+{
+ if (timing_arc_sets_) {
+ if (from && to) {
+ LibertyPortPair port_pair(from, to);
+ return port_timing_arc_set_map_->findKey(&port_pair);
+ }
+ else if (from)
+ return timing_arc_set_from_map_->findKey(from);
+ else if (to)
+ return timing_arc_set_to_map_->findKey(to);
+ }
+ return NULL;
+}
+
TimingArcSet *
LibertyCell::findTimingArcSet(TimingArcSet *key) const
{
@@ -1277,36 +1224,6 @@ LibertyCell::timingArcSetCount() const
return 0;
}
-CellTimingArcSetIterator *
-LibertyCell::timingArcSetIterator() const
-{
- return new CellTimingArcSetIterator(timing_arc_sets_);
-}
-
-CellTimingArcSetIterator *
-LibertyCell::timingArcSetIterator(LibertyPort *from,
- LibertyPort *to) const
-{
- if (timing_arc_sets_) {
- LibertyPortPair port_pair(from, to);
- TimingArcSetSeq *sets = port_timing_arc_set_map_->findKey(&port_pair);
- return new CellTimingArcSetIterator(sets);
- }
- else
- return new CellTimingArcSetIterator(NULL);
-}
-
-CellTimingArcSetIterator *
-LibertyCell::timingArcSetFromIterator(LibertyPort *from) const
-{
- if (timing_arc_sets_) {
- TimingArcSetSeq *sets = timing_arc_set_from_map_->findKey(from);
- return new CellTimingArcSetIterator(sets);
- }
- else
- return new CellTimingArcSetIterator(NULL);
-}
-
bool
LibertyCell::hasTimingArcs(LibertyPort *port) const
{
@@ -1315,17 +1232,6 @@ LibertyCell::hasTimingArcs(LibertyPort *port) const
|| timing_arc_set_to_map_->findKey(port));
}
-CellTimingArcSetIterator *
-LibertyCell::timingArcSetToIterator(LibertyPort *to) const
-{
- if (timing_arc_sets_) {
- TimingArcSetSeq *sets = timing_arc_set_to_map_->findKey(to);
- return new CellTimingArcSetIterator(sets);
- }
- else
- return new CellTimingArcSetIterator(NULL);
-}
-
void
LibertyCell::makeSequential(int size,
bool is_register,
@@ -1386,12 +1292,6 @@ LibertyCell::hasSequentials() const
return sequentials_ && !sequentials_->empty();
}
-CellSequentialIterator *
-LibertyCell::sequentialIterator() const
-{
- return new CellSequentialIterator(sequentials_);
-}
-
void
LibertyCell::addScaledCell(OperatingConditions *op_cond,
LibertyCell *scaled_cell)
@@ -1400,37 +1300,31 @@ LibertyCell::addScaledCell(OperatingConditions *op_cond,
scaled_cells_ = new ScaledCellMap;
(*scaled_cells_)[op_cond] = scaled_cell;
- LibertyCellPortBitIterator *port_iter1 = libertyPortBitIterator();
- LibertyCellPortBitIterator *port_iter2=scaled_cell->libertyPortBitIterator();
- while (port_iter1->hasNext() && port_iter2->hasNext()) {
- LibertyPort *port = port_iter1->next();
- LibertyPort *scaled_port = port_iter2->next();
+ LibertyCellPortBitIterator port_iter1(this);
+ LibertyCellPortBitIterator port_iter2(scaled_cell);
+ while (port_iter1.hasNext() && port_iter2.hasNext()) {
+ LibertyPort *port = port_iter1.next();
+ LibertyPort *scaled_port = port_iter2.next();
port->addScaledPort(op_cond, scaled_port);
}
- delete port_iter1;
- delete port_iter2;
- CellTimingArcSetIterator *set_iter1 = timingArcSetIterator();
- CellTimingArcSetIterator *set_iter2 = scaled_cell->timingArcSetIterator();
- while (set_iter1->hasNext() && set_iter2->hasNext()) {
- TimingArcSet *arc_set1 = set_iter1->next();
- TimingArcSet *arc_set2 = set_iter2->next();
- TimingArcSetArcIterator *arc_iter1 = arc_set1->timingArcIterator();
- TimingArcSetArcIterator *arc_iter2 = arc_set2->timingArcIterator();
- while (arc_iter1->hasNext() && arc_iter2->hasNext()) {
- TimingArc *arc = arc_iter1->next();
- TimingArc *scaled_arc = arc_iter2->next();
+ LibertyCellTimingArcSetIterator set_iter1(this);
+ LibertyCellTimingArcSetIterator set_iter2(scaled_cell);
+ while (set_iter1.hasNext() && set_iter2.hasNext()) {
+ TimingArcSet *arc_set1 = set_iter1.next();
+ TimingArcSet *arc_set2 = set_iter2.next();
+ TimingArcSetArcIterator arc_iter1(arc_set1);
+ TimingArcSetArcIterator arc_iter2(arc_set2);
+ while (arc_iter1.hasNext() && arc_iter2.hasNext()) {
+ TimingArc *arc = arc_iter1.next();
+ TimingArc *scaled_arc = arc_iter2.next();
if (TimingArc::equiv(arc, scaled_arc)) {
TimingModel *model = scaled_arc->model();
model->setIsScaled(true);
arc->addScaledModel(op_cond, model);
}
}
- delete arc_iter1;
- delete arc_iter2;
}
- delete set_iter1;
- delete set_iter2;
}
void
@@ -1519,6 +1413,20 @@ LibertyCell::addOcvDerate(OcvDerate *derate)
////////////////////////////////////////////////////////////////
+LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell) :
+ TimingArcSetSeq::Iterator(cell->timing_arc_sets_)
+{
+}
+
+LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell,
+ const LibertyPort *from,
+ const LibertyPort *to):
+ TimingArcSetSeq::Iterator(cell->timingArcSets(from, to))
+{
+}
+
+////////////////////////////////////////////////////////////////
+
// Latch enable port/function for a latch D->Q timing arc set.
class LatchEnable
{
@@ -1581,30 +1489,28 @@ LibertyCell::makeLatchEnables(Report *report,
{
if (hasSequentials()
|| hasInferedRegTimingArcs()) {
- CellTimingArcSetIterator *set_iter = timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *en_to_q = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(this);
+ while (set_iter.hasNext()) {
+ TimingArcSet *en_to_q = set_iter.next();
if (en_to_q->role() == TimingRole::latchEnToQ()) {
LibertyPort *en = en_to_q->from();
LibertyPort *q = en_to_q->to();
- CellTimingArcSetIterator *to_iter = timingArcSetToIterator(q);
- while (to_iter->hasNext()) {
- TimingArcSet *d_to_q = to_iter->next();
+ LibertyCellTimingArcSetIterator to_iter(this, NULL, q);
+ while (to_iter.hasNext()) {
+ TimingArcSet *d_to_q = to_iter.next();
if (d_to_q->role() == TimingRole::latchDtoQ()) {
LibertyPort *d = d_to_q->from();
- CellTimingArcSetIterator *check_iter = timingArcSetIterator(en, d);
- while (check_iter->hasNext()) {
- TimingArcSet *setup_check = check_iter->next();
+ LibertyCellTimingArcSetIterator check_iter(this, en, d);
+ while (check_iter.hasNext()) {
+ TimingArcSet *setup_check = check_iter.next();
if (setup_check->role() == TimingRole::setup()) {
LatchEnable *latch_enable = makeLatchEnable(d, en, q, d_to_q,
en_to_q,
setup_check,
debug);
- TimingArcSetArcIterator *check_arc_iter =
- setup_check->timingArcIterator();
- if (check_arc_iter->hasNext()) {
- TimingArc *check_arc = check_arc_iter->next();
- delete check_arc_iter;
+ TimingArcSetArcIterator check_arc_iter( setup_check);
+ if (check_arc_iter.hasNext()) {
+ TimingArc *check_arc = check_arc_iter.next();
TransRiseFall *en_tr = latch_enable->enableTransition();
TransRiseFall *check_tr = check_arc->fromTrans()->asRiseFall();
if (check_tr == en_tr) {
@@ -1640,16 +1546,12 @@ LibertyCell::makeLatchEnables(Report *report,
}
break;
}
- delete check_arc_iter;
}
}
- delete check_iter;
}
}
- delete to_iter;
}
}
- delete set_iter;
}
}
@@ -1657,19 +1559,16 @@ FuncExpr *
LibertyCell::findLatchEnableFunc(LibertyPort *data,
LibertyPort *enable) const
{
- CellSequentialIterator *iter = sequentialIterator();
- while (iter->hasNext()) {
- Sequential *seq = iter->next();
+ LibertyCellSequentialIterator iter(this);
+ while (iter.hasNext()) {
+ Sequential *seq = iter.next();
if (seq->isLatch()
&& seq->data()
&& seq->data()->hasPort(data)
&& seq->clock()
- && seq->clock()->hasPort(enable)) {
- delete iter;
+ && seq->clock()->hasPort(enable))
return seq->clock();
- }
}
- delete iter;
return NULL;
}
@@ -1703,16 +1602,16 @@ LibertyCell::inferLatchRoles(Debug *debug)
if (hasInferedRegTimingArcs()) {
// Hunt down potential latch D/EN/Q triples.
LatchEnableSet latch_enables;
- CellTimingArcSetIterator *set_iter = timingArcSetIterator();
- while (set_iter->hasNext()) {
- TimingArcSet *en_to_q = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(this);
+ while (set_iter.hasNext()) {
+ TimingArcSet *en_to_q = set_iter.next();
// Locate potential d->q arcs from reg clk->q arcs.
if (en_to_q->role() == TimingRole::regClkToQ()) {
LibertyPort *en = en_to_q->from();
LibertyPort *q = en_to_q->to();
- CellTimingArcSetIterator *to_iter = timingArcSetToIterator(q);
- while (to_iter->hasNext()) {
- TimingArcSet *d_to_q = to_iter->next();
+ LibertyCellTimingArcSetIterator to_iter(this, NULL, q);
+ while (to_iter.hasNext()) {
+ TimingArcSet *d_to_q = to_iter.next();
// Look for combinational d->q arcs.
TimingRole *d_to_q_role = d_to_q->role();
if ((d_to_q_role == TimingRole::combinational()
@@ -1724,22 +1623,19 @@ LibertyCell::inferLatchRoles(Debug *debug)
|| d_to_q_role == TimingRole::latchDtoQ()) {
LibertyPort *d = d_to_q->from();
// Check for setup check from en -> d.
- CellTimingArcSetIterator *check_iter = timingArcSetIterator(en, d);
- while (check_iter->hasNext()) {
- TimingArcSet *setup_check = check_iter->next();
+ LibertyCellTimingArcSetIterator check_iter(this, en, d);
+ while (check_iter.hasNext()) {
+ TimingArcSet *setup_check = check_iter.next();
if (setup_check->role() == TimingRole::setup()) {
makeLatchEnable(d, en, q, d_to_q, en_to_q, setup_check, debug);
d_to_q->setRole(TimingRole::latchDtoQ());
en_to_q->setRole(TimingRole::latchEnToQ());
}
}
- delete check_iter;
}
}
- delete to_iter;
}
}
- delete set_iter;
}
}
@@ -1869,12 +1765,6 @@ LibertyPort::setDirection(PortDirection *dir)
liberty_cell_->setHasInternalPorts(true);
}
-LibertyPortMemberIterator *
-LibertyPort::libertyMemberIterator() const
-{
- return new LibertyPortMemberIterator(this);
-}
-
LibertyPort *
LibertyPort::findLibertyMember(int index) const
{
@@ -1903,12 +1793,11 @@ LibertyPort::setCapacitance(const TransRiseFall *tr,
{
capacitance_.setValue(tr, min_max, cap);
if (hasMembers()) {
- LibertyPortMemberIterator *member_iter = libertyMemberIterator();
- while (member_iter->hasNext()) {
- LibertyPort *port_bit = member_iter->next();
+ LibertyPortMemberIterator member_iter(this);
+ while (member_iter.hasNext()) {
+ LibertyPort *port_bit = member_iter.next();
port_bit->setCapacitance(tr, min_max, cap);
}
- delete member_iter;
}
}
@@ -1958,15 +1847,14 @@ LibertyPort::setFunction(FuncExpr *func)
{
function_ = func;
if (is_bus_ || is_bundle_) {
- LibertyPortMemberIterator *member_iter = libertyMemberIterator();
+ LibertyPortMemberIterator member_iter(this);
int bit_offset = 0;
- while (member_iter->hasNext()) {
- LibertyPort *port_bit = member_iter->next();
+ while (member_iter.hasNext()) {
+ LibertyPort *port_bit = member_iter.next();
FuncExpr *sub_expr = (func) ? func->bitSubExpr(bit_offset) : NULL;
port_bit->setFunction(sub_expr);
bit_offset++;
}
- delete member_iter;
}
}
@@ -1975,14 +1863,13 @@ LibertyPort::setTristateEnable(FuncExpr *enable)
{
tristate_enable_ = enable;
if (hasMembers()) {
- LibertyPortMemberIterator *member_iter = libertyMemberIterator();
- while (member_iter->hasNext()) {
- LibertyPort *port_bit = member_iter->next();
+ LibertyPortMemberIterator member_iter(this);
+ while (member_iter.hasNext()) {
+ LibertyPort *port_bit = member_iter.next();
FuncExpr *sub_expr =
(enable) ? enable->bitSubExpr(port_bit->busBitIndex()) : NULL;
port_bit->setTristateEnable(sub_expr);
}
- delete member_iter;
}
}
diff --git a/liberty/Liberty.hh b/liberty/Liberty.hh
index 256b92c6..d8cb89a6 100644
--- a/liberty/Liberty.hh
+++ b/liberty/Liberty.hh
@@ -28,7 +28,7 @@
namespace sta {
-class LibertyLibraryCellIterator;
+class LibertyCellIterator;
class LibertyCellPortIterator;
class LibertyCellPortBitIterator;
class LibertyPortMemberIterator;
@@ -41,34 +41,33 @@ class Debug;
class LibertyBuilder;
class LibertyReader;
class OcvDerate;
+class TimingArcAttrs;
+class InternalPowerAttrs;
typedef Set LibrarySet;
typedef Map TableTemplateMap;
-typedef TableTemplateMap::Iterator TableTemplateIterator;
typedef Map BusDclMap;
typedef Map ScaleFactorsMap;
typedef Map WireloadMap;
typedef Map WireloadSelectionMap;
typedef Map OperatingConditionsMap;
-typedef OperatingConditionsMap::Iterator OperatingConditionsIterator;
typedef Map PortToSequentialMap;
typedef Vector TimingArcSetSeq;
-typedef TimingArcSetSeq::ConstIterator CellTimingArcSetIterator;
typedef Set TimingArcSetMap;
+typedef Map LibertyPortPairTimingArcMap;
typedef Vector InternalPowerSeq;
-typedef InternalPowerSeq::Iterator LibertyCellInternalPowerIterator;
typedef Vector LeakagePowerSeq;
-typedef LeakagePowerSeq::Iterator LibertyCellLeakagePowerIterator;
-typedef Map LibertyPortTimingArcSetSeqMap;
+typedef Map LibertyPortTimingArcMap;
typedef Map ScaledCellMap;
typedef Map ScaledPortMap;
typedef Map ModeDefMap;
typedef Map ModeValueMap;
typedef Map LatchEnableMap;
typedef Map OcvDerateMap;
-typedef Map LibertyPortTimingArcSetMap;
+typedef Vector TimingArcAttrsSeq;
+typedef Vector InternalPowerAttrsSeq;
typedef enum {
clock_gate_none,
@@ -132,14 +131,12 @@ public:
LibertyCell *findLibertyCell(const char *name) const;
void findLibertyCellsMatching(PatternMatch *pattern,
LibertyCellSeq *cells);
- LibertyLibraryCellIterator *libertyCellIterator() const;
DelayModelType delayModelType() const { return delay_model_type_; }
void setDelayModelType(DelayModelType type);
void addBusDcl(BusDcl *bus_dcl);
BusDcl *findBusDcl(const char *name) const;
void addTableTemplate(TableTemplate *tbl_template);
TableTemplate *findTableTemplate(const char *name);
- TableTemplateIterator *tableTemplateIterator();
float nominalProcess() { return nominal_process_; }
void setNominalProcess(float process);
float nominalVoltage() const { return nominal_voltage_; }
@@ -254,7 +251,6 @@ public:
void setDefaultWireloadSelection(WireloadSelection *selection);
OperatingConditions *findOperatingConditions(const char *name);
- OperatingConditionsIterator *operatingConditionsIterator();
OperatingConditions *defaultOperatingConditions() const;
void addOperatingConditions(OperatingConditions *op_cond);
void setDefaultOperatingConditions(OperatingConditions *op_cond);
@@ -291,7 +287,7 @@ protected:
Units *units_;
DelayModelType delay_model_type_;
BusDclMap bus_dcls_;
- TableTemplateMap templates_;
+ TableTemplateMap template_map_;
float nominal_process_;
float nominal_voltage_;
float nominal_temperature_;
@@ -340,22 +336,40 @@ protected:
private:
DISALLOW_COPY_AND_ASSIGN(LibertyLibrary);
- friend class LibertyLibraryCellIterator;
+ friend class LibertyCellIterator;
+ friend class TableTemplateIterator;
+ friend class OperatingConditionsIterator;
};
-class LibertyLibraryCellIterator : public Iterator
+class LibertyCellIterator : public Iterator
{
public:
- explicit LibertyLibraryCellIterator(const LibertyLibrary *library);
+ explicit LibertyCellIterator(const LibertyLibrary *library);
bool hasNext();
LibertyCell *next();
private:
- DISALLOW_COPY_AND_ASSIGN(LibertyLibraryCellIterator);
+ DISALLOW_COPY_AND_ASSIGN(LibertyCellIterator);
ConcreteCellMap::ConstIterator iter_;
};
+class TableTemplateIterator : public TableTemplateMap::ConstIterator
+{
+public:
+ TableTemplateIterator(const LibertyLibrary *library) :
+ TableTemplateMap::ConstIterator(library->template_map_) {}
+};
+
+class OperatingConditionsIterator : public OperatingConditionsMap::ConstIterator
+{
+public:
+ OperatingConditionsIterator(const LibertyLibrary *library) :
+ OperatingConditionsMap::ConstIterator(library->operating_conditions_) {}
+};
+
+////////////////////////////////////////////////////////////////
+
class LibertyCell : public ConcreteCell
{
public:
@@ -365,8 +379,6 @@ public:
virtual ~LibertyCell();
const LibertyLibrary *libertyLibrary() const { return liberty_library_; }
LibertyLibrary *libertyLibrary() { return liberty_library_; }
- LibertyCellPortIterator *libertyPortIterator() const;
- LibertyCellPortBitIterator *libertyPortBitIterator() const;
LibertyPort *findLibertyPort(const char *name) const;
void findLibertyPortsMatching(PatternMatch *pattern,
LibertyPortSeq *ports) const;
@@ -395,27 +407,26 @@ public:
bool isClockGate() const;
void setClockGateType(ClockGateType clock_gate_type);
virtual unsigned addTimingArcSet(TimingArcSet *set);
+ void addTimingArcAttrs(TimingArcAttrs *attrs);
virtual void addInternalPower(InternalPower *power);
+ void addInternalPowerAttrs(InternalPowerAttrs *attrs);
virtual void addLeakagePower(LeakagePower *power);
// Call after cell is finished being constructed.
virtual void finish(bool infer_latches,
Report *report,
Debug *debug);
+ // Internal to LibertyCellTimingArcSetIterator.
+ TimingArcSetSeq *timingArcSets(const LibertyPort *from,
+ const LibertyPort *to) const;
size_t timingArcSetCount() const;
// Find a timing arc set equivalent to key.
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
- CellTimingArcSetIterator *timingArcSetIterator() const;
- CellTimingArcSetIterator *timingArcSetIterator(LibertyPort *from,
- LibertyPort *to) const;
- CellTimingArcSetIterator *timingArcSetFromIterator(LibertyPort *from) const;
- CellTimingArcSetIterator *timingArcSetToIterator(LibertyPort *to) const;
bool hasTimingArcs(LibertyPort *port) const;
- LibertyCellInternalPowerIterator *internalPowerIterator();
- LibertyCellLeakagePowerIterator *leakagePowerIterator();
- float leakagePower() const;
+ InternalPowerSeq *internalPowers() const { return internal_powers_; }
+ LeakagePowerSeq *leakagePowers() const { return leakage_powers_; }
+ float leakagePower() const { return leakage_power_; }
bool hasSequentials() const;
- CellSequentialIterator *sequentialIterator() const;
void makeSequential(int size,
bool is_register,
FuncExpr *clk,
@@ -463,7 +474,7 @@ protected:
virtual void addPort(ConcretePort *port);
void setHasInternalPorts(bool has_internal);
void setLibertyLibrary(LibertyLibrary *library);
- void deleteTimingModels();
+ void deleteTimingArcAttrs();
void makeLatchEnables(Report *report,
Debug *debug);
FuncExpr *findLatchEnableFunc(LibertyPort *data,
@@ -478,6 +489,7 @@ protected:
void findDefaultCondArcs();
virtual void translatePresetClrCheckRoles();
virtual void inferLatchRoles(Debug *debug);
+ void deleteInternalPowerAttrs();
LibertyLibrary *liberty_library_;
float area_;
@@ -488,12 +500,15 @@ protected:
bool interface_timing_;
ClockGateType clock_gate_type_;
TimingArcSetSeq *timing_arc_sets_;
+ // Used to find matching arc sets in equivalent cells.
TimingArcSetMap *timing_arc_set_map_;
- LibertyPortTimingArcSetMap *port_timing_arc_set_map_;
- LibertyPortTimingArcSetSeqMap *timing_arc_set_from_map_;
- LibertyPortTimingArcSetSeqMap *timing_arc_set_to_map_;
+ LibertyPortPairTimingArcMap *port_timing_arc_set_map_;
+ LibertyPortTimingArcMap *timing_arc_set_from_map_;
+ LibertyPortTimingArcMap *timing_arc_set_to_map_;
+ TimingArcAttrsSeq timing_arc_attrs_;
bool has_infered_reg_timing_arcs_;
InternalPowerSeq *internal_powers_;
+ InternalPowerAttrsSeq internal_power_attrs_;
LeakagePowerSeq *leakage_powers_;
SequentialSeq *sequentials_;
PortToSequentialMap *port_to_seq_map_;
@@ -522,6 +537,8 @@ private:
friend class LibertyCellPortIterator;
friend class LibertyPort;
friend class LibertyBuilder;
+ friend class LibertyCellTimingArcSetIterator;
+ friend class LibertyCellSequentialIterator;
};
class LibertyCellPortIterator : public Iterator
@@ -551,11 +568,42 @@ private:
ConcreteCellPortBitIterator *iter_;
};
+class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::Iterator
+{
+public:
+ LibertyCellTimingArcSetIterator(const LibertyCell *cell);
+ LibertyCellTimingArcSetIterator(const LibertyCell *cell,
+ const LibertyPort *from,
+ const LibertyPort *to);
+};
+
+class LibertyCellSequentialIterator : public SequentialSeq::ConstIterator
+{
+public:
+ LibertyCellSequentialIterator(const LibertyCell *cell) :
+ SequentialSeq::ConstIterator(cell->sequentials_) {}
+};
+
+class LibertyCellLeakagePowerIterator : public LeakagePowerSeq::Iterator
+{
+public:
+ LibertyCellLeakagePowerIterator(const LibertyCell *cell) :
+ LeakagePowerSeq::Iterator(cell->leakagePowers()) {}
+};
+
+class LibertyCellInternalPowerIterator : public InternalPowerSeq::Iterator
+{
+public:
+ LibertyCellInternalPowerIterator(const LibertyCell *cell) :
+ InternalPowerSeq::Iterator(cell->internalPowers()) {}
+};
+
+////////////////////////////////////////////////////////////////
+
class LibertyPort : public ConcretePort
{
public:
LibertyCell *libertyCell() const { return liberty_cell_; }
- LibertyPortMemberIterator *libertyMemberIterator() const;
LibertyPort *findLibertyMember(int index) const;
LibertyPort *findLibertyBusBit(int index) const;
float capacitance(const TransRiseFall *tr,
diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc
index 0ee13853..3d9d4be8 100644
--- a/liberty/LibertyBuilder.cc
+++ b/liberty/LibertyBuilder.cc
@@ -276,36 +276,28 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell,
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, TransRiseFall::rise(), to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_negative_unate:
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, TransRiseFall::rise(), to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_non_unate:
@@ -320,7 +312,6 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model);
makeTimingArc(arc_set, TransRiseFall::rise(), to_tr, model);
- attrs->setModelRef(to_tr, true);
}
}
if (to_rise) {
@@ -329,7 +320,6 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, TransRiseFall::rise(), to_tr, model);
makeTimingArc(arc_set, TransRiseFall::fall(), to_tr, model);
- attrs->setModelRef(to_tr, true);
}
}
break;
@@ -355,7 +345,6 @@ LibertyBuilder::makeLatchDtoQArcs(LibertyCell *cell,
TransRiseFall *from_tr = (sense == timing_sense_negative_unate) ?
to_tr->opposite() : to_tr;
makeTimingArc(arc_set, from_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
}
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
@@ -363,7 +352,6 @@ LibertyBuilder::makeLatchDtoQArcs(LibertyCell *cell,
TransRiseFall *from_tr = (sense == timing_sense_negative_unate) ?
to_tr->opposite() : to_tr;
makeTimingArc(arc_set, from_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
}
return arc_set;
}
@@ -420,16 +408,12 @@ LibertyBuilder::makeFromTransitionArcs(LibertyCell *cell,
TransRiseFall *to_tr;
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, from_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, from_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
- }
return arc_set;
}
@@ -450,17 +434,14 @@ LibertyBuilder::makePresetClrArcs(LibertyCell *cell,
switch (attrs->timingSense()) {
case timing_sense_positive_unate:
makeTimingArc(arc_set, to_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
break;
case timing_sense_negative_unate:
makeTimingArc(arc_set, opp_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
break;
case timing_sense_non_unate:
case timing_sense_unknown:
makeTimingArc(arc_set, to_tr, to_tr, model);
makeTimingArc(arc_set, opp_tr, to_tr, model);
- attrs->setModelRef(to_tr, true);
break;
case timing_sense_none:
break;
@@ -494,36 +475,28 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell,
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::rise(), Transition::trZ1(), model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::rise(), Transition::trZ0(), model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_negative_unate:
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::fall(), Transition::trZ1(), model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::fall(), Transition::trZ0(), model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_non_unate:
@@ -534,7 +507,6 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, Transition::rise(), Transition::trZ1(), model);
makeTimingArc(arc_set, Transition::fall(), Transition::trZ1(), model);
- attrs->setModelRef(to_tr, true);
}
}
if (to_fall) {
@@ -543,7 +515,6 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, Transition::rise(), Transition::trZ0(), model);
makeTimingArc(arc_set, Transition::fall(), Transition::trZ0(), model);
- attrs->setModelRef(to_tr, true);
}
}
break;
@@ -577,36 +548,28 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell,
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::rise(), Transition::tr0Z(), model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::rise(), Transition::tr1Z(), model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_negative_unate:
if (to_rise) {
to_tr = TransRiseFall::rise();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::fall(), Transition::tr0Z(), model);
- attrs->setModelRef(to_tr, true);
- }
}
if (to_fall) {
to_tr = TransRiseFall::fall();
model = attrs->model(to_tr);
- if (model) {
+ if (model)
makeTimingArc(arc_set, Transition::fall(), Transition::tr1Z(), model);
- attrs->setModelRef(to_tr, true);
- }
}
break;
case timing_sense_non_unate:
@@ -617,7 +580,6 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, Transition::fall(), Transition::tr0Z(), model);
makeTimingArc(arc_set, Transition::rise(), Transition::tr0Z(), model);
- attrs->setModelRef(to_tr, true);
}
}
if (to_fall) {
@@ -626,7 +588,6 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell,
if (model) {
makeTimingArc(arc_set, Transition::fall(), Transition::tr1Z(), model);
makeTimingArc(arc_set, Transition::rise(), Transition::tr1Z(), model);
- attrs->setModelRef(to_tr, true);
}
}
break;
diff --git a/liberty/LibertyClass.hh b/liberty/LibertyClass.hh
index 6f1978d5..babfebe1 100644
--- a/liberty/LibertyClass.hh
+++ b/liberty/LibertyClass.hh
@@ -55,14 +55,14 @@ class TimingRole;
class Transition;
class TransRiseFall;
class TransRiseFallBoth;
+class LibertyCellSequentialIterator;
typedef Vector LibertyCellSeq;
typedef Vector SequentialSeq;
-typedef SequentialSeq::ConstIterator CellSequentialIterator;
typedef Map LibertyCellEquivMap;
typedef Vector LibertyPortSeq;
typedef Set LibertyPortSet;
-typedef std::pair LibertyPortPair;
+typedef std::pair LibertyPortPair;
typedef Set LibertyCellSet;
typedef Vector FloatSeq;
typedef Vector FloatTable;
diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc
index d0ff2762..05dfed82 100644
--- a/liberty/LibertyReader.cc
+++ b/liberty/LibertyReader.cc
@@ -131,6 +131,7 @@ LibertyReader::readLibertyFile(const char *filename,
mode_def_ = NULL;
mode_value_ = NULL;
ocv_derate_ = NULL;
+ have_resistance_unit_ = false;
TransRiseFallIterator tr_iter;
while (tr_iter.hasNext()) {
@@ -169,6 +170,7 @@ LibertyReader::defineVisitors()
defineAttrVisitor("time_unit", &LibertyReader::visitTimeUnit);
defineAttrVisitor("pulling_resistance_unit",
&LibertyReader::visitPullingResistanceUnit);
+ defineAttrVisitor("resistance_unit", &LibertyReader::visitResistanceUnit);
defineAttrVisitor("capacitive_load_unit",
&LibertyReader::visitCapacitiveLoadUnit);
defineAttrVisitor("voltage_unit", &LibertyReader::visitVoltageUnit);
@@ -580,6 +582,12 @@ LibertyReader::endLibrary(LibertyGroup *group)
void
LibertyReader::endLibraryAttrs(LibertyGroup *group)
{
+ // Default resistance_unit to pulling_resistance_unit.
+ if (!have_resistance_unit_) {
+ Units *units = library_->units();
+ units->resistanceUnit()->copy(units->pullingResistanceUnit());
+ }
+
// These attributes reference named groups in the library so
// wait until the end of the library to resolve them.
if (default_wireload_) {
@@ -640,7 +648,17 @@ void
LibertyReader::visitPullingResistanceUnit(LibertyAttr *attr)
{
if (library_)
+ parseUnits(attr, "ohm", res_scale_,
+ library_->units()->pullingResistanceUnit());
+}
+
+void
+LibertyReader::visitResistanceUnit(LibertyAttr *attr)
+{
+ if (library_) {
parseUnits(attr, "ohm", res_scale_, library_->units()->resistanceUnit());
+ have_resistance_unit_ = true;
+ }
}
void
@@ -700,8 +718,8 @@ LibertyReader::parseUnits(LibertyAttr *attr,
}
float scale_mult = 1.0F;
- if (stringEq(s + 1, unit_suffix)) {
- char scale_char = *s;
+ if (*s && stringEqual(s + 1, unit_suffix)) {
+ char scale_char = tolower(*s);
if (scale_char == 'k')
scale_mult = 1E+3F;
else if (scale_char == 'm')
@@ -717,7 +735,7 @@ LibertyReader::parseUnits(LibertyAttr *attr,
else
libWarn(attr, "unknown unit scale %c.\n", scale_char);
}
- else if (!stringEq(s, unit_suffix))
+ else if (!stringEqual(s, unit_suffix))
libWarn(attr, "unknown unit suffix %s.\n", s + 1);
scale_var = scale_mult * mult;
@@ -738,9 +756,9 @@ LibertyReader::visitCapacitiveLoadUnit(LibertyAttr *attr)
value = value_iter.next();
if (value->isString()) {
const char *suffix = value->stringValue();
- if (stringEq(suffix, "ff"))
+ if (stringEqual(suffix, "ff"))
cap_scale_ = scale * 1E-15F;
- else if (stringEq(suffix, "pf"))
+ else if (stringEqual(suffix, "pf"))
cap_scale_ = scale * 1E-12F;
else
libWarn(attr, "capacitive_load_units are not ff or pf.\n");
@@ -1814,15 +1832,7 @@ LibertyReader::makeTimingArcs(PortGroup *port_group)
LibertyPort *port = port_iter.next();
makeTimingArcs(port, timing);
}
-
- // Delete unreferenced models to prevent memory leak.
- TransRiseFallIterator tr_iter;
- while (tr_iter.hasNext()) {
- TransRiseFall *tr = tr_iter.next();
- TimingModel *model = timing->model(tr);
- if (model && !timing->modelRef(tr))
- delete model;
- }
+ cell_->addTimingArcAttrs(timing);
}
}
@@ -1837,6 +1847,7 @@ LibertyReader::makeInternalPowers(PortGroup *port_group)
LibertyPort *port = port_iter.next();
makeInternalPowers(port, power_group);
}
+ cell_->addInternalPowerAttrs(power_group);
}
}
@@ -2205,27 +2216,25 @@ LibertyReader::makeTimingArcs(const char *from_port_name,
// one -> bus
if (from_port_iter.hasNext()) {
LibertyPort *from_port = from_port_iter.next();
- LibertyPortMemberIterator *bit_iter = to_port->libertyMemberIterator();
- while (bit_iter->hasNext()) {
- LibertyPort *to_port_bit = bit_iter->next();
+ LibertyPortMemberIterator bit_iter(to_port);
+ while (bit_iter.hasNext()) {
+ LibertyPort *to_port_bit = bit_iter.next();
builder_->makeTimingArcs(cell_, from_port, to_port_bit,
related_out_port, timing);
}
- delete bit_iter;
}
}
else {
// bus -> bus
if (timing->isOneToOne()) {
if (static_cast(from_port_iter.size()) == to_port->size()) {
- LibertyPortMemberIterator *to_iter = to_port->libertyMemberIterator();
- while (from_port_iter.hasNext() && to_iter->hasNext()) {
+ LibertyPortMemberIterator to_iter(to_port);
+ while (from_port_iter.hasNext() && to_iter.hasNext()) {
LibertyPort *from_port_bit = from_port_iter.next();
- LibertyPort *to_port_bit = to_iter->next();
+ LibertyPort *to_port_bit = to_iter.next();
builder_->makeTimingArcs(cell_, from_port_bit, to_port_bit,
related_out_port, timing);
}
- delete to_iter;
}
else
libWarn(timing->line(),
@@ -2236,13 +2245,12 @@ LibertyReader::makeTimingArcs(const char *from_port_name,
else {
while (from_port_iter.hasNext()) {
LibertyPort *from_port_bit = from_port_iter.next();
- LibertyPortMemberIterator *to_iter = to_port->libertyMemberIterator();
- while (to_iter->hasNext()) {
- LibertyPort *to_port_bit = to_iter->next();
+ LibertyPortMemberIterator to_iter(to_port);
+ while (to_iter.hasNext()) {
+ LibertyPort *to_port_bit = to_iter.next();
builder_->makeTimingArcs(cell_, from_port_bit, to_port_bit,
related_out_port, timing);
}
- delete to_iter;
}
}
}
@@ -2270,12 +2278,11 @@ LibertyReader::makeInternalPowers(LibertyPort *port,
}
else {
if (port->hasMembers()) {
- LibertyPortMemberIterator *bit_iter = port->libertyMemberIterator();
- while (bit_iter->hasNext()) {
- LibertyPort *port_bit = bit_iter->next();
+ LibertyPortMemberIterator bit_iter(port);
+ while (bit_iter.hasNext()) {
+ LibertyPort *port_bit = bit_iter.next();
builder_->makeInternalPower(cell_, port_bit, NULL, power_group);
}
- delete bit_iter;
}
else
builder_->makeInternalPower(cell_, port, NULL, power_group);
@@ -2306,25 +2313,23 @@ LibertyReader::makeInternalPowers(LibertyPort *port,
// one -> bus
if (related_port_iter.hasNext()) {
LibertyPort *related_port = related_port_iter.next();
- LibertyPortMemberIterator *bit_iter = port->libertyMemberIterator();
- while (bit_iter->hasNext()) {
- LibertyPort *port_bit = bit_iter->next();
+ LibertyPortMemberIterator bit_iter(port);
+ while (bit_iter.hasNext()) {
+ LibertyPort *port_bit = bit_iter.next();
builder_->makeInternalPower(cell_, port_bit, related_port, power_group);
}
- delete bit_iter;
}
}
else {
// bus -> bus
if (power_group->isOneToOne()) {
if (static_cast(related_port_iter.size()) == port->size()) {
- LibertyPortMemberIterator *to_iter = port->libertyMemberIterator();
- while (related_port_iter.hasNext() && to_iter->hasNext()) {
+ LibertyPortMemberIterator to_iter(port);
+ while (related_port_iter.hasNext() && to_iter.hasNext()) {
LibertyPort *related_port_bit = related_port_iter.next();
- LibertyPort *port_bit = to_iter->next();
+ LibertyPort *port_bit = to_iter.next();
builder_->makeInternalPower(cell_, port_bit, related_port_bit, power_group);
}
- delete to_iter;
}
else
libWarn(power_group->line(),
@@ -2335,12 +2340,11 @@ LibertyReader::makeInternalPowers(LibertyPort *port,
else {
while (related_port_iter.hasNext()) {
LibertyPort *related_port_bit = related_port_iter.next();
- LibertyPortMemberIterator *to_iter = port->libertyMemberIterator();
- while (to_iter->hasNext()) {
- LibertyPort *port_bit = to_iter->next();
+ LibertyPortMemberIterator to_iter(port);
+ while (to_iter.hasNext()) {
+ LibertyPort *port_bit = to_iter.next();
builder_->makeInternalPower(cell_, port_bit, related_port_bit, power_group);
}
- delete to_iter;
}
}
}
@@ -2562,12 +2566,11 @@ LibertyReader::endPorts(LibertyGroup *)
if (in_bus_ || in_bundle_) {
// Do not clobber member port capacitances by setting the capacitance
// on a bus or bundle.
- LibertyPortMemberIterator *member_iter = port->libertyMemberIterator();
- while (member_iter->hasNext()) {
- LibertyPort *member = member_iter->next();
+ LibertyPortMemberIterator member_iter(port);
+ while (member_iter.hasNext()) {
+ LibertyPort *member = member_iter.next();
setPortCapDefault(member);
}
- delete member_iter;
}
else
setPortCapDefault(port);
@@ -4447,7 +4450,7 @@ LibertyReader::visitRelatedPowerPin(LibertyAttr *attr)
LibertyPortSeq::Iterator port_iter(ports_);
while (port_iter.hasNext()) {
LibertyPort *port = port_iter.next();
- port->setRelatedPowerPin(stringCopy(related_power_pin));
+ port->setRelatedPowerPin(related_power_pin);
}
}
}
@@ -4699,8 +4702,8 @@ PortGroup::PortGroup(LibertyPortSeq *ports,
PortGroup::~PortGroup()
{
- timings_.deleteContents();
- internal_power_groups_.deleteContents();
+ // TimingGroups and IntternalPower are NOT deleted because ownership is transfered
+ // to LibertyCell::timing_arc_attrs_ by LibertyReader::makeTimingArcs.
delete ports_;
}
@@ -4846,6 +4849,8 @@ TimingGroup::TimingGroup(int line) :
TimingGroup::~TimingGroup()
{
+ // TimingAttrs contents are not deleted because they are referenced
+ // by TimingArcSets.
if (related_output_port_name_)
stringDelete(related_output_port_name_);
}
@@ -5000,7 +5005,7 @@ PortNameBitIterator::init(const char *port_name)
LibertyPort *port = visitor_->findPort(cell_, port_name);
if (port) {
if (port->isBus())
- bit_iterator_ = port->libertyMemberIterator();
+ bit_iterator_ = new LibertyPortMemberIterator(port);
else
port_ = port;
size_ = port->size();
diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh
index 2a59e29b..9ec1d655 100644
--- a/liberty/LibertyReaderPvt.hh
+++ b/liberty/LibertyReaderPvt.hh
@@ -78,6 +78,7 @@ public:
virtual void visitAttr(LibertyAttr *attr);
virtual void visitTimeUnit(LibertyAttr *attr);
virtual void visitCapacitiveLoadUnit(LibertyAttr *attr);
+ virtual void visitResistanceUnit(LibertyAttr *attr);
virtual void visitPullingResistanceUnit(LibertyAttr *attr);
virtual void visitVoltageUnit(LibertyAttr *attr);
virtual void visitCurrentUnit(LibertyAttr *attr);
@@ -546,6 +547,7 @@ protected:
float curr_scale_;
float power_scale_;
float energy_scale_;
+ bool have_resistance_unit_;
private:
DISALLOW_COPY_AND_ASSIGN(LibertyReader);
diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc
index a16deb7c..1b68b038 100644
--- a/liberty/TableModel.cc
+++ b/liberty/TableModel.cc
@@ -25,7 +25,6 @@ namespace sta {
static void
reportPvt(const LibertyLibrary *library,
- const LibertyCell *cell,
const Pvt *pvt,
int digits,
string *result);
@@ -124,7 +123,7 @@ GateTableModel::reportGateDelay(const LibertyCell *cell,
string *result) const
{
const LibertyLibrary *library = cell->libertyLibrary();
- reportPvt(library, cell, pvt, digits, result);
+ reportPvt(library, pvt, digits, result);
reportTableLookup("Delay", library, cell, pvt, delay_model_, in_slew,
load_cap, related_out_cap, digits, result);
if (delay_sigma_models_[EarlyLate::earlyIndex()])
@@ -386,7 +385,7 @@ CheckTableModel::reportCheckDelay(const LibertyCell *cell,
findAxisValues(from_slew, to_slew, related_out_cap,
axis_value1, axis_value2, axis_value3);
const LibertyLibrary *library = cell->libertyLibrary();
- reportPvt(library, cell, pvt, digits, result);
+ reportPvt(library, pvt, digits, result);
model_->reportValue("Check", library, cell, pvt,
axis_value1, from_slew_annotation, axis_value2,
axis_value3, digits, result);
@@ -586,7 +585,6 @@ TableModel::reportValue(const char *result_name,
static void
reportPvt(const LibertyLibrary *library,
- const LibertyCell *cell,
const Pvt *pvt,
int digits,
string *result)
diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc
index 5a07fa7f..df88373a 100644
--- a/liberty/TimingArc.cc
+++ b/liberty/TimingArc.cc
@@ -18,6 +18,7 @@
#include "FuncExpr.hh"
#include "TimingRole.hh"
#include "Liberty.hh"
+#include "TimingModel.hh"
#include "TimingArc.hh"
namespace sta {
@@ -41,18 +42,29 @@ TimingArcAttrs::TimingArcAttrs() :
mode_name_(NULL),
mode_value_(NULL),
ocv_arc_depth_(0.0),
- models_{NULL, NULL},
- model_refs_{false, false}
+ models_{NULL, NULL}
{
}
+// Destructor does NOT delete contents because it is a component
+// of TimingGroup (that is deleted after building the LibertyCell)
+// and (potentially) multiple TimingArcSets.
TimingArcAttrs::~TimingArcAttrs()
{
+}
+
+void
+TimingArcAttrs::deleteContents()
+{
+ if (cond_)
+ cond_->deleteSubexprs();
stringDelete(sdf_cond_);
stringDelete(sdf_cond_start_);
stringDelete(sdf_cond_end_);
stringDelete(mode_name_);
stringDelete(mode_value_);
+ delete models_[0];
+ delete models_[1];
}
void
@@ -115,19 +127,6 @@ TimingArcAttrs::setModel(TransRiseFall *tr,
models_[tr->index()] = model;
}
-bool
-TimingArcAttrs::modelRef(TransRiseFall *tr) const
-{
- return model_refs_[tr->index()];
-}
-
-void
-TimingArcAttrs::setModelRef(TransRiseFall *tr,
- bool ref)
-{
- model_refs_[tr->index()] = ref;
-}
-
void
TimingArcAttrs::setOcvArcDepth(float depth)
{
@@ -150,51 +149,36 @@ TimingArcSet::TimingArcSet(LibertyCell *cell,
role_(role),
cond_(attrs->cond()),
is_cond_default_(false),
- sdf_cond_start_(NULL),
- sdf_cond_end_(NULL),
- mode_name_(stringCopy(attrs->modeName())),
- mode_value_(stringCopy(attrs->modeValue())),
+ sdf_cond_start_(attrs->sdfCondStart()),
+ sdf_cond_end_(attrs->sdfCondEnd()),
+ mode_name_(attrs->modeName()),
+ mode_value_(attrs->modeValue()),
ocv_arc_depth_(attrs->ocvArcDepth()),
index_(0),
is_disabled_constraint_(false)
{
const char *sdf_cond = attrs->sdfCond();
- const char *sdf_cond_start = attrs->sdfCondStart();
- const char *sdf_cond_end = attrs->sdfCondEnd();
if (sdf_cond)
- sdf_cond_start = sdf_cond_end = sdf_cond;
- if (sdf_cond_start)
- sdf_cond_start_ = stringCopy(sdf_cond_start);
- if (sdf_cond_end)
- sdf_cond_end_ = stringCopy(sdf_cond_end);
+ sdf_cond_start_ = sdf_cond_end_ = sdf_cond;
init(cell);
}
-TimingArcSet::TimingArcSet(LibertyCell *cell,
- LibertyPort *from,
- LibertyPort *to,
- LibertyPort *related_out,
- TimingRole *role,
- FuncExpr *cond,
- const char *sdf_cond_start,
- const char *sdf_cond_end,
- const char *mode_name,
- const char *mode_value) :
- from_(from),
- to_(to),
- related_out_(related_out),
+TimingArcSet::TimingArcSet(TimingRole *role) :
+ from_(NULL),
+ to_(NULL),
+ related_out_(NULL),
role_(role),
- cond_(cond),
+ cond_(NULL),
is_cond_default_(false),
- sdf_cond_start_(stringCopy(sdf_cond_start)),
- sdf_cond_end_(stringCopy(sdf_cond_end)),
- mode_name_(stringCopy(mode_name)),
- mode_value_(stringCopy(mode_value)),
+ sdf_cond_start_(NULL),
+ sdf_cond_end_(NULL),
+ mode_name_(NULL),
+ mode_value_(NULL),
index_(0),
is_disabled_constraint_(false)
{
- init(cell);
+ init(NULL);
}
void
@@ -283,12 +267,6 @@ TimingArcSet::setIsCondDefault(bool is_default)
is_cond_default_ = is_default;
}
-TimingArcSetArcIterator *
-TimingArcSet::timingArcIterator() const
-{
- return new TimingArcSetArcIterator(this);
-}
-
void
TimingArcSet::arcsFrom(const TransRiseFall *from_tr,
// Return values.
@@ -373,21 +351,15 @@ static bool
timingArcsEquiv(const TimingArcSet *set1,
const TimingArcSet *set2)
{
- TimingArcSetArcIterator *arc_iter1 = set1->timingArcIterator();
- TimingArcSetArcIterator *arc_iter2 = set2->timingArcIterator();
- while (arc_iter1->hasNext() && arc_iter2->hasNext()) {
- TimingArc *arc1 = arc_iter1->next();
- TimingArc *arc2 = arc_iter2->next();
- if (!TimingArc::equiv(arc1, arc2)) {
- delete arc_iter1;
- delete arc_iter2;
+ TimingArcSetArcIterator arc_iter1(set1);
+ TimingArcSetArcIterator arc_iter2(set2);
+ while (arc_iter1.hasNext() && arc_iter2.hasNext()) {
+ TimingArc *arc1 = arc_iter1.next();
+ TimingArc *arc2 = arc_iter2.next();
+ if (!TimingArc::equiv(arc1, arc2))
return false;
- }
}
- bool eq = !arc_iter1->hasNext() && !arc_iter2->hasNext();
- delete arc_iter1;
- delete arc_iter2;
- return eq;
+ return !arc_iter1.hasNext() && !arc_iter2.hasNext();
}
bool
@@ -461,42 +433,27 @@ static bool
timingArcsLess(const TimingArcSet *set1,
const TimingArcSet *set2)
{
- TimingArcSetArcIterator *arc_iter1 = set1->timingArcIterator();
- TimingArcSetArcIterator *arc_iter2 = set2->timingArcIterator();
- while (arc_iter1->hasNext() && arc_iter2->hasNext()) {
- TimingArc *arc1 = arc_iter1->next();
- TimingArc *arc2 = arc_iter2->next();
+ TimingArcSetArcIterator arc_iter1(set1);
+ TimingArcSetArcIterator arc_iter2(set2);
+ while (arc_iter1.hasNext() && arc_iter2.hasNext()) {
+ TimingArc *arc1 = arc_iter1.next();
+ TimingArc *arc2 = arc_iter2.next();
int from_index1 = arc1->fromTrans()->index();
int from_index2 = arc2->fromTrans()->index();
- if (from_index1 < from_index2) {
- delete arc_iter1;
- delete arc_iter2;
+ if (from_index1 < from_index2)
return true;
- }
- if (from_index1 > from_index2) {
- delete arc_iter1;
- delete arc_iter2;
+ if (from_index1 > from_index2)
return false;
- }
// from_index1 == from_index2
int to_index1 = arc1->toTrans()->index();
int to_index2 = arc2->toTrans()->index();
- if (to_index1 < to_index2) {
- delete arc_iter1;
- delete arc_iter2;
+ if (to_index1 < to_index2)
return true;
- }
- if (to_index1 > to_index2) {
- delete arc_iter1;
- delete arc_iter2;
+ if (to_index1 > to_index2)
return false;
- }
// Continue if arc transitions are equal.
}
- bool less = !arc_iter1->hasNext() && arc_iter2->hasNext();
- delete arc_iter1;
- delete arc_iter2;
- return less;
+ return !arc_iter1.hasNext() && arc_iter2.hasNext();
}
////////////////////////////////////////////////////////////////
@@ -510,9 +467,7 @@ TimingArcSet::wireArcIndex(const TransRiseFall *tr)
void
TimingArcSet::init()
{
- wire_timing_arc_set_ = new TimingArcSet(NULL,NULL,NULL,NULL,
- TimingRole::wire(),
- NULL, NULL, NULL, NULL, NULL);
+ wire_timing_arc_set_ = new TimingArcSet(TimingRole::wire());
new TimingArc(wire_timing_arc_set_, Transition::rise(),
Transition::rise(), NULL);
new TimingArc(wire_timing_arc_set_, Transition::fall(),
diff --git a/liberty/TimingArc.hh b/liberty/TimingArc.hh
index 1519495d..ff432210 100644
--- a/liberty/TimingArc.hh
+++ b/liberty/TimingArc.hh
@@ -94,6 +94,7 @@ class TimingArcAttrs
public:
TimingArcAttrs();
virtual ~TimingArcAttrs();
+ void deleteContents();
TimingType timingType() const { return timing_type_; }
void setTimingType(TimingType type);
TimingSense timingSense() const { return timing_sense_; }
@@ -113,9 +114,6 @@ public:
TimingModel *model(TransRiseFall *tr) const;
void setModel(TransRiseFall *tr,
TimingModel *model);
- bool modelRef(TransRiseFall *tr) const;
- void setModelRef(TransRiseFall *tr,
- bool ref);
float ocvArcDepth() const { return ocv_arc_depth_; }
void setOcvArcDepth(float depth);
@@ -130,7 +128,6 @@ protected:
const char *mode_value_;
float ocv_arc_depth_;
TimingModel *models_[TransRiseFall::index_count];
- bool model_refs_[TransRiseFall::index_count];
private:
DISALLOW_COPY_AND_ASSIGN(TimingArcAttrs);
@@ -150,16 +147,6 @@ public:
LibertyPort *related_out,
TimingRole *role,
TimingArcAttrs *attrs);
- TimingArcSet(LibertyCell *cell,
- LibertyPort *from,
- LibertyPort *to,
- LibertyPort *related_out,
- TimingRole *role,
- FuncExpr *cond,
- const char *sdf_cond_start,
- const char *sdf_cond_end,
- const char *mode_name,
- const char *mode_value);
virtual ~TimingArcSet();
LibertyCell *libertyCell() const;
LibertyPort *from() const { return from_; }
@@ -170,7 +157,6 @@ public:
// Rise/fall if the arc set is rising_edge or falling_edge.
TransRiseFall *isRisingFallingEdge() const;
size_t arcCount() const { return arcs_.size(); }
- TimingArcSetArcIterator *timingArcIterator() const;
TimingArcSeq &arcs() { return arcs_; }
// Return 1 or 2 arcs matching from transition.
void arcsFrom(const TransRiseFall *from_tr,
@@ -217,6 +203,7 @@ public:
protected:
void init(LibertyCell *cell);
+ TimingArcSet(TimingRole *role);
LibertyPort *from_;
LibertyPort *to_;
diff --git a/liberty/Units.hh b/liberty/Units.hh
index 2d43d60f..1320b35f 100644
--- a/liberty/Units.hh
+++ b/liberty/Units.hh
@@ -66,6 +66,8 @@ public:
const Unit *voltageUnit() const { return &voltage_unit_; }
Unit *resistanceUnit() { return &resistance_unit_; }
const Unit *resistanceUnit() const { return &resistance_unit_; }
+ Unit *pullingResistanceUnit() { return &pulling_resistance_unit_; }
+ const Unit *pullingResistanceUnit() const {return &pulling_resistance_unit_;}
Unit *currentUnit() { return ¤t_unit_; }
const Unit *currentUnit() const { return ¤t_unit_; }
Unit *powerUnit() { return &power_unit_; }
@@ -82,6 +84,7 @@ private:
Unit capacitance_unit_;
Unit voltage_unit_;
Unit resistance_unit_;
+ Unit pulling_resistance_unit_;
Unit current_unit_;
Unit power_unit_;
Unit distance_unit_;
diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc
index a625febb..93cbc370 100644
--- a/sdc/Sdc.cc
+++ b/sdc/Sdc.cc
@@ -401,14 +401,13 @@ Sdc::removeLibertyAnnotations()
LibertyPortPairSet::Iterator from_to_iter(disable->fromTo());
while (from_to_iter.hasNext()) {
LibertyPortPair *pair = from_to_iter.next();
- LibertyPort *from = pair->first;
- LibertyPort *to = pair->second;
- CellTimingArcSetIterator *arc_iter = cell->timingArcSetIterator(from, to);
- while (arc_iter->hasNext()) {
- TimingArcSet *arc_set = arc_iter->next();
+ const LibertyPort *from = pair->first;
+ const LibertyPort *to = pair->second;
+ LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
+ while (arc_iter.hasNext()) {
+ TimingArcSet *arc_set = arc_iter.next();
arc_set->setIsDisabledConstraint(false);
}
- delete arc_iter;
}
}
@@ -3704,12 +3703,11 @@ Sdc::disable(LibertyCell *cell,
}
if (from && to) {
disabled_cell->setDisabledFromTo(from, to);
- CellTimingArcSetIterator *arc_iter = cell->timingArcSetIterator(from, to);
- while (arc_iter->hasNext()) {
- TimingArcSet *arc_set = arc_iter->next();
+ LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
+ while (arc_iter.hasNext()) {
+ TimingArcSet *arc_set = arc_iter.next();
arc_set->setIsDisabledConstraint(true);
}
- delete arc_iter;
}
else if (from) {
disabled_cell->setDisabledFrom(from);
@@ -3734,12 +3732,11 @@ Sdc::removeDisable(LibertyCell *cell,
if (disabled_cell) {
if (from && to) {
disabled_cell->removeDisabledFromTo(from, to);
- CellTimingArcSetIterator *arc_iter = cell->timingArcSetIterator(from, to);
- while (arc_iter->hasNext()) {
- TimingArcSet *arc_set = arc_iter->next();
+ LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
+ while (arc_iter.hasNext()) {
+ TimingArcSet *arc_set = arc_iter.next();
arc_set->setIsDisabledConstraint(false);
}
- delete arc_iter;
}
else if (from) {
disabled_cell->removeDisabledFrom(from);
@@ -4212,16 +4209,13 @@ Sdc::exceptionToInvalid(const Pin *pin)
LibertyPort *port = network_->libertyPort(pin);
if (port) {
LibertyCell *cell = port->libertyCell();
- CellTimingArcSetIterator *set_iter = cell->timingArcSetToIterator(port);
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, NULL, port);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
TimingRole *role = set->role();
- if (role->genericRole() == TimingRole::regClkToQ()) {
- delete set_iter;
+ if (role->genericRole() == TimingRole::regClkToQ())
return true;
- }
}
- delete set_iter;
}
return false;
}
@@ -4381,15 +4375,12 @@ Sdc::hasLibertyChecks(const Pin *pin)
if (cell) {
LibertyPort *port = network_->libertyPort(pin);
if (port) {
- CellTimingArcSetIterator *timing_iter=cell->timingArcSetToIterator(port);
- while (timing_iter->hasNext()) {
- TimingArcSet *arc_set = timing_iter->next();
- if (arc_set->role()->isTimingCheck()) {
- delete timing_iter;
+ LibertyCellTimingArcSetIterator timing_iter(cell, NULL, port);
+ while (timing_iter.hasNext()) {
+ TimingArcSet *arc_set = timing_iter.next();
+ if (arc_set->role()->isTimingCheck())
return true;
- }
}
- delete timing_iter;
}
}
return false;
@@ -6463,8 +6454,8 @@ Sdc::setEdgeDisabledInstPorts(DisabledPorts *disabled_port,
LibertyPortPairSet::Iterator from_to_iter(disabled_port->fromTo());
while (from_to_iter.hasNext()) {
LibertyPortPair *pair = from_to_iter.next();
- LibertyPort *from_port = pair->first;
- LibertyPort *to_port = pair->second;
+ const LibertyPort *from_port = pair->first;
+ const LibertyPort *to_port = pair->second;
Pin *from_pin = network_->findPin(inst, from_port);
Pin *to_pin = network_->findPin(inst, to_port);
if (from_pin && network_->direction(from_pin)->isAnyInput()
diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc
index 5877bbdc..b4894474 100644
--- a/sdc/WriteSdc.cc
+++ b/sdc/WriteSdc.cc
@@ -1059,8 +1059,8 @@ WriteSdc::writeDisabledCells() const
LibertyPortPairSeq::Iterator pair_iter(pairs);
while (pair_iter.hasNext()) {
LibertyPortPair *from_to = pair_iter.next();
- LibertyPort *from = from_to->first;
- LibertyPort *to = from_to->second;
+ const LibertyPort *from = from_to->first;
+ const LibertyPort *to = from_to->second;
fprintf(stream_, "set_disable_timing -from {%s} -to {%s} ",
from->name(),
to->name());
@@ -1151,8 +1151,8 @@ WriteSdc::writeDisabledInstances() const
LibertyPortPairSeq::Iterator pair_iter(pairs);
while (pair_iter.hasNext()) {
LibertyPortPair *from_to = pair_iter.next();
- LibertyPort *from_port = from_to->first;
- LibertyPort *to_port = from_to->second;
+ const LibertyPort *from_port = from_to->first;
+ const LibertyPort *to_port = from_to->second;
fprintf(stream_, "set_disable_timing -from {%s} -to {%s} ",
from_port->name(),
to_port->name());
diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc
index 161865ef..5a8b1f6c 100644
--- a/sdf/SdfReader.cc
+++ b/sdf/SdfReader.cc
@@ -295,9 +295,9 @@ SdfReader::setEdgeDelays(Edge *edge,
if (triple_count == 1
|| triple_count == 2) {
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
size_t triple_index;
if (triple_count == 1)
triple_index = 0;
@@ -306,7 +306,6 @@ SdfReader::setEdgeDelays(Edge *edge,
SdfTriple *triple = (*triples)[triple_index];
setEdgeArcDelays(edge, arc, triple);
}
- delete arc_iter;
}
else if (triple_count == 0)
sdfError("%s with no triples.\n", sdf_cmd);
@@ -404,9 +403,9 @@ SdfReader::iopath(SdfPortSpec *from_edge,
// condelse matches the default (unconditional) arc.
|| (condelse && lib_cond == NULL))) {
matched = true;
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
if ((from_edge->transition() == Transition::riseFall())
|| (arc->fromTrans() == from_edge->transition())) {
size_t triple_index = arc->toTrans()->sdfTripleIndex();
@@ -425,7 +424,6 @@ SdfReader::iopath(SdfPortSpec *from_edge,
}
}
}
- delete arc_iter;
}
}
if (!matched)
@@ -551,9 +549,9 @@ SdfReader::annotateCheckEdges(Pin *data_pin,
&& edge_role->genericRole() == sdf_role->genericRole()))
&& cond_matches) {
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
if (((data_edge->transition() == Transition::riseFall())
|| (arc->toTrans() == data_edge->transition()))
&& ((clk_edge->transition() == Transition::riseFall())
@@ -561,7 +559,6 @@ SdfReader::annotateCheckEdges(Pin *data_pin,
setEdgeArcDelays(edge, arc, triple);
}
}
- delete arc_iter;
matched = true;
}
}
diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc
index f6954fdd..26481497 100644
--- a/sdf/SdfWriter.cc
+++ b/sdf/SdfWriter.cc
@@ -414,9 +414,9 @@ SdfWriter::writeArcDelays(Edge *edge)
{
RiseFallMinMax delays;
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
TransRiseFall *tr = arc->toTrans()->asRiseFall();
ArcDelay min_delay = graph_->arcDelay(edge, arc, arc_delay_min_index_);
delays.setValue(tr, MinMax::min(), delayAsFloat(min_delay));
@@ -424,7 +424,6 @@ SdfWriter::writeArcDelays(Edge *edge)
ArcDelay max_delay = graph_->arcDelay(edge, arc, arc_delay_max_index_);
delays.setValue(tr, MinMax::max(), delayAsFloat(max_delay));
}
- delete arc_iter;
if (delays.hasValue(TransRiseFall::rise(), MinMax::min())
&& delays.hasValue(TransRiseFall::fall(), MinMax::min())) {
@@ -570,14 +569,13 @@ SdfWriter::writeCheck(Edge *edge,
// Examine the arcs to see if the check requires clk or data edge specifiers.
TimingArc *arcs[TransRiseFall::index_count][TransRiseFall::index_count] =
{{NULL, NULL}, {NULL, NULL}};
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
TransRiseFall *clk_tr = arc->fromTrans()->asRiseFall();
TransRiseFall *data_tr = arc->toTrans()->asRiseFall();;
arcs[clk_tr->index()][data_tr->index()] = arc;
}
- delete arc_iter;
if (arcs[TransRiseFall::fallIndex()][TransRiseFall::riseIndex()] == NULL
&& arcs[TransRiseFall::fallIndex()][TransRiseFall::fallIndex()] == NULL)
@@ -587,12 +585,11 @@ SdfWriter::writeCheck(Edge *edge,
writeEdgeCheck(edge, sdf_check, TransRiseFall::fallIndex(), arcs);
else {
// No special case; write all the checks with data and clock edge specifiers.
- arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
writeCheck(edge, arc, sdf_check, true, true);
}
- delete arc_iter;
}
}
diff --git a/search/CheckMaxSkews.cc b/search/CheckMaxSkews.cc
index 83ff9774..16b832a0 100644
--- a/search/CheckMaxSkews.cc
+++ b/search/CheckMaxSkews.cc
@@ -196,9 +196,9 @@ CheckMaxSkews:: visitMaxSkewChecks(Vertex *vertex,
if (edge->role() == TimingRole::skew()) {
Vertex *ref_vertex = edge->from(graph);
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
TransRiseFall *clk_tr = arc->fromTrans()->asRiseFall();
TransRiseFall *ref_tr = arc->toTrans()->asRiseFall();
VertexPathIterator clk_path_iter(vertex, clk_tr, clk_min_max, search);
@@ -218,7 +218,6 @@ CheckMaxSkews:: visitMaxSkewChecks(Vertex *vertex,
}
}
}
- delete arc_iter;
}
}
}
diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc
index 75fef7eb..05f21a13 100644
--- a/search/CheckSlewLimits.cc
+++ b/search/CheckSlewLimits.cc
@@ -109,6 +109,8 @@ CheckSlewLimits::checkSlews(const Pin *pin,
{
corner1 = NULL;
tr = NULL;
+ slew = 0.0;
+ limit = 0.0;
slack = MinMax::min()->initValue();
if (corner)
checkSlews1(pin, corner, min_max,
diff --git a/search/Corner.cc b/search/Corner.cc
index 50410cc9..127c5dcf 100644
--- a/search/Corner.cc
+++ b/search/Corner.cc
@@ -420,17 +420,7 @@ Corner::findDcalcAnalysisPt(const MinMax *min_max) const
PathAnalysisPt *
Corner::findPathAnalysisPt(const MinMax *min_max) const
{
- int ap_count = path_analysis_pts_.size();
- if (ap_count == 0)
- return NULL;
- else if (ap_count == 1)
- return path_analysis_pts_[0];
- else if (ap_count == 2)
- return path_analysis_pts_[min_max->index()];
- else {
- internalError("unknown analysis point count");
- return NULL;
- }
+ return path_analysis_pts_[min_max->index()];
}
void
diff --git a/search/Crpr.cc b/search/Crpr.cc
index 0e895005..e6d722bf 100644
--- a/search/Crpr.cc
+++ b/search/Crpr.cc
@@ -88,8 +88,9 @@ Crpr::maxCrpr(ClkInfo *clk_info)
if (!crpr_clk_path.isNull()) {
PathVertex crpr_clk_vpath(crpr_clk_path, this);
Arrival other_arrival = otherMinMaxArrival(&crpr_clk_vpath);
- float crpr_diff = abs(delayAsFloat(crpr_clk_vpath.arrival(this)
- - other_arrival));
+ float crpr_diff = abs(delayAsFloat(crpr_clk_vpath.arrival(this),
+ EarlyLate::late())
+ - delayAsFloat(other_arrival, EarlyLate::early()));
return crpr_diff;
}
else
@@ -371,7 +372,8 @@ float
Crpr::crprArrivalDiff(const PathVertex *path)
{
Arrival other_arrival = otherMinMaxArrival(path);
- float crpr_diff = abs(delayAsFloat(path->arrival(this)-other_arrival));
+ float crpr_diff = abs(delayAsFloat(path->arrival(this), EarlyLate::late())
+ - delayAsFloat(other_arrival, EarlyLate::early()));
return crpr_diff;
}
diff --git a/search/FindRegister.cc b/search/FindRegister.cc
index 4ef86404..5416ad77 100644
--- a/search/FindRegister.cc
+++ b/search/FindRegister.cc
@@ -243,10 +243,10 @@ FindRegVisitor::findSequential(const Pin *clk_pin,
{
has_seqs = false;
matches = false;
- CellSequentialIterator *seq_iter = cell->sequentialIterator();
- while (seq_iter->hasNext()) {
+ LibertyCellSequentialIterator seq_iter(cell);
+ while (seq_iter.hasNext()) {
has_seqs = true;
- Sequential *seq = seq_iter->next();
+ Sequential *seq = seq_iter.next();
if ((seq->isRegister() && edge_triggered)
|| (seq->isLatch() && latches)) {
if (clk_tr == TransRiseFallBoth::riseFall()) {
@@ -270,7 +270,6 @@ FindRegVisitor::findSequential(const Pin *clk_pin,
}
}
}
- delete seq_iter;
}
bool
@@ -281,13 +280,12 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell,
bool latches)
{
bool matches = false;
- CellTimingArcSetIterator *set_iter = cell->timingArcSetIterator();
const TransRiseFall *clk_tr1 = clk_tr->asRiseFall();
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
- TimingArcSetArcIterator *arc_iter = set->timingArcIterator();
- TimingArc *arc = arc_iter->next();
- delete arc_iter;
+ LibertyCellTimingArcSetIterator set_iter(cell);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
+ TimingArcSetArcIterator arc_iter(set);
+ TimingArc *arc = arc_iter.next();
TransRiseFall *arc_clk_tr = arc->fromTrans()->asRiseFall();
bool tr_matches = (clk_tr == TransRiseFallBoth::riseFall()
|| (arc_clk_tr == clk_tr1
@@ -304,7 +302,6 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell,
break;
}
}
- delete set_iter;
return matches;
}
@@ -313,18 +310,14 @@ FindRegVisitor::hasTimingCheck(LibertyCell *cell,
LibertyPort *clk,
LibertyPort *d)
{
- bool has_check = false;
- CellTimingArcSetIterator *set_iter = cell->timingArcSetIterator(clk, d);
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, clk, d);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
TimingRole *role = set->role();
- if (role->isTimingCheck()) {
- has_check = true;
- break;
- }
+ if (role->isTimingCheck())
+ return true;
}
- delete set_iter;
- return has_check;
+ return false;
}
class FindRegInstances : public FindRegVisitor
@@ -560,18 +553,14 @@ FindRegClkPins::matchPin(Pin *pin)
{
LibertyPort *port = network_->libertyPort(pin);
LibertyCell *cell = port->libertyCell();
- CellTimingArcSetIterator *set_iter = cell->timingArcSetFromIterator(port);
- bool match = false;
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, port, NULL);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
TimingRole *role = set->role();
- if (role->isTimingCheck()) {
- match = true;
- break;
- }
+ if (role->isTimingCheck())
+ return true;
}
- delete set_iter;
- return match;
+ return false;
}
@@ -622,18 +611,14 @@ FindRegAsyncPins::matchPin(Pin *pin)
{
LibertyPort *port = network_->libertyPort(pin);
LibertyCell *cell = port->libertyCell();
- CellTimingArcSetIterator *set_iter = cell->timingArcSetFromIterator(port);
- bool match = false;
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, port, NULL);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
TimingRole *role = set->role();
- if (role == TimingRole::regSetClr()) {
- match = true;
- break;
- }
+ if (role == TimingRole::regSetClr())
+ return true;
}
- delete set_iter;
- return match;
+ return false;
}
PinSet *
@@ -676,20 +661,16 @@ FindRegOutputPins::matchPin(Pin *pin)
{
LibertyPort *port = network_->libertyPort(pin);
LibertyCell *cell = port->libertyCell();
- CellTimingArcSetIterator *set_iter = cell->timingArcSetToIterator(port);
- bool match = false;
- while (set_iter->hasNext()) {
- TimingArcSet *set = set_iter->next();
+ LibertyCellTimingArcSetIterator set_iter(cell, NULL, port);
+ while (set_iter.hasNext()) {
+ TimingArcSet *set = set_iter.next();
TimingRole *role = set->role();
if (role == TimingRole::regClkToQ()
|| role == TimingRole::latchEnToQ()
- || role == TimingRole::latchDtoQ()) {
- match = true;
- break;
- }
+ || role == TimingRole::latchDtoQ())
+ return true;
}
- delete set_iter;
- return match;
+ return false;
}
void
diff --git a/search/PathEnd.cc b/search/PathEnd.cc
index c6a5b4d1..b548e79c 100644
--- a/search/PathEnd.cc
+++ b/search/PathEnd.cc
@@ -75,7 +75,7 @@ PathEnd::pathEarlyLate(const StaState *sta) const
}
const EarlyLate *
-PathEnd::clkEarlyLate(const StaState *sta) const
+PathEnd::clkEarlyLate(const StaState *) const
{
return NULL;
}
diff --git a/search/PathEnum.cc b/search/PathEnum.cc
index 799c4611..bcbfa336 100644
--- a/search/PathEnum.cc
+++ b/search/PathEnum.cc
@@ -103,7 +103,6 @@ PathEnum::PathEnum(int group_count,
int endpoint_count,
bool unique_pins,
bool cmp_slack,
- const MinMax *min_max,
const StaState *sta) :
StaState(sta),
cmp_slack_(cmp_slack),
diff --git a/search/PathEnum.hh b/search/PathEnum.hh
index 88dd970c..ec88e998 100644
--- a/search/PathEnum.hh
+++ b/search/PathEnum.hh
@@ -57,7 +57,6 @@ public:
int endpoint_count,
bool unique_pins,
bool cmp_slack,
- const MinMax *min_max,
const StaState *sta);
// Insert path ends that are enumerated in slack/arrival order.
void insert(PathEnd *path_end);
diff --git a/search/PathGroup.cc b/search/PathGroup.cc
index 30ba9059..bc48bd83 100644
--- a/search/PathGroup.cc
+++ b/search/PathGroup.cc
@@ -757,7 +757,7 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
group_path_iter->next(name, groups);
PathGroup *group = findPathGroup(name, path_min_max);
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, true, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
}
delete group_path_iter;
@@ -766,22 +766,22 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
Clock *clk = clk_iter->next();
PathGroup *group = findPathGroup(clk, path_min_max);
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, true, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
}
delete clk_iter;
PathGroup *group = unconstrained_[mm_index];
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, false, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, false);
group = path_delay_[mm_index];
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, true, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
group = gated_clk_[mm_index];
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, true, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
group = async_[mm_index];
if (group)
- enumPathEnds(group, group_count, endpoint_count, unique_pins, true, path_min_max);
+ enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
}
}
}
@@ -791,12 +791,11 @@ PathGroups::enumPathEnds(PathGroup *group,
int group_count,
int endpoint_count,
bool unique_pins,
- bool cmp_slack,
- const MinMax *min_max)
+ bool cmp_slack)
{
// Insert the worst max_path path ends in the group into a path
// enumerator.
- PathEnum path_enum(group_count, endpoint_count, unique_pins, cmp_slack, min_max, this);
+ PathEnum path_enum(group_count, endpoint_count, unique_pins, cmp_slack, this);
PathGroupIterator *end_iter = group->iterator();
while (end_iter->hasNext()) {
PathEnd *end = end_iter->next();
diff --git a/search/PathGroup.hh b/search/PathGroup.hh
index b4db883d..d5c04174 100644
--- a/search/PathGroup.hh
+++ b/search/PathGroup.hh
@@ -149,8 +149,7 @@ protected:
int group_count,
int endpoint_count,
bool unique_pins,
- bool cmp_slack,
- const MinMax *min_max);
+ bool cmp_slack);
void pushGroupPathEnds(PathEndSeq *path_ends);
void pushUnconstrainedPathEnds(PathEndSeq *path_ends,
diff --git a/search/Power.cc b/search/Power.cc
index ac37651b..59a789cf 100644
--- a/search/Power.cc
+++ b/search/Power.cc
@@ -23,7 +23,6 @@
#include "Liberty.hh"
#include "InternalPower.hh"
#include "LeakagePower.hh"
-#include "InternalPower.hh"
#include "TimingArc.hh"
#include "FuncExpr.hh"
#include "PortDirection.hh"
@@ -103,6 +102,7 @@ Power::power(const Corner *corner,
total.incr(inst_power);
}
}
+ delete inst_iter;
}
////////////////////////////////////////////////////////////////
@@ -138,10 +138,10 @@ Power::power(const Instance *inst,
bool is_clk;
activity(to_pin, activity1, is_clk);
if (to_port->direction()->isAnyOutput()) {
- findSwitchingPower(inst, cell, to_pin, to_port, activity1, load_cap,
+ findSwitchingPower(cell, to_port, activity1, load_cap,
dcalc_ap, result);
}
- findInternalPower(inst, cell, to_pin, to_port, activity1, is_clk,
+ findInternalPower(inst, cell, to_port, activity1, is_clk,
load_cap, dcalc_ap, result);
}
delete pin_iter;
@@ -151,7 +151,6 @@ Power::power(const Instance *inst,
void
Power::findInternalPower(const Instance *inst,
LibertyCell *cell,
- const Pin *to_pin,
const LibertyPort *to_port,
float activity,
bool is_clk,
@@ -173,9 +172,9 @@ Power::findInternalPower(const Instance *inst,
units_->capacitanceUnit()->asString(load_cap),
activity * 1e-9,
duty);
- LibertyCellInternalPowerIterator *pwr_iter = cell->internalPowerIterator();
- while (pwr_iter->hasNext()) {
- InternalPower *pwr = pwr_iter->next();
+ LibertyCellInternalPowerIterator pwr_iter(cell);
+ while (pwr_iter.hasNext()) {
+ InternalPower *pwr = pwr_iter.next();
const char *related_pg_pin = pwr->relatedPgPin();
if (pwr->port() == to_port
&& ((related_pg_pin == NULL || pwr_pin == NULL)
@@ -189,7 +188,7 @@ Power::findInternalPower(const Instance *inst,
while (tr_iter.hasNext()) {
TransRiseFall *to_tr = tr_iter.next();
// Need unateness to find from_tr.
- float slew = sta_->vertexSlew(from_vertex, to_tr, dcalc_ap);
+ float slew = delayAsFloat(sta_->vertexSlew(from_vertex, to_tr, dcalc_ap));
float energy, tr_internal;
if (from_port) {
float energy1 = pwr->power(to_tr, pvt, slew, load_cap);
@@ -216,7 +215,6 @@ Power::findInternalPower(const Instance *inst,
}
}
}
- delete pwr_iter;
debugPrint1(debug_, "power", 2, " internal = %.5g\n", port_internal);
result.setInternal(result.internal() + port_internal);
}
@@ -232,13 +230,12 @@ Power::loadCap(const Pin *to_pin,
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
ceff_sum += graph_delay_calc_->ceff(edge, arc, dcalc_ap);
ceff_count++;
}
- delete arc_iter;
}
return ceff_sum / ceff_count;
}
@@ -250,9 +247,9 @@ Power::findLeakagePower(const Instance *inst,
PowerResult &result)
{
float leakage = cell->leakagePower();
- LibertyCellLeakagePowerIterator *pwr_iter = cell->leakagePowerIterator();
- while (pwr_iter->hasNext()) {
- LeakagePower *leak = pwr_iter->next();
+ LibertyCellLeakagePowerIterator pwr_iter(cell);
+ while (pwr_iter.hasNext()) {
+ LeakagePower *leak = pwr_iter.next();
FuncExpr *when = leak->when();
if (when) {
LogicValue when_value = sim_->evalExpr(when, inst);
@@ -267,14 +264,11 @@ Power::findLeakagePower(const Instance *inst,
}
}
}
- delete pwr_iter;
result.setLeakage(leakage);
}
void
-Power::findSwitchingPower(const Instance *inst,
- LibertyCell *cell,
- const Pin *to_pin,
+Power::findSwitchingPower(LibertyCell *cell,
const LibertyPort *to_port,
float activity,
float load_cap,
@@ -307,7 +301,7 @@ Power::activity(const Pin *pin,
float
Power::voltage(LibertyCell *cell,
- const LibertyPort *port,
+ const LibertyPort *,
const DcalcAnalysisPt *dcalc_ap)
{
// Should use cell pg_pin voltage name to voltage.
diff --git a/search/Power.hh b/search/Power.hh
index 9a69b44e..3146a526 100644
--- a/search/Power.hh
+++ b/search/Power.hh
@@ -51,7 +51,6 @@ protected:
PowerResult &result);
void findInternalPower(const Instance *inst,
LibertyCell *cell,
- const Pin *to_pin,
const LibertyPort *to_port,
float activity,
bool is_clk,
@@ -63,9 +62,7 @@ protected:
LibertyCell *cell,
// Return values.
PowerResult &result);
- void findSwitchingPower(const Instance *inst,
- LibertyCell *cell,
- const Pin *to_pin,
+ void findSwitchingPower(LibertyCell *cell,
const LibertyPort *to_port,
float activity,
float load_cap,
diff --git a/search/ReportPath.cc b/search/ReportPath.cc
index 19eb30b5..b5af8b64 100644
--- a/search/ReportPath.cc
+++ b/search/ReportPath.cc
@@ -2713,8 +2713,8 @@ ReportPath::reportPath5(const Path *path,
// from the input to the loads. Report the wire delay on the
// input pin instead.
Arrival next_time = next_path->arrival(this) + time_offset;
- incr = delayMeanSigma(next_time, min_max)
- - delayMeanSigma(time, min_max);
+ incr = delayAsFloat(next_time, min_max)
+ - delayAsFloat(time, min_max);
time = next_time;
line_case = "input_drive";
}
@@ -2761,13 +2761,13 @@ ReportPath::reportPath5(const Path *path,
line_case = "clk_ideal";
}
else if (is_clk && !is_clk_start) {
- incr = delayMeanSigma(time, min_max)
- - delayMeanSigma(prev_time, min_max);
+ incr = delayAsFloat(time, min_max)
+ - delayAsFloat(prev_time, min_max);
line_case = "clk_prop";
}
else {
- incr = delayMeanSigma(time, min_max)
- - delayMeanSigma(prev_time, min_max);
+ incr = delayAsFloat(time, min_max)
+ - delayAsFloat(prev_time, min_max);
line_case = "normal";
}
if (report_input_pin_
@@ -3264,7 +3264,7 @@ ReportPath::reportTotalDelay(Delay value,
const EarlyLate *early_late,
string &result)
{
- const char *str = delayMeanSigmaString(value, early_late, units_, digits_);
+ const char *str = delayAsString(value, early_late, units_, digits_);
if (stringEq(str, minus_zero_))
// Filter "-0.00" fields.
str = plus_zero_;
@@ -3281,7 +3281,7 @@ ReportPath::reportFieldDelayMinus(Delay value,
if (delayAsFloat(value) == field_blank_)
reportFieldBlank(field, result);
else {
- float mean_sigma = delayMeanSigma(value, early_late);
+ float mean_sigma = delayAsFloat(value, early_late);
const char *str = units_->timeUnit()->asString(-mean_sigma, digits_);
if (stringEq(str, plus_zero_))
// Force leading minus sign.
@@ -3299,7 +3299,7 @@ ReportPath::reportFieldDelay(Delay value,
if (delayAsFloat(value) == field_blank_)
reportFieldBlank(field, result);
else {
- const char *str = delayMeanSigmaString(value, early_late, units_, digits_);
+ const char *str = delayAsString(value, early_late, units_, digits_);
if (stringEq(str, minus_zero_))
// Filter "-0.00" fields.
str = plus_zero_;
diff --git a/search/Search.cc b/search/Search.cc
index 39a6fae7..7a875f64 100644
--- a/search/Search.cc
+++ b/search/Search.cc
@@ -3052,7 +3052,7 @@ Search::deratedDelay(Vertex *from_vertex,
DcalcAPIndex ap_index = dcalc_ap->index();
float derate = timingDerate(from_vertex, arc, edge, is_clk, path_ap);
ArcDelay delay = graph_->arcDelay(edge, arc, ap_index);
- return delay + Delay((derate - 1.0) * delayAsFloat(delay));
+ return delay * derate;
}
float
@@ -3706,13 +3706,40 @@ Search::exceptionTo(ExceptionPathType type,
Slack
Search::totalNegativeSlack(const MinMax *min_max)
+{
+ tnsPreamble();
+ Slack tns = 0.0;
+ CornerIterator corner_iter(this);
+ while (corner_iter.hasNext()) {
+ Corner *corner = corner_iter.next();
+ PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
+ Slack tns1 = tns_[path_ap_index];
+ if (tns1 < tns)
+ tns = tns1;
+ }
+ return tns;
+}
+
+Slack
+Search::totalNegativeSlack(const Corner *corner,
+ const MinMax *min_max)
+{
+ tnsPreamble();
+ PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
+ return tns_[path_ap_index];
+}
+
+void
+Search::tnsPreamble()
{
wnsTnsPreamble();
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
+ tns_.resize(path_ap_count);
+ tns_slacks_.resize(path_ap_count);
if (tns_exists_)
updateInvalidTns();
else
findTotalNegativeSlacks();
- return static_cast(tns_[min_max->index()]);
}
void
@@ -3731,6 +3758,7 @@ Search::tnsInvalid(Vertex *vertex)
void
Search::updateInvalidTns()
{
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
VertexSet::Iterator vertex_iter(invalid_tns_);
while (vertex_iter.hasNext()) {
Vertex *vertex = vertex_iter.next();
@@ -3738,7 +3766,7 @@ Search::updateInvalidTns()
if (isEndpoint(vertex)) {
debugPrint1(debug_, "tns", 2, "update tns %s\n",
vertex->name(sdc_network_));
- Slack slacks[MinMax::index_count];
+ SlackSeq slacks(path_ap_count);
wnsSlacks(vertex, slacks);
if (tns_exists_)
@@ -3753,67 +3781,64 @@ Search::updateInvalidTns()
void
Search::findTotalNegativeSlacks()
{
- int min_index = MinMax::minIndex();
- int max_index = MinMax::maxIndex();
- tns_[min_index] = 0.0;
- tns_[max_index] = 0.0;
- tns_slacks_[min_index].clear();
- tns_slacks_[max_index].clear();
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
+ for (PathAPIndex i = 0; i < path_ap_count; i++) {
+ tns_[i] = 0.0;
+ tns_slacks_[i].clear();
+ }
VertexSet::Iterator end_iter(endpoints());
while (end_iter.hasNext()) {
Vertex *vertex = end_iter.next();
// No locking required.
- Slack slacks[MinMax::index_count];
+ SlackSeq slacks(path_ap_count);
wnsSlacks(vertex, slacks);
- tnsIncr(vertex, delayAsFloat(slacks[min_index]), min_index);
- tnsIncr(vertex, delayAsFloat(slacks[max_index]), max_index);
+ for (PathAPIndex i = 0; i < path_ap_count; i++)
+ tnsIncr(vertex, slacks[i], i);
}
tns_exists_ = true;
}
void
Search::updateTns(Vertex *vertex,
- Slack *slacks)
+ SlackSeq &slacks)
{
- int min_index = MinMax::minIndex();
- int max_index = MinMax::maxIndex();
- tnsDecr(vertex, min_index);
- tnsIncr(vertex, delayAsFloat(slacks[min_index]), min_index);
-
- tnsDecr(vertex, max_index);
- tnsIncr(vertex, delayAsFloat(slacks[max_index]), max_index);
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
+ for (PathAPIndex i = 0; i < path_ap_count; i++) {
+ tnsDecr(vertex, i);
+ tnsIncr(vertex, slacks[i], i);
+ }
}
void
Search::tnsIncr(Vertex *vertex,
- float slack,
- int min_max_index)
+ Slack slack,
+ PathAPIndex path_ap_index)
{
- if (fuzzyLess(slack, 0.0)) {
+ if (delayFuzzyLess(slack, 0.0)) {
debugPrint2(debug_, "tns", 3, "tns+ %s %s\n",
delayAsString(slack, units_),
vertex->name(sdc_network_));
- tns_[min_max_index] += slack;
- if (tns_slacks_[min_max_index].hasKey(vertex))
+ tns_[path_ap_index] += slack;
+ if (tns_slacks_[path_ap_index].hasKey(vertex))
internalError("tns incr existing vertex");
- tns_slacks_[min_max_index][vertex] = slack;
+ tns_slacks_[path_ap_index][vertex] = slack;
}
}
void
Search::tnsDecr(Vertex *vertex,
- int min_max_index)
+ PathAPIndex path_ap_index)
{
Slack slack;
bool found;
- tns_slacks_[min_max_index].findKey(vertex, slack, found);
+ tns_slacks_[path_ap_index].findKey(vertex, slack, found);
if (found
&& delayFuzzyLess(slack, 0.0)) {
debugPrint2(debug_, "tns", 3, "tns- %s %s\n",
delayAsString(slack, units_),
vertex->name(sdc_network_));
- tns_[min_max_index] -= delayAsFloat(slack);
- tns_slacks_[min_max_index].eraseKey(vertex);
+ tns_[path_ap_index] -= delayAsFloat(slack);
+ tns_slacks_[path_ap_index].eraseKey(vertex);
}
}
@@ -3823,27 +3848,44 @@ Search::tnsNotifyBefore(Vertex *vertex)
{
if (tns_exists_
&& isEndpoint(vertex)) {
- int min_index = MinMax::minIndex();
- int max_index = MinMax::maxIndex();
- tnsDecr(vertex, min_index);
- tnsDecr(vertex, max_index);
+ int ap_count = corners_->pathAnalysisPtCount();
+ for (int i = 0; i < ap_count; i++) {
+ tnsDecr(vertex, i);
+ }
}
}
////////////////////////////////////////////////////////////////
-Slack
-Search::worstSlack(const MinMax *min_max)
+void
+Search::worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
worstSlackPreamble();
- return worst_slacks_->worstSlack(min_max);
+ worst_slacks_->worstSlack(min_max, worst_slack, worst_vertex);
}
-Vertex *
-Search::worstSlackVertex(const MinMax *min_max)
+void
+Search::worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
worstSlackPreamble();
- return worst_slacks_->worstSlackVertex(min_max);
+ worst_slacks_->worstSlack(corner, min_max, worst_slack, worst_vertex);
+}
+
+void
+Search::worstSlackPreamble()
+{
+ wnsTnsPreamble();
+ if (worst_slacks_)
+ updateInvalidTns();
+ else
+ worst_slacks_ = new WorstSlacks(this);
}
void
@@ -3873,16 +3915,6 @@ Search::wnsTnsPreamble()
seedRequireds();
}
-void
-Search::worstSlackPreamble()
-{
- wnsTnsPreamble();
- if (worst_slacks_)
- updateInvalidTns();
- else
- worst_slacks_ = new WorstSlacks(this);
-}
-
void
Search::clearWorstSlack()
{
@@ -3898,17 +3930,17 @@ Search::clearWorstSlack()
class FindEndSlackVisitor : public PathEndVisitor
{
public:
- FindEndSlackVisitor(Slack *slacks,
+ FindEndSlackVisitor(SlackSeq &slacks,
const StaState *sta);
virtual PathEndVisitor *copy();
virtual void visit(PathEnd *path_end);
protected:
- Slack *slacks_;
+ SlackSeq &slacks_;
const StaState *sta_;
};
-FindEndSlackVisitor::FindEndSlackVisitor(Slack *slacks,
+FindEndSlackVisitor::FindEndSlackVisitor(SlackSeq &slacks,
const StaState *sta) :
slacks_(slacks),
sta_(sta)
@@ -3927,21 +3959,22 @@ FindEndSlackVisitor::visit(PathEnd *path_end)
{
if (!path_end->isUnconstrained()) {
PathRef &path = path_end->pathRef();
- int mm_index = path.minMax(sta_)->index();
+ PathAPIndex path_ap_index = path.pathAnalysisPtIndex(sta_);
Slack slack = path_end->slack(sta_);
- if (delayFuzzyLess(slack, slacks_[mm_index]))
- slacks_[mm_index] = slack;
+ if (delayFuzzyLess(slack, slacks_[path_ap_index]))
+ slacks_[path_ap_index] = slack;
}
}
void
Search::wnsSlacks(Vertex *vertex,
// Return values.
- Slack *slacks)
+ SlackSeq &slacks)
{
Slack slack_init = MinMax::min()->initValue();
- slacks[MinMax::minIndex()] = slack_init;
- slacks[MinMax::maxIndex()] = slack_init;
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
+ for (PathAPIndex i = 0; i < path_ap_count; i++)
+ slacks[i] = slack_init;
if (hasFanout(vertex, search_adj_, graph_)) {
// If the vertex has fanout the path slacks include downstream
// PathEnd slacks so find the endpoint slack directly.
@@ -3952,23 +3985,23 @@ Search::wnsSlacks(Vertex *vertex,
VertexPathIterator path_iter(vertex, this);
while (path_iter.hasNext()) {
Path *path = path_iter.next();
- const MinMax *path_min_max = path->minMax(this);
- int path_mm_index = path_min_max->index();
+ PathAPIndex path_ap_index = path->pathAnalysisPtIndex(this);
const Slack path_slack = path->slack(this);
if (!path->tag(this)->isFilter()
- && delayFuzzyLess(path_slack, slacks[path_mm_index]))
- slacks[path_mm_index] = path_slack;
+ && delayFuzzyLess(path_slack, slacks[path_ap_index]))
+ slacks[path_ap_index] = path_slack;
}
}
}
Slack
Search::wnsSlack(Vertex *vertex,
- const MinMax *min_max)
+ PathAPIndex path_ap_index)
{
- Slack slacks[MinMax::index_count];
+ PathAPIndex path_ap_count = corners_->pathAnalysisPtCount();
+ SlackSeq slacks(path_ap_count);
wnsSlacks(vertex, slacks);
- return slacks[min_max->index()];
+ return slacks[path_ap_index];
}
////////////////////////////////////////////////////////////////
diff --git a/search/Search.hh b/search/Search.hh
index 7a88ca6a..3164df39 100644
--- a/search/Search.hh
+++ b/search/Search.hh
@@ -59,6 +59,8 @@ typedef Set ClkInfoSet;
typedef HashSet TagHashSet;
typedef HashSet TagGroupSet;
typedef Map VertexSlackMap;
+typedef Vector VertexSlackMapSeq;
+typedef Vector WorstSlacksSeq;
class Search : public StaState
{
@@ -124,11 +126,22 @@ public:
void findRequireds(Level level);
bool requiredsSeeded() const { return requireds_seeded_; }
bool requiredsExist() const { return requireds_exist_; }
+ // The sum of all negative endpoints slacks.
+ // Incrementally updated.
Slack totalNegativeSlack(const MinMax *min_max);
- // Worst endpoint slack.
- Slack worstSlack(const MinMax *min_max);
- // Worst endpoint slack vertex.
- Vertex *worstSlackVertex(const MinMax *min_max);
+ Slack totalNegativeSlack(const Corner *corner,
+ const MinMax *min_max);
+ // Worst endpoint slack and vertex.
+ // Incrementally updated.
+ void worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
+ void worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
// Clock arrival respecting ideal clock insertion delay and latency.
Arrival clkPathArrival(const Path *clk_path) const;
Arrival clkPathArrival(const Path *clk_path,
@@ -313,7 +326,7 @@ public:
TagGroup *tagGroup(TagGroupIndex index) const;
void reportArrivals(Vertex *vertex) const;
Slack wnsSlack(Vertex *vertex,
- const MinMax *min_max);
+ PathAPIndex path_ap_index);
void levelChangedBefore(Vertex *vertex);
void seedInputArrival(const Pin *pin,
Vertex *vertex,
@@ -471,24 +484,25 @@ protected:
void deleteFilterTagGroups();
void deleteFilterClkInfos();
+ void tnsPreamble();
void findTotalNegativeSlacks();
void updateInvalidTns();
void clearWorstSlack();
void wnsSlacks(Vertex *vertex,
// Return values.
- Slack *slacks);
+ SlackSeq &slacks);
void wnsTnsPreamble();
void worstSlackPreamble();
void deleteWorstSlacks();
void updateWorstSlacks(Vertex *vertex,
- Slack *slacks);
+ Slack slacks);
void updateTns(Vertex *vertex,
- Slack *slacks);
+ SlackSeq &slacks);
void tnsIncr(Vertex *vertex,
- float slack,
- int min_max_index);
+ Slack slack,
+ PathAPIndex path_ap_index);
void tnsDecr(Vertex *vertex,
- int min_max_index);
+ PathAPIndex path_ap_index);
void tnsNotifyBefore(Vertex *vertex);
PathGroups *makePathGroups(int group_count,
int endpoint_count,
@@ -539,9 +553,12 @@ protected:
bool tns_exists_;
// Endpoint vertices with slacks that have changed since tns was found.
VertexSet invalid_tns_;
- double tns_[MinMax::index_count];
- VertexSlackMap tns_slacks_[MinMax::index_count];
+ // Indexed by path_ap->index().
+ SlackSeq tns_;
+ // Indexed by path_ap->index().
+ VertexSlackMapSeq tns_slacks_;
mutable Mutex tns_lock_;
+ // Indexed by path_ap->index().
WorstSlacks *worst_slacks_;
// Use pointer to clk_info set so Tag.hh does not need to be included.
ClkInfoSet *clk_info_set_;
diff --git a/search/SearchClass.hh b/search/SearchClass.hh
index a66fb98d..313fc9de 100644
--- a/search/SearchClass.hh
+++ b/search/SearchClass.hh
@@ -110,6 +110,7 @@ typedef Vector ArrivalSeq;
typedef Map VertexPathCountMap;
typedef UnorderedMap ArrivalMap;
typedef Vector PathVertexSeq;
+typedef Vector SlackSeq;
typedef enum {
report_path_full,
diff --git a/search/Sim.cc b/search/Sim.cc
index 47bcd52b..f7099765 100644
--- a/search/Sim.cc
+++ b/search/Sim.cc
@@ -1114,11 +1114,10 @@ isCondDisabled(Edge *edge,
LibertyCell *cell = network->libertyCell(inst);
LibertyPort *from_port = network->libertyPort(from_pin);
LibertyPort *to_port = network->libertyPort(to_pin);
- CellTimingArcSetIterator *cond_iter =
- cell->timingArcSetIterator(from_port, to_port);
+ LibertyCellTimingArcSetIterator cond_iter(cell, from_port, to_port);
is_disabled = false;
- while (cond_iter->hasNext()) {
- TimingArcSet *cond_set = cond_iter->next();
+ while (cond_iter.hasNext()) {
+ TimingArcSet *cond_set = cond_iter.next();
FuncExpr *cond = cond_set->cond();
if (cond && sim->evalExpr(cond, inst) == logic_one) {
disable_cond = cond;
@@ -1126,7 +1125,6 @@ isCondDisabled(Edge *edge,
break;
}
}
- delete cond_iter;
}
}
diff --git a/search/Sta.cc b/search/Sta.cc
index 6ef6c813..7fd8cb50 100644
--- a/search/Sta.cc
+++ b/search/Sta.cc
@@ -515,6 +515,7 @@ Sta::~Sta()
delete debug_;
delete units_;
delete report_;
+ delete power_;
}
void
@@ -1624,15 +1625,12 @@ hasDisabledArcs(Edge *edge,
Graph *graph)
{
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
- if (!searchThru(edge, arc, graph)) {
- delete arc_iter;
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
+ if (!searchThru(edge, arc, graph))
return true;
- }
}
- delete arc_iter;
return false;
}
@@ -2847,17 +2845,32 @@ Sta::totalNegativeSlack(const MinMax *min_max)
}
Slack
-Sta::worstSlack(const MinMax *min_max)
+Sta::totalNegativeSlack(const Corner *corner,
+ const MinMax *min_max)
{
searchPreamble();
- return search_->worstSlack(min_max);
+ return search_->totalNegativeSlack(corner, min_max);
}
-Vertex *
-Sta::worstSlackVertex(const MinMax *min_max)
+void
+Sta::worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
searchPreamble();
- return search_->worstSlackVertex(min_max);
+ return search_->worstSlack(min_max, worst_slack, worst_vertex);
+}
+
+void
+Sta::worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
+{
+ searchPreamble();
+ return search_->worstSlack(corner, min_max, worst_slack, worst_vertex);
}
////////////////////////////////////////////////////////////////
@@ -3623,16 +3636,15 @@ Sta::makeInstanceAfter(Instance *inst)
{
LibertyCell *lib_cell = network_->libertyCell(inst);
if (lib_cell && lib_cell->hasInternalPorts()) {
- LibertyCellPortBitIterator *port_iter = lib_cell->libertyPortBitIterator();
- while (port_iter->hasNext()) {
- LibertyPort *lib_port = port_iter->next();
+ LibertyCellPortBitIterator port_iter(lib_cell);
+ while (port_iter.hasNext()) {
+ LibertyPort *lib_port = port_iter.next();
if (lib_port->direction()->isInternal()
&& lib_cell->hasTimingArcs(lib_port)) {
Pin *pin = network_->findPin(inst, lib_port);
connectPinAfter(pin);
}
}
- delete port_iter;
}
}
@@ -4719,7 +4731,7 @@ Sta::reportSlewLimitVerbose(Pin *pin,
Slew slew;
float limit, slack;
check_slew_limits_->checkSlews(pin, corner, min_max,
- corner, tr, slew, limit, slack);
+ corner1, tr, slew, limit, slack);
report_path_->reportSlewLimitVerbose(pin, corner1, tr, slew,
limit, slack, min_max);
}
diff --git a/search/Sta.hh b/search/Sta.hh
index 17e3cf42..fdb0b232 100644
--- a/search/Sta.hh
+++ b/search/Sta.hh
@@ -903,12 +903,19 @@ public:
// The sum of all negative endpoints slacks.
// Incrementally updated.
Slack totalNegativeSlack(const MinMax *min_max);
- // Worst endpoint slack.
+ Slack totalNegativeSlack(const Corner *corner,
+ const MinMax *min_max);
+ // Worst endpoint slack and vertex.
// Incrementally updated.
- Slack worstSlack(const MinMax *min_max);
- // Worst endpoint slack vertex.
- // Incrementally updated.
- Vertex *worstSlackVertex(const MinMax *min_max);
+ void worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
+ void worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
VertexPathIterator *vertexPathIterator(Vertex *vertex,
const TransRiseFall *tr,
const PathAnalysisPt *path_ap);
diff --git a/search/WorstSlack.cc b/search/WorstSlack.cc
index d3a03a80..856cffc3 100644
--- a/search/WorstSlack.cc
+++ b/search/WorstSlack.cc
@@ -19,155 +19,95 @@
#include "Debug.hh"
#include "Report.hh"
#include "Graph.hh"
+#include "Corner.hh"
#include "Search.hh"
+#include "PathAnalysisPt.hh"
#include "WorstSlack.hh"
namespace sta {
using std::min;
-////////////////////////////////////////////////////////////////
-
-class WnsSlackLess
+WorstSlacks::WorstSlacks(StaState *sta) :
+ sta_(sta)
{
-public:
- WnsSlackLess(const MinMax *min_max,
- Search *search);
- bool operator()(Vertex *vertex1,
- Vertex *vertex2);
-
-private:
- const MinMax *min_max_;
- Search *search_;
-};
-
-WnsSlackLess::WnsSlackLess(const MinMax *min_max,
- Search *search) :
- min_max_(min_max),
- search_(search)
-{
-}
-
-bool
-WnsSlackLess::operator()(Vertex *vertex1,
- Vertex *vertex2)
-{
- return delayFuzzyLess(search_->wnsSlack(vertex1, min_max_),
- search_->wnsSlack(vertex2, min_max_));
-}
-
-////////////////////////////////////////////////////////////////
-
-class WorstSlack
-{
-public:
- WorstSlack(const MinMax *min_max,
- StaState *sta);
- Vertex *worstVertex();
- Slack worstSlack();
- void clear();
- void updateWorstSlack(Vertex *vertex,
- Slack *slacks);
- void deleteVertexBefore(Vertex *vertex);
-
-protected:
- void findWorstSlack();
- void initQueue();
- void findWorstInQueue();
- void setWorstSlack(Vertex *vertex,
- Slack slack);
- void sortQueue();
- void checkQueue();
-
- Slack slack_init_;
- // Vertex with the worst slack.
- // When NULL the worst slack is unknown but in the queue.
- Vertex *worst_vertex_;
- Slack worst_slack_;
- Slack slack_threshold_;
- // Vertices with slack < threshold_
- VertexSet queue_;
- // Queue is sorted and pruned to min_queue_size_ vertices when it
- // reaches max_queue_size_.
- int min_queue_size_;
- int max_queue_size_;
- Mutex lock_;
- const MinMax *min_max_;
- WnsSlackLess slack_less_;
- StaState *sta_;
-};
-
-////////////////////////////////////////////////////////////////
-
-
-WorstSlacks::WorstSlacks(StaState *sta)
-{
- worst_slacks_[MinMax::minIndex()] = new WorstSlack(MinMax::min(), sta);
- worst_slacks_[MinMax::maxIndex()] = new WorstSlack(MinMax::max(), sta);
-}
-
-WorstSlacks::~WorstSlacks()
-{
- delete worst_slacks_[MinMax::minIndex()];
- delete worst_slacks_[MinMax::maxIndex()];
+ worst_slacks_.resize(sta->corners()->pathAnalysisPtCount());
}
void
-WorstSlacks::clear()
+WorstSlacks::worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
- worst_slacks_[MinMax::minIndex()]->clear();
- worst_slacks_[MinMax::maxIndex()]->clear();
+ worst_slack = MinMax::min()->initValue();
+ worst_vertex = NULL;
+ CornerIterator corner_iter(sta_);
+ while (corner_iter.hasNext()) {
+ Corner *corner = corner_iter.next();
+ PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
+ Slack worst_slack1;
+ Vertex *worst_vertex1;
+ worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_,
+ worst_slack1, worst_vertex1);
+ if (delayFuzzyLess(worst_slack1, worst_slack)) {
+ worst_slack = worst_slack1;
+ worst_vertex = worst_vertex1;
+ }
+ }
}
-Slack
-WorstSlacks::worstSlack(const MinMax *min_max)
+void
+WorstSlacks::worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
- return worst_slacks_[min_max->index()]->worstSlack();
-}
-
-Vertex *
-WorstSlacks::worstSlackVertex(const MinMax *min_max)
-{
- return worst_slacks_[min_max->index()]->worstVertex();
+ PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index();
+ worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_,
+ worst_slack, worst_vertex);
}
void
WorstSlacks::updateWorstSlacks(Vertex *vertex,
- Slack *slacks)
+ SlackSeq &slacks)
{
- worst_slacks_[MinMax::minIndex()]->updateWorstSlack(vertex, slacks);
- worst_slacks_[MinMax::maxIndex()]->updateWorstSlack(vertex, slacks);
+ PathAPIndex path_ap_count = sta_->corners()->pathAnalysisPtCount();
+ for (PathAPIndex i = 0; i < path_ap_count; i++)
+ worst_slacks_[i].updateWorstSlack(vertex, slacks, i, sta_);
}
void
WorstSlacks::worstSlackNotifyBefore(Vertex *vertex)
{
- worst_slacks_[MinMax::minIndex()]->deleteVertexBefore(vertex);
- worst_slacks_[MinMax::maxIndex()]->deleteVertexBefore(vertex);
+ WorstSlackSeq::Iterator worst_iter(worst_slacks_);
+ while (worst_iter.hasNext()) {
+ WorstSlack &worst_slack = worst_iter.next();
+ worst_slack.deleteVertexBefore(vertex);
+ }
}
////////////////////////////////////////////////////////////////
-WorstSlack::WorstSlack(const MinMax *min_max,
- StaState *sta) :
+WorstSlack::WorstSlack() :
slack_init_(MinMax::min()->initValue()),
worst_vertex_(NULL),
worst_slack_(slack_init_),
slack_threshold_(slack_init_),
min_queue_size_(10),
- max_queue_size_(20),
- min_max_(min_max),
- slack_less_(min_max, sta->search()),
- sta_(sta)
+ max_queue_size_(20)
{
}
-void
-WorstSlack::clear()
+WorstSlack::WorstSlack(const WorstSlack &) :
+ slack_init_(MinMax::min()->initValue()),
+ worst_vertex_(NULL),
+ worst_slack_(slack_init_),
+ slack_threshold_(slack_init_),
+ min_queue_size_(10),
+ max_queue_size_(20)
{
- queue_.clear();
- worst_vertex_ = NULL;
- worst_slack_ = slack_init_;
}
void
@@ -182,36 +122,36 @@ WorstSlack::deleteVertexBefore(Vertex *vertex)
lock_.unlock();
}
-Vertex *
-WorstSlack::worstVertex()
+void
+WorstSlack::worstSlack(PathAPIndex path_ap_index,
+ const StaState *sta,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex)
{
- findWorstSlack();
- return worst_vertex_;
-}
-
-Slack
-WorstSlack::worstSlack()
-{
- findWorstSlack();
- return worst_slack_;
+ findWorstSlack(path_ap_index, sta);
+ worst_slack = worst_slack_;
+ worst_vertex = worst_vertex_;
}
void
-WorstSlack::findWorstSlack()
+WorstSlack::findWorstSlack(PathAPIndex path_ap_index,
+ const StaState *sta)
{
if (worst_vertex_ == NULL) {
if (queue_.empty())
- initQueue();
+ initQueue(path_ap_index, sta);
else
- findWorstInQueue();
+ findWorstInQueue(path_ap_index, sta);
}
}
void
-WorstSlack::initQueue()
+WorstSlack::initQueue(PathAPIndex path_ap_index,
+ const StaState *sta)
{
- Search *search = sta_->search();
- const Debug *debug = sta_->debug();
+ Search *search = sta->search();
+ const Debug *debug = sta->debug();
debugPrint0(debug, "wns", 3, "init queue\n");
queue_.clear();
@@ -221,27 +161,28 @@ WorstSlack::initQueue()
VertexSet::Iterator end_iter(search->endpoints());
while (end_iter.hasNext()) {
Vertex *vertex = end_iter.next();
- Slack slack = search->wnsSlack(vertex, min_max_);
+ Slack slack = search->wnsSlack(vertex, path_ap_index);
if (!delayFuzzyEqual(slack, slack_init_)) {
if (delayFuzzyLess(slack, worst_slack_))
- setWorstSlack(vertex, slack);
+ setWorstSlack(vertex, slack, sta);
if (delayFuzzyLessEqual(slack, slack_threshold_))
queue_.insert(vertex);
int queue_size = queue_.size();
if (queue_size >= max_queue_size_)
- sortQueue();
+ sortQueue(path_ap_index, sta);
}
}
debugPrint1(debug, "wns", 3, "threshold %s\n",
- delayAsString(slack_threshold_, sta_->units()));
+ delayAsString(slack_threshold_, sta->units()));
// checkQueue();
}
void
-WorstSlack::sortQueue()
+WorstSlack::sortQueue(PathAPIndex path_ap_index,
+ const StaState *sta)
{
- Search *search = sta_->search();
- const Debug *debug = sta_->debug();
+ Search *search = sta->search();
+ const Debug *debug = sta->debug();
debugPrint0(debug, "wns", 3, "sort queue\n");
VertexSeq vertices;
@@ -251,36 +192,38 @@ WorstSlack::sortQueue()
Vertex *vertex = queue_iter.next();
vertices.push_back(vertex);
}
- sort(vertices, slack_less_);
+ WnsSlackLess slack_less(path_ap_index, sta);
+ sort(vertices, slack_less);
int vertex_count = vertices.size();
int threshold_index = min(min_queue_size_, vertex_count - 1);
Vertex *threshold_vertex = vertices[threshold_index];
- slack_threshold_ = search->wnsSlack(threshold_vertex, min_max_);
+ slack_threshold_ = search->wnsSlack(threshold_vertex, path_ap_index);
debugPrint1(debug, "wns", 3, "threshold %s\n",
- delayAsString(slack_threshold_, sta_->units()));
+ delayAsString(slack_threshold_, sta->units()));
// Reinsert vertices with slack < threshold.
queue_.clear();
VertexSeq::Iterator queue_iter2(vertices);
while (queue_iter2.hasNext()) {
Vertex *vertex = queue_iter2.next();
- Slack slack = search->wnsSlack(vertex, min_max_);
+ Slack slack = search->wnsSlack(vertex, path_ap_index);
if (delayFuzzyGreater(slack, slack_threshold_))
break;
queue_.insert(vertex);
}
max_queue_size_ = queue_.size() * 2;
Vertex *worst_slack_vertex = vertices[0];
- Slack worst_slack_slack = search->wnsSlack(worst_slack_vertex, min_max_);
- setWorstSlack(worst_slack_vertex, worst_slack_slack);
+ Slack worst_slack_slack = search->wnsSlack(worst_slack_vertex, path_ap_index);
+ setWorstSlack(worst_slack_vertex, worst_slack_slack, sta);
}
void
-WorstSlack::findWorstInQueue()
+WorstSlack::findWorstInQueue(PathAPIndex path_ap_index,
+ const StaState *sta)
{
- Search *search = sta_->search();
- const Debug *debug = sta_->debug();
+ Search *search = sta->search();
+ const Debug *debug = sta->debug();
debugPrint0(debug, "wns", 3, "find worst in queue\n");
worst_vertex_ = NULL;
@@ -288,29 +231,31 @@ WorstSlack::findWorstInQueue()
VertexSet::Iterator queue_iter(queue_);
while (queue_iter.hasNext()) {
Vertex *vertex = queue_iter.next();
- Slack slack = search->wnsSlack(vertex, min_max_);
+ Slack slack = search->wnsSlack(vertex, path_ap_index);
if (slack < worst_slack_)
- setWorstSlack(vertex, slack);
+ setWorstSlack(vertex, slack, sta);
}
}
void
-WorstSlack::checkQueue()
+WorstSlack::checkQueue(PathAPIndex path_ap_index,
+ const StaState *sta)
{
- Search *search = sta_->search();
- Report *report = sta_->report();
- Units *units = sta_->units();
- const Network *network = sta_->network();
+ Search *search = sta->search();
+ Report *report = sta->report();
+ Units *units = sta->units();
+ const Network *network = sta->network();
VertexSeq ends;
VertexSet::Iterator end_iter(search->endpoints());
while (end_iter.hasNext()) {
Vertex *end = end_iter.next();
- if (delayFuzzyLessEqual(search->wnsSlack(end, min_max_),
+ if (delayFuzzyLessEqual(search->wnsSlack(end, path_ap_index),
slack_threshold_))
ends.push_back(end);
}
- sort(ends, slack_less_);
+ WnsSlackLess slack_less(path_ap_index, sta);
+ sort(ends, slack_less);
VertexSet end_set;
VertexSeq::Iterator end_iter2(ends);
@@ -318,11 +263,11 @@ WorstSlack::checkQueue()
Vertex *end = end_iter2.next();
end_set.insert(end);
if (!queue_.hasKey(end)
- && delayFuzzyLessEqual(search->wnsSlack(end, min_max_),
+ && delayFuzzyLessEqual(search->wnsSlack(end, path_ap_index),
slack_threshold_))
report->print("WorstSlack queue missing %s %s < %s\n",
end->name(network),
- delayAsString(search->wnsSlack(end, min_max_), units),
+ delayAsString(search->wnsSlack(end, path_ap_index), units),
delayAsString(slack_threshold_, units));
}
@@ -332,7 +277,7 @@ WorstSlack::checkQueue()
if (!end_set.hasKey(end))
report->print("WorstSlack queue extra %s %s > %s\n",
end->name(network),
- delayAsString(search->wnsSlack(end, min_max_),
+ delayAsString(search->wnsSlack(end, path_ap_index),
units),
delayAsString(slack_threshold_, units));
}
@@ -340,18 +285,20 @@ WorstSlack::checkQueue()
void
WorstSlack::updateWorstSlack(Vertex *vertex,
- Slack *slacks)
+ SlackSeq &slacks,
+ PathAPIndex path_ap_index,
+ const StaState *sta)
{
- const Debug *debug = sta_->debug();
- const Network *network = sta_->network();
- Slack slack = slacks[min_max_->index()];
+ const Debug *debug = sta->debug();
+ const Network *network = sta->network();
+ Slack slack = slacks[path_ap_index];
- // Locking is required because ArrivalVisitor called by multiple
+ // Locking is required because ArrivalVisitor is called by multiple
// threads.
lock_.lock();
if (worst_vertex_
&& delayFuzzyLess(slack, worst_slack_))
- setWorstSlack(vertex, slack);
+ setWorstSlack(vertex, slack, sta);
else if (vertex == worst_vertex_)
// Mark worst slack as unknown (updated by findWorstSlack().
worst_vertex_ = NULL;
@@ -360,13 +307,13 @@ WorstSlack::updateWorstSlack(Vertex *vertex,
&& delayFuzzyLessEqual(slack, slack_threshold_)) {
debugPrint2(debug, "wns", 3, "insert %s %s\n",
vertex->name(network),
- delayAsString(slack, sta_->units()));
+ delayAsString(slack, sta->units()));
queue_.insert(vertex);
}
else {
debugPrint2(debug, "wns", 3, "delete %s %s\n",
vertex->name(network),
- delayAsString(slack, sta_->units()));
+ delayAsString(slack, sta->units()));
queue_.eraseKey(vertex);
}
lock_.unlock();
@@ -375,13 +322,31 @@ WorstSlack::updateWorstSlack(Vertex *vertex,
void
WorstSlack::setWorstSlack(Vertex *vertex,
- Slack slack)
+ Slack slack,
+ const StaState *sta)
{
- debugPrint2(sta_->debug(), "wns", 3, "%s %s\n",
- vertex->name(sta_->network()),
- delayAsString(slack, sta_->units()));
+ debugPrint2(sta->debug(), "wns", 3, "%s %s\n",
+ vertex->name(sta->network()),
+ delayAsString(slack, sta->units()));
worst_vertex_ = vertex;
worst_slack_ = slack;
}
+////////////////////////////////////////////////////////////////
+
+WnsSlackLess::WnsSlackLess(PathAPIndex path_ap_index,
+ const StaState *sta) :
+ path_ap_index_(path_ap_index),
+ search_(sta->search())
+{
+}
+
+bool
+WnsSlackLess::operator()(Vertex *vertex1,
+ Vertex *vertex2)
+{
+ return delayFuzzyLess(search_->wnsSlack(vertex1, path_ap_index_),
+ search_->wnsSlack(vertex2, path_ap_index_));
+}
+
} // namespace
diff --git a/search/WorstSlack.hh b/search/WorstSlack.hh
index a7bd4416..20a93e4b 100644
--- a/search/WorstSlack.hh
+++ b/search/WorstSlack.hh
@@ -20,25 +20,95 @@
namespace sta {
#include "MinMax.hh"
+#include "Vector.hh"
#include "GraphClass.hh"
+#include "SearchClass.hh"
class StaState;
class WorstSlack;
+class WnsSlackLess;
+
+typedef Vector WorstSlackSeq;
class WorstSlacks
{
public:
WorstSlacks(StaState *sta);
- ~WorstSlacks();
- void clear();
- Slack worstSlack(const MinMax *min_max);
- Vertex *worstSlackVertex(const MinMax *min_max);
+ void worstSlack(const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
+ void worstSlack(const Corner *corner,
+ const MinMax *min_max,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
void updateWorstSlacks(Vertex *vertex,
- Slack *slacks);
+ SlackSeq &slacks);
void worstSlackNotifyBefore(Vertex *vertex);
protected:
- WorstSlack *worst_slacks_[MinMax::index_count];
+ WorstSlackSeq worst_slacks_;
+ const StaState *sta_;
+};
+
+class WnsSlackLess
+{
+public:
+ WnsSlackLess(PathAPIndex path_ap_index,
+ const StaState *sta);
+ bool operator()(Vertex *vertex1,
+ Vertex *vertex2);
+
+private:
+ PathAPIndex path_ap_index_;
+ Search *search_;
+};
+
+class WorstSlack
+{
+public:
+ WorstSlack();
+ WorstSlack(const WorstSlack &);
+ void worstSlack(PathAPIndex path_ap_index,
+ const StaState *sta,
+ // Return values.
+ Slack &worst_slack,
+ Vertex *&worst_vertex);
+ void updateWorstSlack(Vertex *vertex,
+ SlackSeq &slacks,
+ PathAPIndex path_ap_index,
+ const StaState *sta);
+ void deleteVertexBefore(Vertex *vertex);
+
+protected:
+ void findWorstSlack(PathAPIndex path_ap_index,
+ const StaState *sta);
+ void initQueue(PathAPIndex path_ap_index,
+ const StaState *sta);
+ void findWorstInQueue(PathAPIndex path_ap_index,
+ const StaState *sta);
+ void setWorstSlack(Vertex *vertex,
+ Slack slack,
+ const StaState *sta);
+ void sortQueue(PathAPIndex path_ap_index,
+ const StaState *sta);
+ void checkQueue(PathAPIndex path_ap_index,
+ const StaState *sta);
+
+ Slack slack_init_;
+ // Vertex with the worst slack.
+ // When NULL the worst slack is unknown but in the queue.
+ Vertex *worst_vertex_;
+ Slack worst_slack_;
+ Slack slack_threshold_;
+ // Vertices with slack < threshold_
+ VertexSet queue_;
+ // Queue is sorted and pruned to min_queue_size_ vertices when it
+ // reaches max_queue_size_.
+ int min_queue_size_;
+ int max_queue_size_;
+ Mutex lock_;
};
} // namespace
diff --git a/tcl/Cmds.tcl b/tcl/Cmds.tcl
index 8ee51ec6..916b051e 100644
--- a/tcl/Cmds.tcl
+++ b/tcl/Cmds.tcl
@@ -1228,6 +1228,9 @@ proc get_ports_or_pins { pattern } {
################################################################
+# If -corner keyword is missing:
+# one corner, return default
+# multiple corner, error
proc parse_corner { keys_var } {
upvar 1 $keys_var keys
@@ -1246,6 +1249,23 @@ proc parse_corner { keys_var } {
}
}
+# Assumes caller checks for existence of -corner keyword arg.
+proc parse_corner_required { keys_var } {
+ upvar 1 $keys_var keys
+
+ if { [info exists keys(-corner)] } {
+ set corner_name $keys(-corner)
+ set corner [find_corner $corner_name]
+ if { $corner == "NULL" } {
+ sta_error "$corner_name is not the name of process corner."
+ } else {
+ return $corner
+ }
+ } else {
+ sta_error "missing -corner arg."
+ }
+}
+
proc parse_corner_or_default { keys_var } {
upvar 1 $keys_var keys
diff --git a/tcl/Search.tcl b/tcl/Search.tcl
index d0a55909..8c84c454 100644
--- a/tcl/Search.tcl
+++ b/tcl/Search.tcl
@@ -289,25 +289,39 @@ proc report_tag_arrivals { pin } {
################################################################
-define_hidden_cmd_args "total_negative_slack" {[-min]|[-max]}
+define_hidden_cmd_args "total_negative_slack" \
+ {[-corner corner] [-min]|[-max]}
proc total_negative_slack { args } {
- parse_key_args "total_negative_slack" args keys {} flags {-min -max}
+ parse_key_args "total_negative_slack" args \
+ keys {-corner} flags {-min -max}
check_argc_eq0 "total_negative_slack" $args
set min_max [parse_min_max_flags flags]
- set tns [total_negative_slack_cmd $min_max]
+ if { [info exists keys(-corner)] } {
+ set corner [parse_corner_required keys]
+ set tns [total_negative_slack_corner_cmd $corner $min_max]
+ } else {
+ set tns [total_negative_slack_cmd $min_max]
+ }
return [time_sta_ui $tns]
}
################################################################
-define_hidden_cmd_args "worst_negative_slack" {[-min]|[-max]}
+define_hidden_cmd_args "worst_negative_slack" \
+ {[-corner corner] [-min]|[-max]}
proc worst_negative_slack { args } {
- parse_key_args "total_negative_slack" args keys {} flags {-min -max}
+ parse_key_args "total_negative_slack" args \
+ keys {-corner} flags {-min -max}
check_argc_eq0 "worst_negative_slack" $args
set min_max [parse_min_max_flags flags]
- set worst_slack [worst_slack $min_max]
+ if { [info exists keys(-corner)] } {
+ set corner [parse_corner_required keys]
+ set worst_slack [worst_slack_corner $corner $min_max]
+ } else {
+ set worst_slack [worst_slack $min_max]
+ }
if { $worst_slack < 0.0 } {
return [time_sta_ui $worst_slack]
} else {
diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i
index a1d7ead3..73f84d4c 100644
--- a/tcl/StaTcl.i
+++ b/tcl/StaTcl.i
@@ -681,9 +681,9 @@ edgeDelayProperty(Edge *edge,
ArcDelay delay = 0.0;
bool delay_exists = false;
TimingArcSet *arc_set = edge->timingArcSet();
- TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator();
- while (arc_iter->hasNext()) {
- TimingArc *arc = arc_iter->next();
+ TimingArcSetArcIterator arc_iter(arc_set);
+ while (arc_iter.hasNext()) {
+ TimingArc *arc = arc_iter.next();
TransRiseFall *to_tr = arc->toTrans()->asRiseFall();
if (to_tr == tr) {
CornerIterator corner_iter(sta);
@@ -700,7 +700,6 @@ edgeDelayProperty(Edge *edge,
}
}
}
- delete arc_iter;
return sta->units()->timeUnit()->asString(delayAsFloat(delay), 8);
}
@@ -1747,7 +1746,7 @@ using namespace sta;
Tcl_SetObjResult(interp, obj);
}
-%typemap(out) CellTimingArcSetIterator* {
+%typemap(out) LibertyCellTimingArcSetIterator* {
Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
Tcl_SetObjResult(interp, obj);
}
@@ -1994,11 +1993,11 @@ private:
~TimingArcSet();
};
-class CellTimingArcSetIterator
+class LibertyCellTimingArcSetIterator
{
private:
- CellTimingArcSetIterator();
- ~CellTimingArcSetIterator();
+ LibertyCellTimingArcSetIterator();
+ ~LibertyCellTimingArcSetIterator();
};
class TimingArcSetArcIterator
@@ -4666,27 +4665,43 @@ find_delays()
}
Slack
-total_negative_slack_cmd(MinMax *min_max)
+total_negative_slack_cmd(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
return 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);
+}
+
Slack
worst_slack(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
- return sta->worstSlack(min_max);
+ Slack worst_slack;
+ Vertex *worst_vertex;
+ sta->worstSlack(min_max, worst_slack, worst_vertex);
+ return worst_slack;
}
-Vertex *
-worst_slack_vertex(const MinMax *min_max)
+Slack
+worst_slack_corner(const Corner *corner,
+ const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
- return sta->worstSlackVertex(min_max);
+ Slack worst_slack;
+ Vertex *worst_vertex;
+ sta->worstSlack(corner, min_max, worst_slack, worst_vertex);
+ return worst_slack;
}
PathRef *
@@ -5460,10 +5475,10 @@ find_liberty_ports_matching(const char *pattern,
}
LibertyCellPortIterator *
-liberty_port_iterator() { return self->libertyPortIterator(); }
+liberty_port_iterator() { return new LibertyCellPortIterator(self); }
-CellTimingArcSetIterator *
-timing_arc_set_iterator() { return self->timingArcSetIterator(); }
+LibertyCellTimingArcSetIterator *
+timing_arc_set_iterator() { return new LibertyCellTimingArcSetIterator(self); }
} // LibertyCell methods
@@ -5500,7 +5515,7 @@ Cell *cell() { return self->cell(); }
const char *object_name() { return self->name(); }
bool is_bus() { return self->isBus(); }
LibertyPortMemberIterator *
-member_iterator() { return self->libertyMemberIterator(); }
+member_iterator() { return new LibertyPortMemberIterator(self); }
const char *
direction() { return self->direction()->name(); }
@@ -5575,7 +5590,7 @@ object_name()
} // TimingArcSet methods
-%extend CellTimingArcSetIterator {
+%extend LibertyCellTimingArcSetIterator {
bool has_next() { return self->hasNext(); }
TimingArcSet *next() { return self->next(); }
void finish() { delete self; }
@@ -5908,7 +5923,7 @@ arrivals_clk(const TransRiseFall *tr,
return floats;
}
-StringSeq *
+TmpStringSeq *
arrivals_clk_delays(const TransRiseFall *tr,
Clock *clk,
const TransRiseFall *clk_tr,
@@ -5948,7 +5963,7 @@ requireds_clk(const TransRiseFall *tr,
return floats;
}
-StringSeq *
+TmpStringSeq *
requireds_clk_delays(const TransRiseFall *tr,
Clock *clk,
const TransRiseFall *clk_tr,
@@ -6002,7 +6017,7 @@ slacks_clk(const TransRiseFall *tr,
return floats;
}
-StringSeq *
+TmpStringSeq *
slacks_clk_delays(const TransRiseFall *tr,
Clock *clk,
const TransRiseFall *clk_tr,
@@ -6054,7 +6069,7 @@ Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); }
TimingRole *role() { return self->role(); }
const char *sense() { return timingSenseString(self->sense()); }
TimingArcSetArcIterator *
-timing_arc_iterator() { return self->timingArcSet()->timingArcIterator(); }
+timing_arc_iterator() { return new TimingArcSetArcIterator(self->timingArcSet()); }
bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); }
bool is_disabled_constraint() { return Sta::sta()->isDisabledConstraint(self);}
bool is_disabled_constant() { return Sta::sta()->isDisabledConstant(self); }
@@ -6084,7 +6099,7 @@ arc_delays(TimingArc *arc)
return floats;
}
-StringSeq *
+TmpStringSeq *
arc_delay_strings(TimingArc *arc,
int digits)
{
diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc
index 7049c45d..b1a306ac 100644
--- a/verilog/VerilogReader.cc
+++ b/verilog/VerilogReader.cc
@@ -560,9 +560,8 @@ VerilogReader::makeModuleInst(const char *module_name,
Port *port = network_->findPort(cell, port_name);
LibertyPort *lport = network_->libertyPort(port);
if (lport->isBus()) {
- LibertyPortMemberIterator *member_iter=lport->libertyMemberIterator();
- lport = member_iter->next();
- delete member_iter;
+ LibertyPortMemberIterator member_iter(lport);
+ lport = member_iter.next();
}
int pin_index = lport->pinIndex();
const char *prev_net_name = net_names[pin_index];
@@ -1969,9 +1968,9 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst,
Instance *inst = network_->makeInstance(cell, lib_inst->instanceName(),
parent);
const char **net_names = lib_inst->netNames();
- LibertyCellPortBitIterator *port_iter = lib_cell->libertyPortBitIterator();
- while (port_iter->hasNext()) {
- LibertyPort *port = port_iter->next();
+ LibertyCellPortBitIterator port_iter(lib_cell);
+ while (port_iter.hasNext()) {
+ LibertyPort *port = port_iter.next();
const char *net_name = net_names[port->pinIndex()];
// net_name may be the name of a single bit bus.
if (net_name) {
@@ -1997,7 +1996,6 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst,
&& lib_cell->hasTimingArcs(port))
network_->makePin(inst, reinterpret_cast(port), NULL);
}
- delete port_iter;
}
////////////////////////////////////////////////////////////////