diff --git a/power/Power.cc b/power/Power.cc index 25e19e9d..cc596820 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -100,7 +100,8 @@ Power::Power(StaState *sta) : input_activity_(), // default set in ensureActivities() seq_activity_map_(100, SeqPinHash(network_), SeqPinEqual()), activities_valid_(false), - bdd_(sta) + bdd_(sta), + corner_(nullptr) { } @@ -113,6 +114,8 @@ Power::clear() seq_activity_map_.clear(); activity_map_.clear(); activities_valid_ = false; + instance_powers_.clear(); + corner_ = nullptr; } void @@ -286,13 +289,10 @@ Power::power(const Corner *corner, pad.clear(); ensureActivities(); - Stats stats(debug_, report_); - LeafInstanceIterator *inst_iter = network_->leafInstanceIterator(); - while (inst_iter->hasNext()) { - Instance *inst = inst_iter->next(); + ensureInstPowers(corner); + for (auto [inst, inst_power] : instance_powers_) { LibertyCell *cell = network_->libertyCell(inst); if (cell) { - PowerResult inst_power = power(inst, cell, corner); if (cell->isMacro() || cell->isMemory() || cell->interfaceTiming()) @@ -308,8 +308,6 @@ Power::power(const Corner *corner, total.incr(inst_power); } } - delete inst_iter; - stats.report("Find power"); } bool @@ -332,17 +330,15 @@ PowerResult Power::power(const Instance *inst, const Corner *corner) { + ensureActivities(); + ensureInstPowers(corner); if (network_->isHierarchical(inst)) { PowerResult result; powerInside(inst, corner, result); return result; } - LibertyCell *cell = network_->libertyCell(inst); - if (cell) { - ensureActivities(); - return power(inst, cell, corner); - } - return PowerResult(); + else + return instance_powers_[inst]; } void @@ -355,13 +351,8 @@ Power::powerInside(const Instance *hinst, Instance *child = child_iter->next(); if (network_->isHierarchical(child)) powerInside(child, corner, result); - else { - LibertyCell *cell = network_->libertyCell(child); - if (cell) { - PowerResult inst_power = power(child, cell, corner); - result.incr(inst_power); - } - } + else + result.incr(instance_powers_[child]); } delete child_iter; } @@ -707,6 +698,7 @@ Power::evalBddActivity(DdNode *bdd, void Power::ensureActivities() { + Stats stats(debug_, report_); // No need to propagate activites if global activity is set. if (!global_activity_.isSet()) { if (!activities_valid_) { @@ -750,6 +742,7 @@ Power::ensureActivities() activities_valid_ = true; } } + stats.report("Power activities"); } void @@ -841,6 +834,32 @@ Power::seedRegOutputActivities(const Instance *reg, //////////////////////////////////////////////////////////////// +void +Power::ensureInstPowers(const Corner *corner) +{ + if (instance_powers_.empty() + || corner != corner_) + findInstPowers(corner); +} + +void +Power::findInstPowers(const Corner *corner) +{ + Stats stats(debug_, report_); + LeafInstanceIterator *inst_iter = network_->leafInstanceIterator(); + while (inst_iter->hasNext()) { + Instance *inst = inst_iter->next(); + LibertyCell *cell = network_->libertyCell(inst); + if (cell) { + PowerResult inst_power = power(inst, cell, corner); + instance_powers_[inst] = inst_power; + } + } + delete inst_iter; + corner_ = corner; + stats.report("Find power"); +} + PowerResult Power::power(const Instance *inst, LibertyCell *cell, @@ -1539,6 +1558,22 @@ Power::clockMinPeriod() return 0.0; } +void +Power::deleteInstanceBefore(const Instance *) +{ + activities_valid_ = false; + instance_powers_.clear(); + corner_ = nullptr; +} + +void +Power::deletePinBefore(const Pin *) +{ + activities_valid_ = false; + instance_powers_.clear(); + corner_ = nullptr; +} + //////////////////////////////////////////////////////////////// PowerResult::PowerResult() : diff --git a/power/Power.hh b/power/Power.hh index 18bc3ab9..e51ce285 100644 --- a/power/Power.hh +++ b/power/Power.hh @@ -107,6 +107,8 @@ public: float clockMinPeriod(); InstanceSeq highestPowerInstances(size_t count, const Corner *corner); + void deleteInstanceBefore(const Instance *inst); + void deletePinBefore(const Pin *pin); protected: PwrActivity &activity(const Pin *pin); @@ -129,6 +131,8 @@ protected: PwrActivity &activity); PwrActivity findActivity(const Pin *pin); + void ensureInstPowers(const Corner *corner); + void findInstPowers(const Corner *corner); PowerResult power(const Instance *inst, LibertyCell *cell, const Corner *corner); @@ -229,6 +233,8 @@ private: PwrSeqActivityMap seq_activity_map_; bool activities_valid_; Bdd bdd_; + std::map instance_powers_; + const Corner *corner_; static constexpr int max_activity_passes_ = 100; diff --git a/search/Sta.cc b/search/Sta.cc index 87fe14a9..d51ecae9 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4588,6 +4588,7 @@ Sta::deleteLeafInstanceBefore(const Instance *inst) { sim_->deleteInstanceBefore(inst); sdc_->deleteInstanceBefore(inst); + power_->deleteInstanceBefore(inst); } void @@ -4664,6 +4665,7 @@ Sta::deletePinBefore(const Pin *pin) } sim_->deletePinBefore(pin); clk_network_->deletePinBefore(pin); + power_->deletePinBefore(pin); } void