This commit is contained in:
James Cherry 2018-12-11 10:47:04 -08:00
parent f49dc75d32
commit d84c24882b
25 changed files with 337 additions and 227 deletions

22
INSTALL
View File

@ -18,25 +18,25 @@ Build requirements
------------------
Other versions may work, but these are the versions used for
developing the code.
development.
from Ubuntu Xcode
16.04 9.4
clang 9.1.0
lldb 902.0.79.7
gcc 3.3.2 5.4.0
18.04.1 10.1
clang 9.1.0 10.0.0
lldb 902.0.79.7 1000.11.38.2
gcc 3.3.2 7.3.0
tcl 8.2 8.6 8.6.6
autoconf 2.53 2.69 2.69
automake 1.6.3 1.15 1.16.1
automake 1.6.3 1.15.1 1.16.1
libtool 1.4.2 2.4.6 2.4.6
swig 1.3.28 3.0.8 3.0.12
bison 1.35 3.04 2.3
flex 2.5.4 2.6.0 2.5.35
swig 1.3.28 3.0.12 3.0.12
bison 1.35 3.0.4 2.3
flex 2.5.4 2.6.4 2.5.35
These packages are optional:
gdb 5.3 7.11 8.0
valgrind 1.9.6 3.11.0 N/A
gdb 5.3 8.1
valgrind 1.9.6 3.13.0 N/A
libz 1.1.4 1.2.5 1.2.8
cudd 2.4.1 2.5.0

View File

@ -1769,7 +1769,10 @@ DmpCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
float
DmpCeffDelayCalc::ceff() const
{
return static_cast<float>(dmp_alg_->ceff());
if (dmp_alg_)
return static_cast<float>(dmp_alg_->ceff());
else
return 0.0;
}
// Notify algorithm components.

View File

@ -45,6 +45,11 @@ Delay
makeDelay(float delay,
float sigma_early,
float sigma_late);
// sigma^2
Delay
makeDelay2(float delay,
float sigma2_early,
float sigma2_late);
float
delayAsFloat(const Delay &delay);
// mean late+/early- sigma
@ -54,6 +59,9 @@ delayAsFloat(const Delay &delay,
float
delaySigma(const Delay &delay,
const EarlyLate *early_late);
float
delaySigma2(const Delay &delay,
const EarlyLate *early_late);
const char *
delayAsString(const Delay &delay,
const Units *units);

View File

@ -178,5 +178,12 @@ delaySigma(const Delay &,
return 0.0;
}
float
delaySigma2(const Delay &,
const EarlyLate *)
{
return 0.0;
}
} // namespace
#endif

View File

@ -35,5 +35,13 @@ makeDelay(float delay,
return delay;
}
inline Delay
makeDelay2(float delay,
float,
float)
{
return delay;
}
} // namespace
#endif

View File

