cache instance power results

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-11-09 17:15:05 -07:00
parent cf903f4db6
commit 771050b0de
3 changed files with 64 additions and 21 deletions

View File

@ -100,7 +100,8 @@ Power::Power(StaState *sta) :
input_activity_(), // default set in ensureActivities() input_activity_(), // default set in ensureActivities()
seq_activity_map_(100, SeqPinHash(network_), SeqPinEqual()), seq_activity_map_(100, SeqPinHash(network_), SeqPinEqual()),
activities_valid_(false), activities_valid_(false),
bdd_(sta) bdd_(sta),
corner_(nullptr)
{ {
} }
@ -113,6 +114,8 @@ Power::clear()
seq_activity_map_.clear(); seq_activity_map_.clear();
activity_map_.clear(); activity_map_.clear();
activities_valid_ = false; activities_valid_ = false;
instance_powers_.clear();
corner_ = nullptr;
} }
void void
@ -286,13 +289,10 @@ Power::power(const Corner *corner,
pad.clear(); pad.clear();
ensureActivities(); ensureActivities();
Stats stats(debug_, report_); ensureInstPowers(corner);
LeafInstanceIterator *inst_iter = network_->leafInstanceIterator(); for (auto [inst, inst_power] : instance_powers_) {
while (inst_iter->hasNext()) {
Instance *inst = inst_iter->next();
LibertyCell *cell = network_->libertyCell(inst); LibertyCell *cell = network_->libertyCell(inst);
if (cell) { if (cell) {
PowerResult inst_power = power(inst, cell, corner);
if (cell->isMacro() if (cell->isMacro()
|| cell->isMemory() || cell->isMemory()
|| cell->interfaceTiming()) || cell->interfaceTiming())
@ -308,8 +308,6 @@ Power::power(const Corner *corner,
total.incr(inst_power); total.incr(inst_power);
} }
} }
delete inst_iter;
stats.report("Find power");
} }
bool bool
@ -332,17 +330,15 @@ PowerResult
Power::power(const Instance *inst, Power::power(const Instance *inst,
const Corner *corner) const Corner *corner)
{ {
ensureActivities();
ensureInstPowers(corner);
if (network_->isHierarchical(inst)) { if (network_->isHierarchical(inst)) {
PowerResult result; PowerResult result;
powerInside(inst, corner, result); powerInside(inst, corner, result);
return result; return result;
} }
LibertyCell *cell = network_->libertyCell(inst); else
if (cell) { return instance_powers_[inst];
ensureActivities();
return power(inst, cell, corner);
}
return PowerResult();
} }
void void
@ -355,13 +351,8 @@ Power::powerInside(const Instance *hinst,
Instance *child = child_iter->next(); Instance *child = child_iter->next();
if (network_->isHierarchical(child)) if (network_->isHierarchical(child))
powerInside(child, corner, result); powerInside(child, corner, result);
else { else
LibertyCell *cell = network_->libertyCell(child); result.incr(instance_powers_[child]);
if (cell) {
PowerResult inst_power = power(child, cell, corner);
result.incr(inst_power);
}
}
} }
delete child_iter; delete child_iter;
} }
@ -707,6 +698,7 @@ Power::evalBddActivity(DdNode *bdd,
void void
Power::ensureActivities() Power::ensureActivities()
{ {
Stats stats(debug_, report_);
// No need to propagate activites if global activity is set. // No need to propagate activites if global activity is set.
if (!global_activity_.isSet()) { if (!global_activity_.isSet()) {
if (!activities_valid_) { if (!activities_valid_) {
@ -750,6 +742,7 @@ Power::ensureActivities()
activities_valid_ = true; activities_valid_ = true;
} }
} }
stats.report("Power activities");
} }
void 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 PowerResult
Power::power(const Instance *inst, Power::power(const Instance *inst,
LibertyCell *cell, LibertyCell *cell,
@ -1539,6 +1558,22 @@ Power::clockMinPeriod()
return 0.0; 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() : PowerResult::PowerResult() :

View File

@ -107,6 +107,8 @@ public:
float clockMinPeriod(); float clockMinPeriod();
InstanceSeq highestPowerInstances(size_t count, InstanceSeq highestPowerInstances(size_t count,
const Corner *corner); const Corner *corner);
void deleteInstanceBefore(const Instance *inst);
void deletePinBefore(const Pin *pin);
protected: protected:
PwrActivity &activity(const Pin *pin); PwrActivity &activity(const Pin *pin);
@ -129,6 +131,8 @@ protected:
PwrActivity &activity); PwrActivity &activity);
PwrActivity findActivity(const Pin *pin); PwrActivity findActivity(const Pin *pin);
void ensureInstPowers(const Corner *corner);
void findInstPowers(const Corner *corner);
PowerResult power(const Instance *inst, PowerResult power(const Instance *inst,
LibertyCell *cell, LibertyCell *cell,
const Corner *corner); const Corner *corner);
@ -229,6 +233,8 @@ private:
PwrSeqActivityMap seq_activity_map_; PwrSeqActivityMap seq_activity_map_;
bool activities_valid_; bool activities_valid_;
Bdd bdd_; Bdd bdd_;
std::map<const Instance*, PowerResult> instance_powers_;
const Corner *corner_;
static constexpr int max_activity_passes_ = 100; static constexpr int max_activity_passes_ = 100;

View File

@ -4588,6 +4588,7 @@ Sta::deleteLeafInstanceBefore(const Instance *inst)
{ {
sim_->deleteInstanceBefore(inst); sim_->deleteInstanceBefore(inst);
sdc_->deleteInstanceBefore(inst); sdc_->deleteInstanceBefore(inst);
power_->deleteInstanceBefore(inst);
} }
void void
@ -4664,6 +4665,7 @@ Sta::deletePinBefore(const Pin *pin)
} }
sim_->deletePinBefore(pin); sim_->deletePinBefore(pin);
clk_network_->deletePinBefore(pin); clk_network_->deletePinBefore(pin);
power_->deletePinBefore(pin);
} }
void void