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

View File

@ -1769,7 +1769,10 @@ DmpCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
float float
DmpCeffDelayCalc::ceff() const 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. // Notify algorithm components.

View File

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

View File

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

View File

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

View File

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

View File

@ -32,12 +32,14 @@ public:
Delay(); Delay();
Delay(float mean); Delay(float mean);
Delay(float mean, Delay(float mean,
float sigma_early, float sigma2_early,
float sigma_late); float sigma2_late);
float mean() const { return mean_; } float mean() const { return mean_; }
float sigma(const EarlyLate *early_late) const; float sigma(const EarlyLate *early_late) const;
float sigmaEarly() const { return sigma_[early_index]; } // sigma^2
float sigmaLate() const { return sigma_[late_index]; } float sigma2(const EarlyLate *early_late) const;
float sigma2Early() const;
float sigma2Late() const;
void operator=(const Delay &delay); void operator=(const Delay &delay);
void operator=(float delay); void operator=(float delay);
void operator+=(const Delay &delay); void operator+=(const Delay &delay);
@ -60,19 +62,16 @@ protected:
private: private:
float mean_; float mean_;
float sigma_[EarlyLate::index_count]; // Sigma^2
float sigma2_[EarlyLate::index_count];
}; };
const Delay delay_zero(0.0); const Delay delay_zero(0.0);
inline Delay Delay
makeDelay(float delay, makeDelay(float delay,
float sigma_early, float sigma_early,
float sigma_late) float sigma_late);
{
return Delay(delay, sigma_early, sigma_late);
}
inline float inline float
delayAsFloat(const Delay &delay) { return delay.mean(); } 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 MinPulseWidthCheck::commonClkPessimism(const StaState *sta) const
{ {
Crpr *crpr = sta->search()->crpr(); CheckCrpr *check_crpr = sta->search()->checkCrpr();
PathVertex close; PathVertex close;
closePath(sta, close); closePath(sta, close);
if (!close.isNull()) if (!close.isNull())
return crpr->checkCrpr(openPath(), &close); return check_crpr->checkCrpr(openPath(), &close);
else else
return 0.0; return 0.0;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1229,8 +1229,8 @@ proc get_ports_or_pins { pattern } {
################################################################ ################################################################
# If -corner keyword is missing: # If -corner keyword is missing:
# one corner, return default # one corner: return default
# multiple corner, error # multiple corners: error
proc parse_corner { keys_var } { proc parse_corner { keys_var } {
upvar 1 $keys_var keys 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. # Assumes caller checks for existence of -corner keyword arg.
proc parse_corner_required { keys_var } { proc parse_corner_required { keys_var } {
upvar 1 $keys_var keys 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 switching [lindex $power_result [expr $index + 1]]
set leakage [lindex $power_result [expr $index + 2]] set leakage [lindex $power_result [expr $index + 2]]
set total [lindex $power_result [expr $index + 3]] 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] puts -nonewline [format "%-20s" $type]
report_power_col $internal $digits report_power_col $internal $digits
report_power_col $switching $digits report_power_col $switching $digits
@ -92,7 +96,12 @@ proc report_power_col { pwr digits } {
proc report_power_col_percent { power_result index } { proc report_power_col_percent { power_result index } {
set total [lindex $power_result 3] set total [lindex $power_result 3]
set col [lindex $power_result $index] 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 } { proc report_power_inst { inst corner digits } {

View File

@ -4798,6 +4798,7 @@ report_slew_limit_verbose(Pin *pin,
TmpFloatSeq * TmpFloatSeq *
design_power(const Corner *corner) design_power(const Corner *corner)
{ {
cmdLinkedNetwork();
PowerResult total, sequential, combinational, macro, pad; PowerResult total, sequential, combinational, macro, pad;
Sta::sta()->power(corner, total, sequential, combinational, macro, pad); Sta::sta()->power(corner, total, sequential, combinational, macro, pad);
FloatSeq *floats = new FloatSeq; FloatSeq *floats = new FloatSeq;
@ -4813,6 +4814,7 @@ TmpFloatSeq *
instance_power(Instance *inst, instance_power(Instance *inst,
const Corner *corner) const Corner *corner)
{ {
cmdLinkedNetwork();
PowerResult power; PowerResult power;
Sta::sta()->power(inst, corner, power); Sta::sta()->power(inst, corner, power);
FloatSeq *floats = new FloatSeq; FloatSeq *floats = new FloatSeq;
@ -6248,7 +6250,7 @@ float inter_clk_uncertainty()
Arrival target_clk_arrival() { return self->targetClkArrival(Sta::sta()); } Arrival target_clk_arrival() { return self->targetClkArrival(Sta::sta()); }
bool path_delay_margin_is_external() bool path_delay_margin_is_external()
{ return self->pathDelayMarginIsExternal();} { 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() TransRiseFall *target_clk_end_trans()
{ return const_cast<TransRiseFall*>(self->targetClkEndTrans(Sta::sta())); } { 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. # The value of the last expression in the body is returned.
proc proc_redirect { proc_name body } { proc proc_redirect { proc_name body } {
set proc_body [concat "proc $proc_name { args } {" \ set proc_body [concat "proc $proc_name { args } {" \
"global errorCode errorInfo;" \
"set redirect \[parse_redirect_args args\];" \ "set redirect \[parse_redirect_args args\];" \
"set code \[catch {" $body "} ret \];" \ "set code \[catch {" $body "} ret \];" \
"if {\$redirect} { redirect_file_end };" \ "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 eval $proc_body
} }