sync
This commit is contained in:
parent
f49dc75d32
commit
d84c24882b
22
INSTALL
22
INSTALL
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -178,5 +178,12 @@ delaySigma(const Delay &,
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
float
|
||||
delaySigma2(const Delay &,
|
||||
const EarlyLate *)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,5 +35,13 @@ makeDelay(float delay,
|
|||
return delay;
|
||||
}
|
||||
|
||||
inline Delay
|
||||
makeDelay2(float delay,
|
||||
float,
|
||||
float)
|
||||
{
|
||||
return delay;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
135
search/Crpr.cc
135
search/Crpr.cc
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 } {
|
||||
|
|
|
|||
|
|
@ -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())); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue