From a23ba7b88e26b603a942db42be48d7ec7acd06cf Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 30 Jul 2020 07:55:48 -0700 Subject: [PATCH] power activity for internal pins --- include/sta/Power.hh | 27 ++++++++++++ search/Power.cc | 102 +++++++++++++++++++++++++++++++++---------- 2 files changed, 105 insertions(+), 24 deletions(-) diff --git a/include/sta/Power.hh b/include/sta/Power.hh index 12625a5e..c35c16f0 100644 --- a/include/sta/Power.hh +++ b/include/sta/Power.hh @@ -25,7 +25,24 @@ class PwrActivity; class PropActivityVisitor; class BfsFwdIterator; +typedef std::pair 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 PwrActivityMap; +typedef UnorderedMap PwrSeqActivityMap; enum class PwrActivityOrigin { @@ -94,6 +111,13 @@ public: float activity, float duty, 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. PwrActivity findClkedActivity(const Pin *pin); @@ -140,6 +164,8 @@ protected: PwrActivity findClkedActivity(const Pin *pin, const Clock *inst_clk); PwrActivity findActivity(const Pin *pin); + PwrActivity findSeqActivity(const Instance *inst, + LibertyPort *port); float portVoltage(LibertyCell *cell, const LibertyPort *port, const DcalcAnalysisPt *dcalc_ap); @@ -172,6 +198,7 @@ private: PwrActivity global_activity_; PwrActivity input_activity_; PwrActivityMap activity_map_; + PwrSeqActivityMap seq_activity_map_; bool activities_valid_; friend class PropActivityVisitor; diff --git a/search/Power.cc b/search/Power.cc index 4a3caadb..506b10e6 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -20,6 +20,7 @@ #include "Debug.hh" #include "EnumNameMap.hh" +#include "Hash.hh" #include "MinMax.hh" #include "Units.hh" #include "Transition.hh" @@ -131,6 +132,47 @@ Power::setPinActivity(const Pin *pin, 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 Power::power(const Corner *corner, // Return values. @@ -358,11 +400,14 @@ Power::evalActivity(FuncExpr *expr, else return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); } - Pin *pin = network_->findPin(inst, port); - if (pin) - return findActivity(pin); - else - return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); + if (port->direction()->isInternal()) + return findSeqActivity(inst, port); + else { + Pin *pin = network_->findPin(inst, port); + if (pin) + return findActivity(pin); + } + return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); } case FuncExpr::op_not: { PwrActivity activity1 = evalActivity(expr->left(), inst, @@ -456,7 +501,7 @@ Power::seedActivities(BfsFwdIterator &bfs) const Pin *pin = vertex->pin(); // Clock activities are baked in. if (!sdc_->isLeafPinClock(pin) - && network_->direction(pin) != PortDirection::internal()) { + && !network_->direction(pin)->isInternal()) { debugPrint1(debug_, "power_activity", 3, "seed %s\n", vertex->name(network_)); PwrActivity &activity = pinActivity(pin); @@ -484,9 +529,9 @@ Power::seedRegOutputActivities(const Instance *inst, // the sequential internal pins (IQ, IQN). InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { - auto pin = pin_iter->next(); - auto port = network_->libertyPort(pin); - auto func = port->function(); + Pin *pin = pin_iter->next(); + LibertyPort *port = network_->libertyPort(pin); + FuncExpr *func = port->function(); if (func) { Vertex *vertex = graph_->pinDrvrVertex(pin); if (func->port() == seq->output() @@ -507,15 +552,12 @@ Power::seedRegOutputActivities(const Instance *reg, LibertyPort *output, bool invert) { - const Pin *pin = network_->findPin(reg, output); - if (pin) { - PwrActivity activity = evalActivity(seq->data(), reg); - if (invert) - activity.set(activity.activity(), - 1.0 - activity.duty(), - activity.origin()); - setPinActivity(pin, activity); - } + PwrActivity activity = evalActivity(seq->data(), reg); + if (invert) + activity.set(activity.activity(), + 1.0 - activity.duty(), + activity.origin()); + setSeqActivity(reg, output, activity); } //////////////////////////////////////////////////////////////// @@ -951,12 +993,24 @@ Power::findActivity(const Pin *pin) return PwrActivity(2.0, 0.5, PwrActivityOrigin::clock); else if (global_activity_.isSet()) return global_activity_; - else { - if (activity_map_.hasKey(pin)) { - PwrActivity &activity = activity_map_[pin]; - if (activity.origin() != PwrActivityOrigin::unknown) - return activity; - } + else if (activity_map_.hasKey(pin)) { + PwrActivity &activity = activity_map_[pin]; + if (activity.origin() != PwrActivityOrigin::unknown) + 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_; }