@ -29,7 +29,11 @@
namespace sta {
#define square(x) ((x)*(x))
inline float
square(float x)
{
return x * x;
}
static Delay delay_init_values[MinMax::index_count];
@ -48,54 +52,76 @@ delayInitValue(const MinMax *min_max)
Delay::Delay() :
mean_(0.0),
sigma_{0.0, 0.0}
sigma2_{0.0, 0.0}
{
}
Delay::Delay(float mean) :
mean_(mean),
sigma_{0.0, 0.0}
sigma2_{0.0, 0.0}
{
}
Delay::Delay(float mean,
float sigma_early,
float sigma_late) :
float sigma2_early,
float sigma2_late) :
mean_(mean),
sigma_{sigma_early, sigma_late}
sigma2_{sigma2_early, sigma2_late}
{
}
float
Delay::sigma(const EarlyLate *early_late) const
{
return sigma_[early_late->index()];
float sigma = sigma2_[early_late->index()];
if (sigma < 0.0)
// Sigma is negative for crpr to offset sigmas in the common
// clock path.
return -sqrt(-sigma);
else
return sqrt(sigma);
}
float
Delay::sigma2(const EarlyLate *early_late) const
{
return sigma2_[early_late->index()];
}
float
Delay::sigma2Early() const
{
return sigma2_[early_index];
}
float
Delay::sigma2Late() const
{
return sigma2_[late_index];
}
void
Delay::operator=(const Delay &delay)
{
mean_ = delay.mean_;
sigma_[early_index] = delay.sigma_[early_index];
sigma_[late_index] = delay.sigma_[late_index];
sigma2_[early_index] = delay.sigma2_[early_index];
sigma2_[late_index] = delay.sigma2_[late_index];
}
void
Delay::operator=(float delay)
{
mean_ = delay;
sigma_[early_index] = 0.0;
sigma_[late_index] = 0.0;
sigma2_[early_index] = 0.0;
sigma2_[late_index] = 0.0;
}
void
Delay::operator+=(const Delay &delay)
{
mean_ += delay.mean_;
sigma_[early_index] = sqrt(square(sigma_[early_index])
+ square(delay.sigma_[early_index]));
sigma_[late_index] = sqrt(square(sigma_[late_index])
+ square(delay.sigma_[late_index]));
sigma2_[early_index] += delay.sigma2_[early_index];
sigma2_[late_index] += delay.sigma2_[late_index];
}
void
@ -108,38 +134,34 @@ Delay
Delay::operator+(const Delay &delay) const
{
return Delay(mean_ + delay.mean_,
sqrt(square(sigma_[early_index])
+ square(delay.sigma_[early_index])),
sqrt(square(sigma_[late_index])
+ square(delay.sigma_[late_index])));
sigma2_[early_index] + delay.sigma2_[early_index],
sigma2_[late_index] + delay.sigma2_[late_index]);
}
Delay
Delay::operator+(float delay) const
{
return Delay(mean_ + delay, sigma_[early_index], sigma_[late_index]);
return Delay(mean_ + delay, sigma2_[early_index], sigma2_[late_index]);
}
Delay
Delay::operator-(const Delay &delay) const
{
return Delay(mean_ - delay.mean_,
sqrt(square(sigma_[early_index])
+ square(delay.sigma_[early_index])),
sqrt(square(sigma_[late_index])
+ square(delay.sigma_[late_index])));
sigma2_[early_index] + delay.sigma2_[early_index],
sigma2_[late_index] + delay.sigma2_[late_index]);
}
Delay
Delay::operator-(float delay) const
{
return Delay(mean_ - delay, sigma_[early_index], sigma_[late_index]);
return Delay(mean_ - delay, sigma2_[early_index], sigma2_[late_index]);
}
Delay
Delay::operator-() const
{
return Delay(-mean_, sigma_[early_index], sigma_[late_index]);
return Delay(-mean_, sigma2_[early_index], sigma2_[late_index]);
}
void
@ -152,8 +174,8 @@ bool
Delay::operator==(const Delay &delay) const
{
return mean_ == delay.mean_
&& sigma_[early_index] == delay.sigma_[early_index]
&& sigma_[late_index] == delay.sigma_[late_index];
&& sigma2_[early_index] == delay.sigma2_[early_index]
&& sigma2_[late_index] == delay.sigma2_[late_index];
}
bool
@ -180,21 +202,40 @@ Delay::operator<=(const Delay &delay) const
return mean_ <= delay.mean_;
}
////////////////////////////////////////////////////////////////
Delay
makeDelay(float delay,
float sigma_early,
float sigma_late)
{
return Delay(delay, square(sigma_early), square(sigma_late));
}
Delay
makeDelay2(float delay,
float sigma2_early,
float sigma2_late)
{
return Delay(delay, sigma2_early, sigma2_late);
}
bool
delayIsInitValue(const Delay &delay,
const MinMax *min_max)
{
return fuzzyEqual(delay.mean(), min_max->initValue())
&& delay.sigmaEarly() == 0.0
&& delay.sigmaLate() == 0.0;
&& delay.sigma2Early() == 0.0
&& delay.sigma2Late() == 0.0;
}
bool
delayFuzzyZero(const Delay &delay)
{
return fuzzyZero(delay.mean())
&& fuzzyZero(delay.sigmaEarly())
&& fuzzyZero(delay.sigmaLate());
// && fuzzyZero(delay.sigma2(EarlyLate::early()))
&& fuzzyZero(delay.sigma2Early())
&& fuzzyZero(delay.sigma2Late());
}
bool
@ -202,8 +243,8 @@ delayFuzzyEqual(const Delay &delay1,
const Delay &delay2)
{
return fuzzyEqual(delay1.mean(), delay2.mean())
&& fuzzyEqual(delay1.sigmaEarly(), delay2.sigmaEarly())
&& fuzzyEqual(delay1.sigmaLate(), delay2.sigmaLate());
&& fuzzyEqual(delay1.sigma2Early(), delay2.sigma2Early())
&& fuzzyEqual(delay1.sigma2Late(), delay2.sigma2Late());
}
bool
@ -311,8 +352,8 @@ operator+(float delay1,
const Delay &delay2)
{
return Delay(delay1 + delay2.mean(),
delay2.sigmaEarly(),
delay2.sigmaLate());
delay2.sigma2Early(),
delay2.sigma2Late());
}
Delay
@ -320,8 +361,8 @@ operator/(float delay1,
const Delay &delay2)
{
return Delay(delay1 / delay2.mean(),
delay2.sigmaEarly(),
delay2.sigmaLate());
delay2.sigma2Early(),
delay2.sigma2Late());
}
Delay
@ -329,8 +370,8 @@ operator*(const Delay &delay1,
float delay2)
{
return Delay(delay1.mean() * delay2,
delay1.sigmaEarly() * delay2,
delay1.sigmaLate() * delay2);
delay1.sigma2Early() * delay2,
delay1.sigma2Late() * delay2);
}
float
@ -345,9 +386,9 @@ delayAsFloat(const Delay &delay,
const EarlyLate *early_late)
{
if (early_late == EarlyLate::early())
return delay.mean() - delay.sigmaEarly();
return delay.mean() - delay.sigma(early_late);
else if (early_late == EarlyLate::late())
return delay.mean() + delay.sigmaLate();
return delay.mean() + delay.sigma(early_late);
else
internalError("unknown early/late value.");
}
@ -359,21 +400,28 @@ delaySigma(const Delay &delay,
return delay.sigma(early_late);
}
float
delaySigma2(const Delay &delay,
const EarlyLate *early_late)
{
return delay.sigma2(early_late);
}
const char *
delayAsString(const Delay &delay,
const Units *units,
int digits)
{
const Unit *unit = units->timeUnit();
float sigma_early = delay.sigmaEarly();
float sigma_late = delay.sigmaLate();
float sigma_early = delay.sigma(EarlyLate::early());
float sigma_late = delay.sigma(EarlyLate::late());
if (fuzzyEqual(sigma_early, sigma_late))
return stringPrintTmp((digits + 2) * 2 + 2,
return stringPrintTmp((digits + 4) * 2 + 2,
"%s|%s",
unit->asString(delay.mean(), digits),
unit->asString(sigma_early, digits));
else
return stringPrintTmp((digits + 2) * 3 + 3,
return stringPrintTmp((digits + 4) * 3 + 3,
"%s|%s:%s",
unit->asString(delay.mean(), digits),
unit->asString(sigma_early, digits),
@ -386,11 +434,7 @@ delayAsString(const Delay &delay,
const Units *units,
int digits)
{
float mean_sigma = delay.mean();
if (early_late == EarlyLate::early())
mean_sigma -= delay.sigmaEarly();
else if (early_late == EarlyLate::late())
mean_sigma += delay.sigmaLate();
float mean_sigma = delayAsFloat(delay, early_late);
return units->timeUnit()->asString(mean_sigma, digits);
}

View File

@ -32,12 +32,14 @@ public:
Delay();
Delay(float mean);
Delay(float mean,
float sigma_early,
float sigma_late);
float sigma2_early,
float sigma2_late);
float mean() const { return mean_; }
float sigma(const EarlyLate *early_late) const;
float sigmaEarly() const { return sigma_[early_index]; }
float sigmaLate() const { return sigma_[late_index]; }
// sigma^2
float sigma2(const EarlyLate *early_late) const;
float sigma2Early() const;
float sigma2Late() const;
void operator=(const Delay &delay);
void operator=(float delay);
void operator+=(const Delay &delay);
@ -60,19 +62,16 @@ protected:
private:
float mean_;
float sigma_[EarlyLate::index_count];
// Sigma^2
float sigma2_[EarlyLate::index_count];
};
const Delay delay_zero(0.0);
inline Delay
Delay
makeDelay(float delay,
float sigma_early,
float sigma_late)
{
return Delay(delay, sigma_early, sigma_late);
}
float sigma_late);
inline float
delayAsFloat(const Delay &delay) { return delay.mean(); }

View File

@ -459,14 +459,14 @@ minPulseWidth(const Path *path,
}
}
float
Crpr
MinPulseWidthCheck::commonClkPessimism(const StaState *sta) const
{
Crpr *crpr = sta->search()->crpr();
CheckCrpr *check_crpr = sta->search()->checkCrpr();
PathVertex close;
closePath(sta, close);
if (!close.isNull())
return crpr->checkCrpr(openPath(), &close);
return check_crpr->checkCrpr(openPath(), &close);
else
return 0.0;
}

