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; } ////////////////////////////////////////////////////////////////