power activity for internal pins

This commit is contained in:
James Cherry 2020-07-30 07:55:48 -07:00
parent 6cdb9d3cfe
commit a23ba7b88e
2 changed files with 105 additions and 24 deletions

View File

@ -25,7 +25,24 @@ class PwrActivity;
class PropActivityVisitor; class PropActivityVisitor;
class BfsFwdIterator; class BfsFwdIterator;
typedef std::pair<const Instance*, LibertyPort*> SeqPin;
class SeqPinHash
{
public:
size_t operator()(const SeqPin &pin) const;
};
class SeqPinEqual
{
public:
bool operator()(const SeqPin &pin1,
const SeqPin &pin2) const;
};
typedef UnorderedMap<const Pin*,PwrActivity> PwrActivityMap; typedef UnorderedMap<const Pin*,PwrActivity> PwrActivityMap;
typedef UnorderedMap<SeqPin, PwrActivity,
SeqPinHash, SeqPinEqual> PwrSeqActivityMap;
enum class PwrActivityOrigin enum class PwrActivityOrigin
{ {
@ -94,6 +111,13 @@ public:
float activity, float activity,
float duty, float duty,
PwrActivityOrigin origin); PwrActivityOrigin origin);
void setSeqActivity(const Instance *reg,
LibertyPort *output,
PwrActivity &activity);
bool hasSeqActivity(const Instance *reg,
LibertyPort *output);
PwrActivity seqActivity(const Instance *reg,
LibertyPort *output);
// Activity is toggles per second. // Activity is toggles per second.
PwrActivity findClkedActivity(const Pin *pin); PwrActivity findClkedActivity(const Pin *pin);
@ -140,6 +164,8 @@ protected:
PwrActivity findClkedActivity(const Pin *pin, PwrActivity findClkedActivity(const Pin *pin,
const Clock *inst_clk); const Clock *inst_clk);
PwrActivity findActivity(const Pin *pin); PwrActivity findActivity(const Pin *pin);
PwrActivity findSeqActivity(const Instance *inst,
LibertyPort *port);
float portVoltage(LibertyCell *cell, float portVoltage(LibertyCell *cell,
const LibertyPort *port, const LibertyPort *port,
const DcalcAnalysisPt *dcalc_ap); const DcalcAnalysisPt *dcalc_ap);
@ -172,6 +198,7 @@ private:
PwrActivity global_activity_; PwrActivity global_activity_;
PwrActivity input_activity_; PwrActivity input_activity_;
PwrActivityMap activity_map_; PwrActivityMap activity_map_;
PwrSeqActivityMap seq_activity_map_;
bool activities_valid_; bool activities_valid_;
friend class PropActivityVisitor; friend class PropActivityVisitor;

View File