View File

@ -85,7 +85,7 @@ public:
float closeOffset(const StaState *sta) const;
ClockEdge *openClkEdge(const StaState *sta) const;
ClockEdge *closeClkEdge(const StaState *sta) const;
float commonClkPessimism(const StaState *sta) const;
Crpr commonClkPessimism(const StaState *sta) const;
protected:
// Open path of the pulse.

View File

@ -51,7 +51,7 @@ public:
PathVertex *tgtPath() { return &tgt_path_; }
float srcLatency(StaState *sta);
float tgtLatency(StaState *sta);
float crpr(StaState *sta);
Crpr crpr(StaState *sta);
float skew() const { return skew_; }
private:
@ -73,7 +73,7 @@ ClkSkew::ClkSkew(PathVertex *src_path,
{
src_path_.copy(src_path);
tgt_path_.copy(tgt_path);
skew_ = srcLatency(sta) - tgtLatency(sta) - crpr(sta);
skew_ = srcLatency(sta) - tgtLatency(sta) - delayAsFloat(crpr(sta));
}
ClkSkew::ClkSkew(ClkSkew &clk_skew)
@ -103,11 +103,11 @@ ClkSkew::tgtLatency(StaState *sta)
return delayAsFloat(tgt_arrival) - tgt_path_.clkEdge(sta)->time();
}
float
Crpr
ClkSkew::crpr(StaState *sta)
{
Crpr *crpr = sta->search()->crpr();
return crpr->checkCrpr(&src_path_, &tgt_path_);
CheckCrpr *check_crpr = sta->search()->checkCrpr();
return check_crpr->checkCrpr(&src_path_, &tgt_path_);
}
////////////////////////////////////////////////////////////////
@ -155,7 +155,7 @@ ClkSkews::reportClkSkew(ClockSet *clks,
tgt_path->transition(this)->asString());
report_->print("%7s %7s %7s\n",
time_unit->asString(clk_skew->tgtLatency(this), digits),
time_unit->asString(-clk_skew->crpr(this), digits),
delayAsString(-clk_skew->crpr(this), units_, digits),
time_unit->asString(clk_skew->skew(), digits));
}
else
@ -281,7 +281,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex,
network_->pathName(tgt_path->pin(this)),
tgt_path->transition(this)->asString(),
time_unit->asString(probe.tgtLatency(this)),
time_unit->asString(probe.crpr(this)),
delayAsString(probe.crpr(this), this),
time_unit->asString(probe.skew()));
if (clk_skew == NULL) {
clk_skew = new ClkSkew(probe);

View File

@ -40,14 +40,14 @@ namespace sta {
using std::min;
using std::abs;
Crpr::Crpr(StaState *sta) :
CheckCrpr::CheckCrpr(StaState *sta) :
StaState(sta)
{
}
PathVertex *
Crpr::clkPathPrev(const PathVertex *path,
PathVertex &tmp)
CheckCrpr::clkPathPrev(const PathVertex *path,
PathVertex &tmp)
{
Vertex *vertex = path->vertex(this);
@ -58,9 +58,9 @@ Crpr::clkPathPrev(const PathVertex *path,
}
PathVertex *
Crpr::clkPathPrev(Vertex *vertex,
int arrival_index,
PathVertex &tmp)
CheckCrpr::clkPathPrev(Vertex *vertex,
int arrival_index,
PathVertex &tmp)
{
PathVertexRep *prevs = vertex->prevPaths();
if (prevs) {
@ -82,7 +82,7 @@ Crpr::clkPathPrev(Vertex *vertex,
// Find the maximum possible crpr (clock min/max delta delay) for a
// path from it's ClkInfo.
Arrival
Crpr::maxCrpr(ClkInfo *clk_info)
CheckCrpr::maxCrpr(ClkInfo *clk_info)
{
const PathVertexRep &crpr_clk_path = clk_info->crprClkPath();
if (!crpr_clk_path.isNull()) {
@ -98,7 +98,7 @@ Crpr::maxCrpr(ClkInfo *clk_info)
}
Arrival
Crpr::otherMinMaxArrival(const PathVertex *path)
CheckCrpr::otherMinMaxArrival(const PathVertex *path)
{
PathAnalysisPt *other_ap = path->pathAnalysisPt(this)->tgtClkAnalysisPt();
Tag *tag = path->tag(this);
@ -115,22 +115,22 @@ Crpr::otherMinMaxArrival(const PathVertex *path)
return path->arrival(this);
}
float
Crpr::checkCrpr(const Path *src_path,
const PathVertex *tgt_clk_path)
Crpr
CheckCrpr::checkCrpr(const Path *src_path,
const PathVertex *tgt_clk_path)
{
float crpr;
Crpr crpr;
Pin *crpr_pin;
checkCrpr(src_path, tgt_clk_path, crpr, crpr_pin);
return crpr;
}
void
Crpr::checkCrpr(const Path *src_path,
const PathVertex *tgt_clk_path,
// Return values.
float &crpr,
Pin *&crpr_pin)
CheckCrpr::checkCrpr(const Path *src_path,
const PathVertex *tgt_clk_path,
// Return values.
Crpr &crpr,
Pin *&crpr_pin)
{
crpr = 0.0;
crpr_pin = NULL;
@ -142,12 +142,12 @@ Crpr::checkCrpr(const Path *src_path,
}
void
Crpr::checkCrpr1(const Path *src_path,
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
float &crpr,
Pin *&crpr_pin)
CheckCrpr::checkCrpr1(const Path *src_path,
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
Crpr &crpr,
Pin *&crpr_pin)
{
crpr = 0.0;
crpr_pin = NULL;
@ -156,7 +156,8 @@ Crpr::checkCrpr1(const Path *src_path,
Clock *src_clk = src_clk_info->clock();
Clock *tgt_clk = tgt_clk_info->clock();
const PathVertex src_clk_path1(src_clk_info->crprClkPath(), this);
const PathVertex *src_clk_path = src_clk_path1.isNull() ? NULL : &src_clk_path1;
const PathVertex *src_clk_path =
src_clk_path1.isNull() ? NULL : &src_clk_path1;
const MinMax *src_clk_min_max =
src_clk_path ? src_clk_path->minMax(this) : src_path->minMax(this);
if (crprPossible(src_clk, tgt_clk)
@ -181,11 +182,11 @@ Crpr::checkCrpr1(const Path *src_path,
// Find the clk path for an input/output port.
void
Crpr::portClkPath(const ClockEdge *clk_edge,
const Pin *clk_src_pin,
const PathAnalysisPt *path_ap,
// Return value.
PathVertex &genclk_path)
CheckCrpr::portClkPath(const ClockEdge *clk_edge,
const Pin *clk_src_pin,
const PathAnalysisPt *path_ap,
// Return value.
PathVertex &genclk_path)
{
Vertex *clk_vertex = graph_->pinDrvrVertex(clk_src_pin);
VertexPathIterator path_iter(clk_vertex, clk_edge->transition(),
@ -201,12 +202,12 @@ Crpr::portClkPath(const ClockEdge *clk_edge,
}
void
Crpr::findCrpr(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
float &crpr,
Pin *&crpr_pin)
CheckCrpr::findCrpr(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
Crpr &crpr,
Pin *&crpr_pin)
{
crpr = 0.0;
crpr_pin = NULL;
@ -261,8 +262,8 @@ Crpr::findCrpr(const PathVertex *src_clk_path,
}
void
Crpr::genClkSrcPaths(const PathVertex *path,
PathVertexSeq &gclk_paths)
CheckCrpr::genClkSrcPaths(const PathVertex *path,
PathVertexSeq &gclk_paths)
{
ClkInfo *clk_info = path->clkInfo(this);
ClockEdge *clk_edge = clk_info->clkEdge();
@ -281,9 +282,24 @@ Crpr::genClkSrcPaths(const PathVertex *path,
}
}
float
Crpr::findCrpr1(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path)
#if SSTA
Crpr
CheckCrpr::findCrpr1(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path)
{
// Remove variation on the common path.
// Note that the crpr sigma is negative to offset the
// sigma of the common clock path.
const EarlyLate *src_el = src_clk_path->minMax(this);
const EarlyLate *tgt_el = tgt_clk_path->minMax(this);
float crpr_sigma2 = delaySigma2(src_clk_path->arrival(this), src_el)
+ delaySigma2(src_clk_path->arrival(this), tgt_el);
return makeDelay2(0.0, -crpr_sigma2, -crpr_sigma2);
}
#else
Crpr
CheckCrpr::findCrpr1(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path)
{
// The source and target edges are different so the crpr
// is the min of the source and target max-min delay.
@ -299,23 +315,24 @@ Crpr::findCrpr1(const PathVertex *src_clk_path,
delayAsString(common_delay, units_));
return common_delay;
}
#endif
float
Crpr::outputDelayCrpr(const Path *src_clk_path,
const ClockEdge *tgt_clk_edge)
Crpr
CheckCrpr::outputDelayCrpr(const Path *src_clk_path,
const ClockEdge *tgt_clk_edge)
{
float crpr;
Crpr crpr;
Pin *crpr_pin;
outputDelayCrpr(src_clk_path, tgt_clk_edge, crpr, crpr_pin);
return crpr;
}
void
Crpr::outputDelayCrpr(const Path *src_path,
const ClockEdge *tgt_clk_edge,
// Return values.
float &crpr,
Pin *&crpr_pin)
CheckCrpr::outputDelayCrpr(const Path *src_path,
const ClockEdge *tgt_clk_edge,
// Return values.
Crpr &crpr,
Pin *&crpr_pin)
{
crpr = 0.0;
crpr_pin = NULL;
@ -329,13 +346,13 @@ Crpr::outputDelayCrpr(const Path *src_path,
}
void
Crpr::outputDelayCrpr1(const Path *src_path,
const ClockEdge *tgt_clk_edge,
const PathAnalysisPt *tgt_path_ap,
bool same_pin,
// Return values.
float &crpr,
Pin *&crpr_pin)
CheckCrpr::outputDelayCrpr1(const Path *src_path,
const ClockEdge *tgt_clk_edge,
const PathAnalysisPt *tgt_path_ap,
bool same_pin,
// Return values.
Crpr &crpr,
Pin *&crpr_pin)
{
crpr = 0.0;
crpr_pin = NULL;
@ -354,8 +371,8 @@ Crpr::outputDelayCrpr1(const Path *src_path,
}
bool
Crpr::crprPossible(Clock *clk1,
Clock *clk2)
CheckCrpr::crprPossible(Clock *clk1,
Clock *clk2)
{
return clk1 && clk2
&& !clk1->isVirtual()
@ -369,7 +386,7 @@ Crpr::crprPossible(Clock *clk1,
}
float
Crpr::crprArrivalDiff(const PathVertex *path)
CheckCrpr::crprArrivalDiff(const PathVertex *path)
{
Arrival other_arrival = otherMinMaxArrival(path);
float crpr_diff = abs(delayAsFloat(path->arrival(this), EarlyLate::late())

View File

@ -27,28 +27,28 @@ namespace sta {
class CrprPaths;
// Clock Reconvergence Pessimism Removal.
class Crpr : public StaState
class CheckCrpr : public StaState
{
public:
explicit Crpr(StaState *sta);
explicit CheckCrpr(StaState *sta);
// Find the maximum possible crpr (clock min/max delta delay) for path.
Arrival maxCrpr(ClkInfo *clk_info);
// Timing check CRPR.
float checkCrpr(const Path *src_clk_path,
const PathVertex *tgt_clk_path);
Crpr checkCrpr(const Path *src_clk_path,
const PathVertex *tgt_clk_path);
void checkCrpr(const Path *src_path,
const PathVertex *tgt_clk_path,
// Return values.
float &crpr,
Crpr &crpr,
Pin *&crpr_pin);
// Output delay CRPR.
float outputDelayCrpr(const Path *src_clk_path,
const ClockEdge *tgt_clk_edge);
Crpr outputDelayCrpr(const Path *src_clk_path,
const ClockEdge *tgt_clk_edge);
void outputDelayCrpr(const Path *src_clk_path,
const ClockEdge *tgt_clk_edge,
// Return values.
float &crpr,
Crpr &crpr,
Pin *&crpr_pin);
// Previous clk path when crpr is enabled.
@ -65,14 +65,14 @@ private:
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
float &crpr,
Crpr &crpr,
Pin *&crpr_pin);
void outputDelayCrpr1(const Path *src_path,
const ClockEdge *tgt_clk_edge,
const PathAnalysisPt *tgt_path_ap,
bool same_pin,
// Return values.
float &crpr,
Crpr &crpr,
Pin *&crpr_pin);
bool crprPossible(Clock *clk1,
Clock *clk2);
@ -82,15 +82,15 @@ private:
const PathVertex *tgt_clk_path,
bool same_pin,
// Return values.
float &crpr,
Crpr &crpr,
Pin *&common_pin);
void portClkPath(const ClockEdge *clk_edge,
const Pin *clk_src_pin,
const PathAnalysisPt *path_ap,
// Return value.
PathVertex &port_clk_path);
float findCrpr1(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path);
Crpr findCrpr1(const PathVertex *src_clk_path,
const PathVertex *tgt_clk_path);
float crprArrivalDiff(const PathVertex *path);
};

View File

@ -68,7 +68,8 @@ Latches::latchRequired(const Path *data_path,
}
else if (enable_path && disable_path) {
Delay open_latency, latency_diff, max_borrow;
float nom_pulse_width, open_uncertainty, open_crpr, crpr_diff;
float nom_pulse_width, open_uncertainty;
Crpr open_crpr, crpr_diff;
bool borrow_limit_exists;
latchBorrowInfo(data_path, enable_path, disable_path, margin,
ignore_clk_latency,
@ -149,8 +150,8 @@ Latches::latchBorrowInfo(const Path *data_path,
Delay &open_latency,
Delay &latency_diff,
float &open_uncertainty,
float &open_crpr,
float &crpr_diff,
Crpr &open_crpr,
Crpr &crpr_diff,
Delay &max_borrow,
bool &borrow_limit_exists)
{
@ -169,14 +170,16 @@ Latches::latchBorrowInfo(const Path *data_path,
crpr_diff = 0.0;
}
else {
Crpr *crpr = search_->crpr();
open_crpr = crpr->checkCrpr(data_path, enable_path);
float close_crpr = crpr->checkCrpr(data_path, disable_path);
CheckCrpr *check_crpr = search_->checkCrpr();
open_crpr = check_crpr->checkCrpr(data_path, enable_path);
Crpr close_crpr = check_crpr->checkCrpr(data_path, disable_path);
crpr_diff = open_crpr - close_crpr;
open_latency = PathEnd::checkTgtClkDelay(enable_path, enable_clk_edge,
TimingRole::setup(), this);
Arrival close_latency = PathEnd::checkTgtClkDelay(disable_path, disable_clk_edge,
TimingRole::latchSetup(), this);
Arrival close_latency = PathEnd::checkTgtClkDelay(disable_path,
disable_clk_edge,
TimingRole::latchSetup(),
this);
latency_diff = open_latency - close_latency;
}
float borrow_limit;
@ -187,7 +190,7 @@ Latches::latchBorrowInfo(const Path *data_path,
max_borrow = borrow_limit;
else
max_borrow = nom_pulse_width - delayAsFloat(latency_diff)
- crpr_diff - delayAsFloat(margin);
- delayAsFloat(crpr_diff) - delayAsFloat(margin);
}
void

View File

@ -70,8 +70,8 @@ public:
Delay &open_latency,
Delay &latency_diff,
float &open_uncertainty,
float &open_crpr,
float &crpr_diff,
Crpr &open_crpr,
Crpr &crpr_diff,
Delay &max_borrow,
bool &borrow_limit_exists);
bool isLatchDtoQ(Edge *edge) const;

View File

@ -257,7 +257,7 @@ PathEnd::borrow(const StaState *) const
return 0.0;
}
float
Crpr
PathEnd::commonClkPessimism(const StaState *) const
{
return 0.0;
@ -535,7 +535,7 @@ PathEndClkConstrained::PathEndClkConstrained(Path *path,
PathEndClkConstrained::PathEndClkConstrained(Path *path,
PathVertex *clk_path,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEnd(path),
clk_path_(clk_path),
@ -730,12 +730,12 @@ PathEndClkConstrained::targetClkUncertainty(const StaState *sta) const
targetClkPath(), checkRole(sta), sta);
}
float
Crpr
PathEndClkConstrained::commonClkPessimism(const StaState *sta) const
{
if (!crpr_valid_) {
Crpr *crpr = sta->search()->crpr();
crpr_ = crpr->checkCrpr(path_.path(), targetClkPath());
CheckCrpr *check_crpr = sta->search()->checkCrpr();
crpr_ = check_crpr->checkCrpr(path_.path(), targetClkPath());
if (checkRole(sta)->genericRole() == TimingRole::hold())
crpr_ = -crpr_;
crpr_valid_ = true;
@ -800,7 +800,7 @@ PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path,
PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrained(path, clk_path, crpr, crpr_valid),
mcp_(mcp)
@ -979,7 +979,7 @@ PathEndCheck::PathEndCheck(Path *path,
Edge *check_edge,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrainedMcp(path, clk_path, mcp, crpr, crpr_valid),
check_arc_(check_arc),
@ -1081,7 +1081,7 @@ PathEndLatchCheck::PathEndLatchCheck(Path *path,
MultiCyclePath *mcp,
PathDelay *path_delay,
Delay src_clk_arrival,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndCheck(path, check_arc, check_edge, clk_path, mcp, crpr, crpr_valid),
disable_path_(disable_path),
@ -1208,8 +1208,8 @@ PathEndLatchCheck::latchBorrowInfo(const StaState *sta,
Delay &open_latency,
Delay &latency_diff,
float &open_uncertainty,
float &open_crpr,
float &crpr_diff,
Crpr &open_crpr,
Crpr &crpr_diff,
Delay &max_borrow,
bool &borrow_limit_exists) const
{
@ -1280,7 +1280,7 @@ PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay,
Path *path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrainedMcp(path, clk_path, mcp, crpr, crpr_valid),
output_delay_(output_delay)
@ -1367,12 +1367,12 @@ PathEndOutputDelay::targetClkArrivalNoCrpr(const StaState *sta) const
}
}
float
Crpr
PathEndOutputDelay::commonClkPessimism(const StaState *sta) const
{
if (!crpr_valid_) {
Crpr *crpr = sta->search()->crpr();
crpr_ = crpr->outputDelayCrpr(path_.path(), targetClkEdge(sta));
CheckCrpr *check_crpr = sta->search()->checkCrpr();
crpr_ = check_crpr->outputDelayCrpr(path_.path(), targetClkEdge(sta));
if (checkRole(sta)->genericRole() == TimingRole::hold())
crpr_ = -crpr_;
}
@ -1482,7 +1482,7 @@ PathEndGatedClock::PathEndGatedClock(Path *gating_ref,
TimingRole *check_role,
MultiCyclePath *mcp,
ArcDelay margin,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrainedMcp(gating_ref, clk_path, mcp, crpr, crpr_valid),
check_role_(check_role),
@ -1562,7 +1562,7 @@ PathEndDataCheck::PathEndDataCheck(DataCheck *check,
PathVertex *data_clk_path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrainedMcp(data_path, clk_path, mcp, crpr, crpr_valid),
data_clk_path_(data_clk_path),
@ -1705,7 +1705,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay,
Edge *check_edge,
OutputDelay *output_delay,
Arrival src_clk_arrival,
float crpr,
Crpr crpr,
bool crpr_valid) :
PathEndClkConstrained(path, clk_path, crpr, crpr_valid),
path_delay_(path_delay),

View File

@ -138,7 +138,7 @@ public:
const TimingRole *checkGenericRole(const StaState *sta) const;
virtual bool pathDelayMarginIsExternal() const;
virtual PathDelay *pathDelay() const;
virtual float commonClkPessimism(const StaState *sta) const;
virtual Crpr commonClkPessimism(const StaState *sta) const;
virtual MultiCyclePath *multiCyclePath() const;
virtual TimingArc *checkArc() const { return NULL; }
// PathEndDataCheck data clock path.
@ -255,7 +255,7 @@ public:
virtual float targetNonInterClkUncertainty(const StaState *sta) const;
virtual float interClkUncertainty(const StaState *sta) const;
virtual float targetClkUncertainty(const StaState *sta) const;
virtual float commonClkPessimism(const StaState *sta) const;
virtual Crpr commonClkPessimism(const StaState *sta) const;
virtual Required requiredTime(const StaState *sta) const;
virtual Slack slack(const StaState *sta) const;
virtual Slack slackNoCrpr(const StaState *sta) const;
@ -269,7 +269,7 @@ protected:
PathVertex *clk_path);
PathEndClkConstrained(Path *path,
PathVertex *clk_path,
float crpr,
Crpr crpr,
bool crpr_valid);
float sourceClkOffset(const ClockEdge *src_clk_edge,
@ -281,7 +281,7 @@ protected:
virtual Required requiredTimeNoCrpr(const StaState *sta) const;
PathVertex clk_path_;
mutable float crpr_;
mutable Crpr crpr_;
mutable bool crpr_valid_;
private:
@ -303,7 +303,7 @@ protected:
PathEndClkConstrainedMcp(Path *path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid);
float checkMcpAdjustment(const Path *path,
const ClockEdge *tgt_clk_edge,
@ -346,7 +346,7 @@ protected:
Edge *check_edge,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid);
TimingArc *check_arc_;
@ -397,8 +397,8 @@ public:
Delay &open_latency,
Delay &latency_diff,
float &open_uncertainty,
float &open_crpr,
float &crpr_diff,
Crpr &open_crpr,
Crpr &crpr_diff,
Delay &max_borrow,
bool &borrow_limit_exists) const;
@ -411,7 +411,7 @@ protected:
MultiCyclePath *mcp,
PathDelay *path_delay,
Delay src_clk_arrival,
float crpr,
Crpr crpr,
bool crpr_valid);
private:
@ -446,7 +446,7 @@ public:
virtual Arrival targetClkArrivalNoCrpr(const StaState *sta) const;
virtual Delay targetClkDelay(const StaState *sta) const;
virtual Delay targetClkInsertionDelay(const StaState *sta) const;
virtual float commonClkPessimism(const StaState *sta) const;
virtual Crpr commonClkPessimism(const StaState *sta) const;
virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const;
@ -455,7 +455,7 @@ protected:
Path *path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid);
Arrival tgtClkDelay(const ClockEdge *tgt_clk_edge,
const TimingRole *check_role,
@ -501,7 +501,7 @@ protected:
TimingRole *check_role,
MultiCyclePath *mcp,
ArcDelay margin,
float crpr,
Crpr crpr,
bool crpr_valid);
TimingRole *check_role_;
@ -538,7 +538,7 @@ protected:
PathVertex *data_clk_path,
PathVertex *clk_path,
MultiCyclePath *mcp,
float crpr,
Crpr crpr,
bool crpr_valid);
Arrival requiredTimeNoCrpr(const StaState *sta) const;
@ -599,7 +599,7 @@ protected:
Edge *check_edge,
OutputDelay *output_delay,
Arrival src_clk_arrival,
float crpr,
Crpr crpr,
bool crpr_valid);
void findSrcClkArrival(const StaState *sta);

View File

@ -188,7 +188,8 @@ Power::findInternalPower(const Instance *inst,
while (tr_iter.hasNext()) {
TransRiseFall *to_tr = tr_iter.next();
// Need unateness to find from_tr.
float slew = delayAsFloat(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);
@ -237,7 +238,10 @@ Power::loadCap(const Pin *to_pin,
ceff_count++;
}
}
return ceff_sum / ceff_count;
if (ceff_count == 0)
return 0.0;
else
return ceff_sum / ceff_count;
}
void
@ -289,14 +293,16 @@ Power::activity(const Pin *pin,
{
const Clock *clk;
findClk(pin, clk, is_clk);
activity = 0.0;
if (clk) {
if (is_clk)
activity = 2.0 / clk->period();
else
activity = default_signal_toggle_rate_ * 2.0 / clk->period();
float period = clk->period();
if (period > 0.0) {
if (is_clk)
activity = 2.0 / period;
else
activity = default_signal_toggle_rate_ * 2.0 / period;
}
}
else
activity = 0.0;
}
float

View File

@ -634,7 +634,8 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end,
string &result)
{
Delay open_latency, latency_diff, max_borrow;
float nom_pulse_width, open_uncertainty, open_crpr, crpr_diff;
float nom_pulse_width, open_uncertainty;
Crpr open_crpr, crpr_diff;
bool borrow_limit_exists;
const EarlyLate *early_late = EarlyLate::late();
end->latchBorrowInfo(this, nom_pulse_width, open_latency, latency_diff,
@ -668,19 +669,19 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end,
ArcDelay margin = end->margin(this);
reportLineTotalMinus("library setup time", margin, early_late, result);
reportDashLineTotal(result);
if (!fuzzyZero(crpr_diff))
if (!delayFuzzyZero(crpr_diff))
reportLineTotalMinus("CRPR difference", crpr_diff, early_late, result);
reportLineTotal("max time borrow", max_borrow, early_late, result);
}
if (delayFuzzyGreater(borrow, delay_zero)
&& (!fuzzyZero(open_uncertainty)
|| !fuzzyZero(open_crpr))) {
|| !delayFuzzyZero(open_crpr))) {
reportDashLineTotal(result);
reportLineTotal("actual time borrow", borrow, early_late, result);
if (!fuzzyZero(open_uncertainty))
reportLineTotal("open edge uncertainty", open_uncertainty,
early_late, result);
if (!fuzzyZero(open_crpr))
if (!delayFuzzyZero(open_crpr))
reportLineTotal("open edge CRPR", open_crpr, early_late, result);
reportDashLineTotal(result);
reportLineTotal("time given to startpoint", time_given_to_startpoint,
@ -1307,7 +1308,7 @@ ReportPath::reportVerbose(MinPulseWidthCheck *check,
reportLine(pin_name, delay_zero, close_arrival, close_el, result);
if (sdc_->crprEnabled()) {
float pessimism = check->commonClkPessimism(this);
Crpr pessimism = check->commonClkPessimism(this);
close_arrival += pessimism;
reportLine("clock reconvergence pessimism", pessimism, close_arrival,
close_el, result);
@ -2512,7 +2513,7 @@ ReportPath::reportCommonClkPessimism(const PathEnd *end,
string &result)
{
if (sdc_->crprEnabled()) {
float pessimism = end->commonClkPessimism(this);
Crpr pessimism = end->commonClkPessimism(this);
clk_arrival += pessimism;
reportLine("clock reconvergence pessimism", pessimism, clk_arrival,
end->clkEarlyLate(this), result);

View File

@ -231,7 +231,7 @@ Search::init(StaState *sta)
report_unconstrained_paths_ = false;
search_adj_ = new SearchThru(NULL, sta);
eval_pred_ = new EvalPred(sta);
crpr_ = new Crpr(sta);
check_crpr_ = new CheckCrpr(sta);
genclks_ = new Genclks(sta);
arrival_visitor_ = new ArrivalVisitor(sta);
clk_arrivals_valid_ = false;
@ -284,7 +284,7 @@ Search::~Search()
delete visit_path_ends_;
delete gated_clk_;
delete worst_slacks_;
delete crpr_;
delete check_crpr_;
delete genclks_;
deleteFilter();
deletePathGroups();
@ -379,7 +379,7 @@ Search::copyState(const StaState *sta)
required_iter_->copyState(sta);
visit_path_ends_->copyState(sta);
gated_clk_->copyState(sta);
crpr_->copyState(sta);
check_crpr_->copyState(sta);
genclks_->copyState(sta);
}
@ -1300,7 +1300,7 @@ ArrivalVisitor::pruneCrprArrivals()
{
const Debug *debug = sta_->debug();
ArrivalMap::Iterator arrival_iter(tag_bldr_->arrivalMap());
Crpr *crpr = sta_->search()->crpr();
CheckCrpr *crpr = sta_->search()->checkCrpr();
while (arrival_iter.hasNext()) {
Tag *tag;
int arrival_index;
@ -2813,7 +2813,7 @@ Search::reportArrivals(Vertex *vertex) const
report_->print(" %s", tag->asString(this));
if (tag_group->hasClkTag()) {
PathVertex tmp;
PathVertex *prev = crpr_->clkPathPrev(vertex, arrival_index, tmp);
PathVertex *prev = check_crpr_->clkPathPrev(vertex, arrival_index, tmp);
report_->print(" clk_prev=[%s]",
prev && !prev->isNull() ? prev->name(this) : "NULL");
}

View File

@ -51,7 +51,7 @@ class WorstSlacks;
class DcalcAnalysisPt;
class VisitPathEnds;
class GatedClk;
class Crpr;
class CheckCrpr;
class Genclks;
class Corner;
@ -339,7 +339,7 @@ public:
virtual bool checkDefaultArrivalPaths() { return true; }
bool matchesFilter(Path *path,
const ClockEdge *to_clk_edge);
Crpr *crpr() { return crpr_; }
CheckCrpr *checkCrpr() { return check_crpr_; }
VisitPathEnds *visitPathEnds() { return visit_path_ends_; }
GatedClk *gatedClk() { return gated_clk_; }
Genclks *genclks() { return genclks_; }
@ -592,7 +592,7 @@ protected:
PathGroups *path_groups_;
VisitPathEnds *visit_path_ends_;
GatedClk *gated_clk_;
Crpr *crpr_;
CheckCrpr *check_crpr_;
bool crpr_path_pruning_enabled_;
Genclks *genclks_;
};

View File

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

View File

@ -1229,8 +1229,8 @@ proc get_ports_or_pins { pattern } {
################################################################
# If -corner keyword is missing:
# one corner, return default
# multiple corner, error
# one corner: return default
# multiple corners: error
proc parse_corner { keys_var } {
upvar 1 $keys_var keys
@ -1249,6 +1249,7 @@ proc parse_corner { keys_var } {
}
}
# -corner keyword is required.
# Assumes caller checks for existence of -corner keyword arg.
proc parse_corner_required { keys_var } {
upvar 1 $keys_var keys

View File

@ -76,7 +76,11 @@ proc report_power_row { type power_result index design_total digits } {
set switching [lindex $power_result [expr $index + 1]]
set leakage [lindex $power_result [expr $index + 2]]
set total [lindex $power_result [expr $index + 3]]
set percent [expr $total / $design_total * 100]
if { $design_total == 0.0 } {
set percent 0.0
} else {
set percent [expr $total / $design_total * 100]
}
puts -nonewline [format "%-20s" $type]
report_power_col $internal $digits
report_power_col $switching $digits
@ -92,7 +96,12 @@ proc report_power_col { pwr digits } {
proc report_power_col_percent { power_result index } {
set total [lindex $power_result 3]
set col [lindex $power_result $index]
puts -nonewline [format "%9.1f%%" [expr $col / $total * 100]]
if { $total == 0.0 } {
set percent 0.0
} else {
set percent [expr $col / $total * 100]
}
puts -nonewline [format "%9.1f%%" $percent]
}
proc report_power_inst { inst corner digits } {

View File

@ -4798,6 +4798,7 @@ report_slew_limit_verbose(Pin *pin,
TmpFloatSeq *
design_power(const Corner *corner)
{
cmdLinkedNetwork();
PowerResult total, sequential, combinational, macro, pad;
Sta::sta()->power(corner, total, sequential, combinational, macro, pad);
FloatSeq *floats = new FloatSeq;
@ -4813,6 +4814,7 @@ TmpFloatSeq *
instance_power(Instance *inst,
const Corner *corner)
{
cmdLinkedNetwork();
PowerResult power;
Sta::sta()->power(inst, corner, power);
FloatSeq *floats = new FloatSeq;
@ -6248,7 +6250,7 @@ float inter_clk_uncertainty()
Arrival target_clk_arrival() { return self->targetClkArrival(Sta::sta()); }
bool path_delay_margin_is_external()
{ return self->pathDelayMarginIsExternal();}
float common_clk_pessimism() { return self->commonClkPessimism(Sta::sta()); }
Crpr common_clk_pessimism() { return self->commonClkPessimism(Sta::sta()); }
TransRiseFall *target_clk_end_trans()
{ return const_cast<TransRiseFall*>(self->targetClkEndTrans(Sta::sta())); }

View File

@ -116,10 +116,11 @@ proc is_keyword_arg { arg } {
# The value of the last expression in the body is returned.
proc proc_redirect { proc_name body } {
set proc_body [concat "proc $proc_name { args } {" \
"global errorCode errorInfo;" \
"set redirect \[parse_redirect_args args\];" \
"set code \[catch {" $body "} ret \];" \
"if {\$redirect} { redirect_file_end };" \
"if {\$code == 1} {error \$ret} else {return \$ret} }" ]
"if {\$code != 0} {return -code error -errorcode \$errorCode -errorinfo \$errorInfo} else {return \$ret} }" ]
eval $proc_body
}