power activity for internal pins
This commit is contained in:
parent
6cdb9d3cfe
commit
a23ba7b88e
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,10 +400,13 @@ Power::evalActivity(FuncExpr *expr,
|
||||||
else
|
else
|
||||||
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
||||||
}
|
}
|
||||||
|
if (port->direction()->isInternal())
|
||||||
|
return findSeqActivity(inst, port);
|
||||||
|
else {
|
||||||
Pin *pin = network_->findPin(inst, port);
|
Pin *pin = network_->findPin(inst, port);
|
||||||
if (pin)
|
if (pin)
|
||||||
return findActivity(pin);
|
return findActivity(pin);
|
||||||
else
|
}
|
||||||
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
||||||
}
|
}
|
||||||
case FuncExpr::op_not: {
|
case FuncExpr::op_not: {
|
||||||
|
|
@ -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);
|
|
||||||
if (pin) {
|
|
||||||
PwrActivity activity = evalActivity(seq->data(), reg);
|
PwrActivity activity = evalActivity(seq->data(), reg);
|
||||||
if (invert)
|
if (invert)
|
||||||
activity.set(activity.activity(),
|
activity.set(activity.activity(),
|
||||||
1.0 - activity.duty(),
|
1.0 - activity.duty(),
|
||||||
activity.origin());
|
activity.origin());
|
||||||
setPinActivity(pin, activity);
|
setSeqActivity(reg, output, 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_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue