This commit is contained in:
James Cherry 2018-12-05 14:18:41 -08:00
parent c3b1679bd7
commit f49dc75d32
51 changed files with 1109 additions and 1175 deletions

View File

@ -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"

View File

@ -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);
}

Binary file not shown.

Binary file not shown.

View File

@ -14,32 +14,20 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#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

View File

@ -14,14 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#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

View File

@ -14,16 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "config.h"
#include <cmath> // 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

View File

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

View File

@ -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

View File

@ -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<GateTimingModel*>(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;
}
}

View File

@ -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 *

View File

@ -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,

View File

@ -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<LibertyCell*>(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;
}
}

View File

@ -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<Library*> LibrarySet;
typedef Map<const char*, TableTemplate*, CharPtrLess> TableTemplateMap;
typedef TableTemplateMap::Iterator TableTemplateIterator;
typedef Map<const char*, BusDcl *, CharPtrLess> BusDclMap;
typedef Map<const char*, ScaleFactors*, CharPtrLess> ScaleFactorsMap;
typedef Map<const char*, Wireload*, CharPtrLess> WireloadMap;
typedef Map<const char*, WireloadSelection*, CharPtrLess> WireloadSelectionMap;
typedef Map<const char*, OperatingConditions*,
CharPtrLess> OperatingConditionsMap;
typedef OperatingConditionsMap::Iterator OperatingConditionsIterator;
typedef Map<LibertyPort*, Sequential*> PortToSequentialMap;
typedef Vector<TimingArcSet*> TimingArcSetSeq;
typedef TimingArcSetSeq::ConstIterator CellTimingArcSetIterator;
typedef Set<TimingArcSet*, TimingArcSetLess> TimingArcSetMap;
typedef Map<LibertyPortPair*, TimingArcSetSeq*,
LibertyPortPairLess> LibertyPortPairTimingArcMap;
typedef Vector<InternalPower*> InternalPowerSeq;
typedef InternalPowerSeq::Iterator LibertyCellInternalPowerIterator;
typedef Vector<LeakagePower*> LeakagePowerSeq;
typedef LeakagePowerSeq::Iterator LibertyCellLeakagePowerIterator;
typedef Map<LibertyPort*, TimingArcSetSeq*> LibertyPortTimingArcSetSeqMap;
typedef Map<const LibertyPort*, TimingArcSetSeq*> LibertyPortTimingArcMap;
typedef Map<const OperatingConditions*, LibertyCell*> ScaledCellMap;
typedef Map<const OperatingConditions*, LibertyPort*> ScaledPortMap;
typedef Map<const char *, ModeDef*, CharPtrLess> ModeDefMap;
typedef Map<const char *, ModeValueDef*, CharPtrLess> ModeValueMap;
typedef Map<TimingArcSet*, LatchEnable*> LatchEnableMap;
typedef Map<const char *, OcvDerate*, CharPtrLess> OcvDerateMap;
typedef Map<LibertyPortPair*, TimingArcSetSeq*,
LibertyPortPairLess> LibertyPortTimingArcSetMap;
typedef Vector<TimingArcAttrs*> TimingArcAttrsSeq;
typedef Vector<InternalPowerAttrs*> 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<LibertyCell*>
class LibertyCellIterator : public Iterator<LibertyCell*>
{
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<LibertyPort*>
@ -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,

View File

@ -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;

View File

@ -55,14 +55,14 @@ class TimingRole;
class Transition;
class TransRiseFall;
class TransRiseFallBoth;
class LibertyCellSequentialIterator;
typedef Vector<LibertyCell*> LibertyCellSeq;
typedef Vector<Sequential*> SequentialSeq;
typedef SequentialSeq::ConstIterator CellSequentialIterator;
typedef Map<LibertyCell*, LibertyCellSeq*> LibertyCellEquivMap;
typedef Vector<LibertyPort*> LibertyPortSeq;
typedef Set<LibertyPort*> LibertyPortSet;
typedef std::pair<LibertyPort*,LibertyPort*> LibertyPortPair;
typedef std::pair<const LibertyPort*,const LibertyPort*> LibertyPortPair;
typedef Set<LibertyCell*> LibertyCellSet;
typedef Vector<float> FloatSeq;
typedef Vector<FloatSeq*> FloatTable;

View File

@ -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<int>(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<int>(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();

View File

@ -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);

View File

@ -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)

View File

@ -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(),

View File

@ -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_;

View File

@ -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 &current_unit_; }
const Unit *currentUnit() const { return &current_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_;

View File

@ -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()

View File

@ -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());

View File

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

View File

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

View File

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

View File

@ -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,

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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),

View File

@ -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);

View File

@ -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();

View File

@ -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,

View File

@ -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.

View File

@ -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,

View File

@ -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_;

View File

@ -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<Slack>(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];
}
////////////////////////////////////////////////////////////////

View File

@ -59,6 +59,8 @@ typedef Set<ClkInfo*, ClkInfoLess> ClkInfoSet;
typedef HashSet<Tag*, TagHash, TagEqual> TagHashSet;
typedef HashSet<TagGroup*, TagGroupHash, TagGroupEqual> TagGroupSet;
typedef Map<Vertex*, Slack> VertexSlackMap;
typedef Vector<VertexSlackMap> VertexSlackMapSeq;
typedef Vector<WorstSlacks> 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_;

View File

@ -110,6 +110,7 @@ typedef Vector<Arrival> ArrivalSeq;
typedef Map<Vertex*, int> VertexPathCountMap;
typedef UnorderedMap<Tag*, int, TagMatchHash, TagMatchEqual> ArrivalMap;
typedef Vector<PathVertex> PathVertexSeq;
typedef Vector<Slack> SlackSeq;
typedef enum {
report_path_full,

View File

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

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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<WorstSlack> 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

View File

@ -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

View File

@ -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 {

View File

@ -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)
{

View File

@ -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*>(port), NULL);
}
delete port_iter;
}
////////////////////////////////////////////////////////////////