From 1d3ae3060037d53266f5690de8417367d4b4b652 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 6 Apr 2020 18:27:40 -0700 Subject: [PATCH] LibertyCell::internalPowers(port) --- doc/ApiChanges.txt | 5 ++ include/sta/Liberty.hh | 21 ++---- liberty/Liberty.cc | 13 ++++ search/Power.cc | 147 +++++++++++++++++++---------------------- 4 files changed, 92 insertions(+), 94 deletions(-) diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt index 7f1aaf36..b986eb6b 100644 --- a/doc/ApiChanges.txt +++ b/doc/ApiChanges.txt @@ -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 ------------------------- diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 61932825..630aa158 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -58,6 +58,7 @@ typedef Set TimingArcSetMap; typedef Map LibertyPortPairTimingArcMap; typedef Vector InternalPowerSeq; +typedef Map PortInternalPowerSeq; typedef Vector LeakagePowerSeq; typedef Map LibertyPortTimingArcMap; typedef Map 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 diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 7529c433..4adfbf73 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -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 diff --git a/search/Power.cc b/search/Power.cc index 6fa6d9a6..d5385732 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -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);