power ideal clock slews

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2021-10-27 18:50:43 -07:00
parent cd593bb88f
commit 28ce2c1d45
7 changed files with 42 additions and 34 deletions

View File

@ -1376,28 +1376,12 @@ GraphDelayCalc1::edgeFromSlew(const Vertex *from_vertex,
const TimingRole *role = edge->role();
if (role->genericRole() == TimingRole::regClkToQ()
&& clk_network_->isIdealClock(from_vertex->pin()))
return idealClkSlew(from_vertex, from_rf, dcalc_ap->slewMinMax());
return clk_network_->idealClkSlew(from_vertex->pin(), from_rf,
dcalc_ap->slewMinMax());
else
return graph_->slew(from_vertex, from_rf, dcalc_ap->index());
}
Slew
GraphDelayCalc1::idealClkSlew(const Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max)
{
float slew = min_max->initValue();
const ClockSet *clks = clk_network_->idealClocks(vertex->pin());
ClockSet::ConstIterator clk_iter(clks);
while (clk_iter.hasNext()) {
Clock *clk = clk_iter.next();
float clk_slew = clk->slew(rf, min_max);
if (min_max->compare(clk_slew, slew))
slew = clk_slew;
}
return slew;
}
// Annotate wire arc delays and load pin slews.
// extra_delay is additional wire delay to add to delay returned
// by the delay calculator.
@ -1574,7 +1558,8 @@ GraphDelayCalc1::checkEdgeClkSlew(const Vertex *from_vertex,
const DcalcAnalysisPt *dcalc_ap)
{
if (clk_network_->isIdealClock(from_vertex->pin()))
return idealClkSlew(from_vertex, from_rf, dcalc_ap->checkClkSlewMinMax());
return clk_network_->idealClkSlew(from_vertex->pin(), from_rf,
dcalc_ap->checkClkSlewMinMax());
else
return graph_->slew(from_vertex, from_rf, dcalc_ap->checkClkSlewIndex());
}

View File

@ -194,9 +194,6 @@ protected:
const RiseFall *from_rf,
const DcalcAnalysisPt *dcalc_ap);
bool bidirectDrvrSlewFromLoad(const Vertex *vertex) const;
Slew idealClkSlew(const Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
MultiDrvrNet *multiDrvrNet(const Vertex *drvr_vertex) const;
void loadCap(Parasitic *drvr_parasitic,
bool has_set_load,

View File

@ -46,6 +46,9 @@ public:
const ClockSet *idealClocks(const Pin *pin);
const PinSet *pins(const Clock *clk);
void clkPinsInvalid();
float idealClkSlew(const Pin *pin,
const RiseFall *rf,
const MinMax *min_max);
protected:
void deletePinBefore(const Pin *pin);

View File

@ -52,8 +52,7 @@ public:
// Invalidate all delays/slews.
virtual void delaysInvalid() {};
// Invalidate vertex and downstream delays/slews.
virtual void delayInvalid(Vertex * /* vertex */) {}
;
virtual void delayInvalid(Vertex * /* vertex */) {};
virtual void delayInvalid(const Pin * /* pin */) {};
virtual void deleteVertexBefore(Vertex * /* vertex */) {};
// Reset to virgin state.

View File

@ -202,4 +202,25 @@ ClkNetwork::pins(const Clock *clk)
return nullptr;
}
float
ClkNetwork::idealClkSlew(const Pin *pin,
const RiseFall *rf,
const MinMax *min_max)
{
const ClockSet *clks = clk_network_->idealClocks(pin);
if (clks && !clks->empty()) {
float slew = min_max->initValue();
ClockSet::ConstIterator clk_iter(clks);
while (clk_iter.hasNext()) {
Clock *clk = clk_iter.next();
float clk_slew = clk->slew(rf, min_max);
if (min_max->compare(clk_slew, slew))
slew = clk_slew;
}
return slew;
}
else
return 0.0;
}
} // namespace

View File

@ -45,6 +45,7 @@
#include "Sim.hh"
#include "Search.hh"
#include "Bfs.hh"
#include "ClkNetwork.hh"
// Related liberty not supported:
// library
@ -648,18 +649,19 @@ Power::findInputInternalPower(const Pin *pin,
for (InternalPower *pwr : *internal_pwrs) {
const char *related_pg_pin = pwr->relatedPgPin();
float energy = 0.0;
int tr_count = 0;
int rf_count = 0;
for (RiseFall *rf : RiseFall::range()) {
float slew = delayAsFloat(graph_->slew(vertex, rf,
dcalc_ap->index()));
float slew = clk_network_->isIdealClock(pin)
? clk_network_->idealClkSlew(pin, rf, MinMax::max())
: delayAsFloat(graph_->slew(vertex, rf, dcalc_ap->index()));
if (!delayInf(slew)) {
float table_energy = pwr->power(rf, pvt, slew, load_cap);
energy += table_energy;
tr_count++;
rf_count++;
}
}
if (tr_count)
energy /= tr_count; // average non-inf energies
if (rf_count)
energy /= rf_count; // average non-inf energies
float duty = 1.0; // fallback default
FuncExpr *when = pwr->when();
if (when) {
@ -787,7 +789,7 @@ Power::findOutputInternalPower(const Pin *to_pin,
}
}
float energy = 0.0;
int tr_count = 0;
int rf_count = 0;
debugPrint(debug_, "power", 2,
" when act/ns duty wgt energy power");
for (RiseFall *to_rf : RiseFall::range()) {
@ -800,11 +802,11 @@ Power::findOutputInternalPower(const Pin *to_pin,
if (!delayInf(slew)) {
float table_energy = pwr->power(to_rf, pvt, slew, load_cap);
energy += table_energy;
tr_count++;
rf_count++;
}
}
if (tr_count)
energy /= tr_count; // average non-inf energies
if (rf_count)
energy /= rf_count; // average non-inf energies
auto duty_sum_iter = pg_duty_sum.find(related_pg_pin);
float weight = 0.0;
if (duty_sum_iter != pg_duty_sum.end()) {

View File

@ -5453,6 +5453,7 @@ Sta::powerPreamble()
// Use arrivals to find clocking info.
searchPreamble();
search_->findAllArrivals();
ensureClkNetwork();
}
void