LibertyCell::internalPowers(port)

This commit is contained in:
James Cherry 2020-04-06 18:27:40 -07:00
parent 958a8577e5
commit 1d3ae30600
4 changed files with 92 additions and 94 deletions

View File

@ -20,6 +20,11 @@ Release 2.1.0 2020/04/05
All public headers files have been moved to include/sta.
The following iterators have been removed.
Use range iteration on the returned collection shown next to them instead.
LibertyCellInternalPowerIterator cell->internalPowers()
LibertyCellLeakagePowerIterator cell->leakagePowers()
Release 2.0.18 2020/02/15
-------------------------

View File

@ -58,6 +58,7 @@ typedef Set<TimingArcSet*, TimingArcSetLess> TimingArcSetMap;
typedef Map<LibertyPortPair, TimingArcSetSeq*,
LibertyPortPairLess> LibertyPortPairTimingArcMap;
typedef Vector<InternalPower*> InternalPowerSeq;
typedef Map<const LibertyPort *, InternalPowerSeq> PortInternalPowerSeq;
typedef Vector<LeakagePower*> LeakagePowerSeq;
typedef Map<const LibertyPort*, TimingArcSetSeq*> LibertyPortTimingArcMap;
typedef Map<const OperatingConditions*, LibertyCell*> ScaledCellMap;
@ -419,12 +420,13 @@ public:
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
bool hasTimingArcs(LibertyPort *port) const;
InternalPowerSeq *internalPowers() { return &internal_powers_; }
InternalPowerSeq *internalPowers();
InternalPowerSeq *internalPowers(const LibertyPort *port);
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
void leakagePower(// Return values.
float &leakage,
bool &exists) const;
bool leakagePowerEx() const { return leakage_power_exists_; }
bool leakagePowerExists() const { return leakage_power_exists_; }
bool hasSequentials() const;
// Find the sequential with the output connected to an (internal) port.
@ -532,6 +534,7 @@ protected:
TimingArcAttrsSeq timing_arc_attrs_;
bool has_infered_reg_timing_arcs_;
InternalPowerSeq internal_powers_;
PortInternalPowerSeq port_internal_powers_;
InternalPowerAttrsSeq internal_power_attrs_;
LeakagePowerSeq leakage_powers_;
SequentialSeq sequentials_;
@ -611,20 +614,6 @@ public:
SequentialSeq::ConstIterator(cell->sequentials_) {}
};
class LibertyCellLeakagePowerIterator : public LeakagePowerSeq::Iterator
{
public:
LibertyCellLeakagePowerIterator(LibertyCell *cell) :
LeakagePowerSeq::Iterator(cell->leakagePowers()) {}
};
class LibertyCellInternalPowerIterator : public InternalPowerSeq::Iterator
{
public:
LibertyCellInternalPowerIterator(LibertyCell *cell) :
InternalPowerSeq::Iterator(cell->internalPowers()) {}
};
////////////////////////////////////////////////////////////////
class LibertyPort : public ConcretePort

View File

@ -1110,6 +1110,19 @@ void
LibertyCell::addInternalPower(InternalPower *power)
{
internal_powers_.push_back(power);
port_internal_powers_[power->port()].push_back(power);
}
InternalPowerSeq *
LibertyCell::internalPowers()
{
return &internal_powers_;
}
InternalPowerSeq *
LibertyCell::internalPowers(const LibertyPort *port)
{
return &port_internal_powers_[port];
}
void

View File