@ -20,6 +20,7 @@
#include "Debug.hh" #include "Debug.hh"
#include "EnumNameMap.hh" #include "EnumNameMap.hh"
#include "Hash.hh"
#include "MinMax.hh" #include "MinMax.hh"
#include "Units.hh" #include "Units.hh"
#include "Transition.hh" #include "Transition.hh"
@ -131,6 +132,47 @@ Power::setPinActivity(const Pin *pin,
activities_valid_ = false; activities_valid_ = false;
} }
// Sequential internal pins may not be in the netlist so their
// activities are stored by instance/liberty_port pairs.
void
Power::setSeqActivity(const Instance *reg,
LibertyPort *output,
PwrActivity &activity)
{
seq_activity_map_[SeqPin(reg, output)] = activity;
activities_valid_ = false;
}
bool
Power::hasSeqActivity(const Instance *reg,
LibertyPort *output)
{
return seq_activity_map_.hasKey(SeqPin(reg, output));
}
PwrActivity
Power::seqActivity(const Instance *reg,
LibertyPort *output)
{
return seq_activity_map_[SeqPin(reg, output)];
}
size_t
SeqPinHash::operator()(const SeqPin &pin) const
{
return hashSum(hashPtr(pin.first), hashPtr(pin.second));
}
bool
SeqPinEqual::operator()(const SeqPin &pin1,
const SeqPin &pin2) const
{
return pin1.first == pin2.first
&& pin1.second == pin2.second;
}
////////////////////////////////////////////////////////////////
void void
Power::power(const Corner *corner, Power::power(const Corner *corner,
// Return values. // Return values.
@ -358,11 +400,14 @@ Power::evalActivity(FuncExpr *expr,
else else
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
} }
Pin *pin = network_->findPin(inst, port); if (port->direction()->isInternal())
if (pin) return findSeqActivity(inst, port);
return findActivity(pin); else {
else Pin *pin = network_->findPin(inst, port);
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); if (pin)
return findActivity(pin);
}
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
} }
case FuncExpr::op_not: { case FuncExpr::op_not: {
PwrActivity activity1 = evalActivity(expr->left(), inst, PwrActivity activity1 = evalActivity(expr->left(), inst,
@ -456,7 +501,7 @@ Power::seedActivities(BfsFwdIterator &bfs)
const Pin *pin = vertex->pin(); const Pin *pin = vertex->pin();
// Clock activities are baked in. // Clock activities are baked in.
if (!sdc_->isLeafPinClock(pin) if (!sdc_->isLeafPinClock(pin)
&& network_->direction(pin) != PortDirection::internal()) { && !network_->direction(pin)->isInternal()) {
debugPrint1(debug_, "power_activity", 3, "seed %s\n", debugPrint1(debug_, "power_activity", 3, "seed %s\n",
vertex->name(network_)); vertex->name(network_));
PwrActivity &activity = pinActivity(pin); PwrActivity &activity = pinActivity(pin);
@ -484,9 +529,9 @@ Power::seedRegOutputActivities(const Instance *inst,
// the sequential internal pins (IQ, IQN). // the sequential internal pins (IQ, IQN).
InstancePinIterator *pin_iter = network_->pinIterator(inst); InstancePinIterator *pin_iter = network_->pinIterator(inst);
while (pin_iter->hasNext()) { while (pin_iter->hasNext()) {
auto pin = pin_iter->next(); Pin *pin = pin_iter->next();
auto port = network_->libertyPort(pin); LibertyPort *port = network_->libertyPort(pin);
auto func = port->function(); FuncExpr *func = port->function();
if (func) { if (func) {
Vertex *vertex = graph_->pinDrvrVertex(pin); Vertex *vertex = graph_->pinDrvrVertex(pin);
if (func->port() == seq->output() if (func->port() == seq->output()
@ -507,15 +552,12 @@ Power::seedRegOutputActivities(const Instance *reg,
LibertyPort *output, LibertyPort *output,
bool invert) bool invert)
{ {
const Pin *pin = network_->findPin(reg, output); PwrActivity activity = evalActivity(seq->data(), reg);
if (pin) { if (invert)
PwrActivity activity = evalActivity(seq->data(), reg); activity.set(activity.activity(),
if (invert) 1.0 - activity.duty(),
activity.set(activity.activity(), activity.origin());
1.0 - activity.duty(), setSeqActivity(reg, output, activity);
activity.origin());
setPinActivity(pin, activity);
}
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -951,12 +993,24 @@ Power::findActivity(const Pin *pin)
return PwrActivity(2.0, 0.5, PwrActivityOrigin::clock); return PwrActivity(2.0, 0.5, PwrActivityOrigin::clock);
else if (global_activity_.isSet()) else if (global_activity_.isSet())
return global_activity_; return global_activity_;
else { else if (activity_map_.hasKey(pin)) {
if (activity_map_.hasKey(pin)) { PwrActivity &activity = activity_map_[pin];
PwrActivity &activity = activity_map_[pin]; if (activity.origin() != PwrActivityOrigin::unknown)
if (activity.origin() != PwrActivityOrigin::unknown) return activity;
return activity; }
} return input_activity_;
}
PwrActivity
Power::findSeqActivity(const Instance *inst,
LibertyPort *port)
{
if (global_activity_.isSet())
return global_activity_;
else if (hasSeqActivity(inst, port)) {
PwrActivity activity = seqActivity(inst, port);
if (activity.origin() != PwrActivityOrigin::unknown)
return activity;
} }
return input_activity_; return input_activity_;
} }