@ -551,78 +551,74 @@ Power::findInternalPower(const Pin *to_pin,
units_->capacitanceUnit()->asString(load_cap));
debugPrint0(debug_, "power", 2, " when act/ns duty energy power\n");
float internal = 0.0;
LibertyCellInternalPowerIterator pwr_iter(cell);
while (pwr_iter.hasNext()) {
InternalPower *pwr = pwr_iter.next();
if (pwr->port() == to_port) {
const char *related_pg_pin = pwr->relatedPgPin();
const LibertyPort *from_port = pwr->relatedPort();
FuncExpr *when = pwr->when();
FuncExpr *infered_when = nullptr;
if (from_port) {
if (when == nullptr) {
FuncExpr *func = to_port->function();
if (func)
infered_when = inferedWhen(func, from_port);
}
for (InternalPower *pwr : *cell->internalPowers(to_port)) {
const char *related_pg_pin = pwr->relatedPgPin();
const LibertyPort *from_port = pwr->relatedPort();
FuncExpr *when = pwr->when();
FuncExpr *infered_when = nullptr;
if (from_port) {
if (when == nullptr) {
FuncExpr *func = to_port->function();
if (func)
infered_when = inferedWhen(func, from_port);
}
else
from_port = to_port;
// If all the "when" clauses exist VSS internal power is ignored.
const Pin *from_pin = network_->findPin(inst, from_port);
if (from_pin
&& ((when && internalPowerMissingWhen(cell, to_port, related_pg_pin))
|| pgNameVoltage(cell, related_pg_pin, dcalc_ap) != 0.0)) {
Vertex *from_vertex = graph_->pinLoadVertex(from_pin);
float duty;
if (infered_when) {
PwrActivity from_activity = findActivity(from_pin);
PwrActivity to_activity = findActivity(to_pin);
float duty1 = evalActivity(infered_when, inst).duty();
if (to_activity.activity() == 0.0)
duty = 0.0;
else
duty = from_activity.activity() / to_activity.activity() * duty1;
}
else if (when)
duty = evalActivity(when, inst).duty();
else if (search_->isClock(from_vertex))
duty = 1.0;
else
duty = 0.5;
float port_energy = 0.0;
for (auto to_rf : RiseFall::range()) {
// Should use unateness to find from_rf.
RiseFall *from_rf = to_rf;
float slew = delayAsFloat(graph_->slew(from_vertex,
from_rf,
dcalc_ap->index()));
if (!fuzzyInf(slew)) {
float table_energy = pwr->power(to_rf, pvt, slew, load_cap);
float tr_energy = table_energy * duty;
debugPrint4(debug_, "power", 3, " %s energy = %9.2e * %.2f = %9.2e\n",
to_rf->shortName(),
table_energy,
duty,
tr_energy);
port_energy += tr_energy;
}
}
float port_internal = port_energy * to_activity.activity();
debugPrint8(debug_, "power", 2, " %s -> %s %s %.2f %.2f %9.2e %9.2e %s\n",
from_port->name(),
to_port->name(),
when ? when->asString() : (infered_when ? infered_when->asString() : " "),
to_activity.activity() * 1e-9,
duty,
port_energy,
port_internal,
related_pg_pin ? related_pg_pin : "no pg_pin");
internal += port_internal;
}
if (infered_when)
infered_when->deleteSubexprs();
}
else
from_port = to_port;
// If all the "when" clauses exist VSS internal power is ignored.
const Pin *from_pin = network_->findPin(inst, from_port);
if (from_pin
&& ((when && internalPowerMissingWhen(cell, to_port, related_pg_pin))
|| pgNameVoltage(cell, related_pg_pin, dcalc_ap) != 0.0)) {
Vertex *from_vertex = graph_->pinLoadVertex(from_pin);
float duty;
if (infered_when) {
PwrActivity from_activity = findActivity(from_pin);
PwrActivity to_activity = findActivity(to_pin);
float duty1 = evalActivity(infered_when, inst).duty();
if (to_activity.activity() == 0.0)
duty = 0.0;
else
duty = from_activity.activity() / to_activity.activity() * duty1;
}
else if (when)
duty = evalActivity(when, inst).duty();
else if (search_->isClock(from_vertex))
duty = 1.0;
else
duty = 0.5;
float port_energy = 0.0;
for (auto to_rf : RiseFall::range()) {
// Should use unateness to find from_rf.
RiseFall *from_rf = to_rf;
float slew = delayAsFloat(graph_->slew(from_vertex,
from_rf,
dcalc_ap->index()));
if (!fuzzyInf(slew)) {
float table_energy = pwr->power(to_rf, pvt, slew, load_cap);
float tr_energy = table_energy * duty;
debugPrint4(debug_, "power", 3, " %s energy = %9.2e * %.2f = %9.2e\n",
to_rf->shortName(),
table_energy,
duty,
tr_energy);
port_energy += tr_energy;
}
}
float port_internal = port_energy * to_activity.activity();
debugPrint8(debug_, "power", 2, " %s -> %s %s %.2f %.2f %9.2e %9.2e %s\n",
from_port->name(),
to_port->name(),
when ? when->asString() : (infered_when ? infered_when->asString() : " "),
to_activity.activity() * 1e-9,
duty,
port_energy,
port_internal,
related_pg_pin ? related_pg_pin : "no pg_pin");
internal += port_internal;
}
if (infered_when)
infered_when->deleteSubexprs();
}
result.setInternal(result.internal() + internal);
}
@ -695,12 +691,9 @@ Power::internalPowerMissingWhen(LibertyCell *cell,
{
int when_input_count = 0;
int when_count = 0;
LibertyCellInternalPowerIterator pwr_iter(cell);
while (pwr_iter.hasNext()) {
auto pwr = pwr_iter.next();
for (InternalPower *pwr : *cell->internalPowers(to_port)) {
auto when = pwr->when();
if (pwr->port() == to_port
&& pwr->relatedPort() == nullptr
if (pwr->relatedPort() == nullptr
&& stringEqIf(pwr->relatedPgPin(), related_pg_pin)
&& when) {
when_count++;
@ -732,9 +725,7 @@ Power::findLeakagePower(const Instance *,
bool found_cond = false;
float default_leakage = 0.0;
bool found_default = false;
LibertyCellLeakagePowerIterator pwr_iter(cell);
while (pwr_iter.hasNext()) {
LeakagePower *leak = pwr_iter.next();
for (LeakagePower *leak : *cell->leakagePowers()) {
FuncExpr *when = leak->when();
if (when) {
FuncExprPortIterator port_iter(when);