set_power_activity -pins
This commit is contained in:
parent
cafb7b9152
commit
ae3da179e2
149
search/Power.cc
149
search/Power.cc
|
|
@ -97,41 +97,52 @@ Power::setInputPortActivity(const Port *input_port,
|
|||
Instance *top_inst = network_->topInstance();
|
||||
const Pin *pin = network_->findPin(top_inst, input_port);
|
||||
if (pin) {
|
||||
activity_map_[pin] = {activity, duty, PwrActivityOrigin::user};
|
||||
user_activity_map_[pin] = {activity, duty, PwrActivityOrigin::user};
|
||||
activities_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Power::setUserActivity(const Pin *pin,
|
||||
float activity,
|
||||
float duty,
|
||||
PwrActivityOrigin origin)
|
||||
{
|
||||
user_activity_map_[pin] = {activity, duty, origin};
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
PwrActivity &
|
||||
Power::pinActivity(const Pin *pin)
|
||||
Power::userActivity(const Pin *pin)
|
||||
{
|
||||
return user_activity_map_[pin];
|
||||
}
|
||||
|
||||
bool
|
||||
Power::hasUserActivity(const Pin *pin)
|
||||
{
|
||||
return user_activity_map_.hasKey(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Power::setActivity(const Pin *pin,
|
||||
PwrActivity &activity)
|
||||
{
|
||||
activity_map_[pin] = activity;
|
||||
}
|
||||
|
||||
PwrActivity &
|
||||
Power::activity(const Pin *pin)
|
||||
{
|
||||
return activity_map_[pin];
|
||||
}
|
||||
|
||||
bool
|
||||
Power::hasPinActivity(const Pin *pin)
|
||||
Power::hasActivity(const Pin *pin)
|
||||
{
|
||||
return activity_map_.hasKey(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Power::setPinActivity(const Pin *pin,
|
||||
PwrActivity &activity)
|
||||
{
|
||||
activity_map_[pin] = activity;
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::setPinActivity(const Pin *pin,
|
||||
float activity,
|
||||
float duty,
|
||||
PwrActivityOrigin origin)
|
||||
{
|
||||
activity_map_[pin] = {activity, duty, origin};
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
// Sequential internal pins may not be in the netlist so their
|
||||
// activities are stored by instance/liberty_port pairs.
|
||||
void
|
||||
|
|
@ -332,44 +343,48 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
auto pin = vertex->pin();
|
||||
debugPrint1(debug_, "power_activity", 3, "visit %s\n",
|
||||
vertex->name(network_));
|
||||
bool input_without_activity = false;
|
||||
if (network_->isLoad(pin)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
if (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (edge->isWire()) {
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
const Pin *from_pin = from_vertex->pin();
|
||||
PwrActivity &from_activity = power_->pinActivity(from_pin);
|
||||
PwrActivity to_activity(from_activity.activity(),
|
||||
from_activity.duty(),
|
||||
PwrActivityOrigin::propagated);
|
||||
if (!power_->hasPinActivity(pin))
|
||||
input_without_activity = true;
|
||||
power_->setPinActivity(pin, to_activity);
|
||||
if (power_->hasUserActivity(pin))
|
||||
power_->setActivity(pin, power_->userActivity(pin));
|
||||
else {
|
||||
bool input_without_activity = false;
|
||||
if (network_->isLoad(pin)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
if (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (edge->isWire()) {
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
const Pin *from_pin = from_vertex->pin();
|
||||
PwrActivity &from_activity = power_->activity(from_pin);
|
||||
PwrActivity to_activity(from_activity.activity(),
|
||||
from_activity.duty(),
|
||||
PwrActivityOrigin::propagated);
|
||||
if (!power_->hasActivity(pin))
|
||||
input_without_activity = true;
|
||||
power_->setActivity(pin, to_activity);
|
||||
}
|
||||
}
|
||||
Instance *inst = network_->instance(pin);
|
||||
auto cell = network_->libertyCell(inst);
|
||||
if (cell && cell->hasSequentials()) {
|
||||
debugPrint1(debug_, "power_activity", 3, "pending reg %s\n",
|
||||
network_->pathName(inst));
|
||||
visited_regs_->insert(inst);
|
||||
found_reg_without_activity_ = input_without_activity;
|
||||
}
|
||||
}
|
||||
Instance *inst = network_->instance(pin);
|
||||
auto cell = network_->libertyCell(inst);
|
||||
if (cell && cell->hasSequentials()) {
|
||||
debugPrint1(debug_, "power_activity", 3, "pending reg %s\n",
|
||||
network_->pathName(inst));
|
||||
visited_regs_->insert(inst);
|
||||
found_reg_without_activity_ = input_without_activity;
|
||||
}
|
||||
}
|
||||
if (network_->isDriver(pin)) {
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
if (port) {
|
||||
FuncExpr *func = port->function();
|
||||
if (func) {
|
||||
Instance *inst = network_->instance(pin);
|
||||
PwrActivity activity = power_->evalActivity(func, inst);
|
||||
power_->setPinActivity(pin, activity);
|
||||
debugPrint3(debug_, "power_activity", 3, "set %s %.2e %.2f\n",
|
||||
vertex->name(network_),
|
||||
activity.activity(),
|
||||
activity.duty());
|
||||
if (network_->isDriver(pin)) {
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
if (port) {
|
||||
FuncExpr *func = port->function();
|
||||
if (func) {
|
||||
Instance *inst = network_->instance(pin);
|
||||
PwrActivity activity = power_->evalActivity(func, inst);
|
||||
power_->setActivity(pin, activity);
|
||||
debugPrint3(debug_, "power_activity", 3, "set %s %.2e %.2f\n",
|
||||
vertex->name(network_),
|
||||
activity.activity(),
|
||||
activity.duty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -469,14 +484,21 @@ Power::preamble()
|
|||
void
|
||||
Power::ensureActivities()
|
||||
{
|
||||
// No need to propagate activites if global activity is set.
|
||||
if (!global_activity_.isSet()) {
|
||||
if (!activities_valid_) {
|
||||
// Clear existing activities.
|
||||
activity_map_.clear();
|
||||
seq_activity_map_.clear();
|
||||
|
||||
ActivitySrchPred activity_srch_pred(this);
|
||||
BfsFwdIterator bfs(BfsIndex::other, &activity_srch_pred, this);
|
||||
seedActivities(bfs);
|
||||
PropActivityVisitor visitor(this, &bfs);
|
||||
visitor.init();
|
||||
// Propagate activities through combinational logic.
|
||||
bfs.visit(levelize_->maxLevel(), &visitor);
|
||||
// Propagate activiities through registers.
|
||||
while (visitor.foundRegWithoutActivity()) {
|
||||
InstanceSet *regs = visitor.stealVisitedRegs();
|
||||
InstanceSet::Iterator reg_iter(regs);
|
||||
|
|
@ -486,7 +508,10 @@ Power::ensureActivities()
|
|||
seedRegOutputActivities(reg, bfs);
|
||||
}
|
||||
delete regs;
|
||||
|
||||
visitor.init();
|
||||
// Propagate register output activities through
|
||||
// combinational logic.
|
||||
bfs.visit(levelize_->maxLevel(), &visitor);
|
||||
}
|
||||
activities_valid_ = true;
|
||||
|
|
@ -504,11 +529,11 @@ Power::seedActivities(BfsFwdIterator &bfs)
|
|||
&& !network_->direction(pin)->isInternal()) {
|
||||
debugPrint1(debug_, "power_activity", 3, "seed %s\n",
|
||||
vertex->name(network_));
|
||||
PwrActivity &activity = pinActivity(pin);
|
||||
PwrActivityOrigin origin = activity.origin();
|
||||
// Default inputs without explicit activities to the input default.
|
||||
if (origin != PwrActivityOrigin::user)
|
||||
setPinActivity(pin, input_activity_);
|
||||
if (hasUserActivity(pin))
|
||||
setActivity(pin, userActivity(pin));
|
||||
else
|
||||
// Default inputs without explicit activities to the input default.
|
||||
setActivity(pin, input_activity_);
|
||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
bfs.enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,14 +75,19 @@ public:
|
|||
void setInputPortActivity(const Port *input_port,
|
||||
float activity,
|
||||
float duty);
|
||||
PwrActivity &pinActivity(const Pin *pin);
|
||||
bool hasPinActivity(const Pin *pin);
|
||||
void setPinActivity(const Pin *pin,
|
||||
PwrActivity &activity);
|
||||
void setPinActivity(const Pin *pin,
|
||||
float activity,
|
||||
float duty,
|
||||
PwrActivityOrigin origin);
|
||||
PwrActivity &activity(const Pin *pin);
|
||||
void setUserActivity(const Pin *pin,
|
||||
float activity,
|
||||
float duty,
|
||||
PwrActivityOrigin origin);
|
||||
// Activity is toggles per second.
|
||||
PwrActivity findClkedActivity(const Pin *pin);
|
||||
|
||||
protected:
|
||||
void preamble();
|
||||
void ensureActivities();
|
||||
bool hasUserActivity(const Pin *pin);
|
||||
PwrActivity &userActivity(const Pin *pin);
|
||||
void setSeqActivity(const Instance *reg,
|
||||
LibertyPort *output,
|
||||
PwrActivity &activity);
|
||||
|
|
@ -90,12 +95,9 @@ public:
|
|||
LibertyPort *output);
|
||||
PwrActivity seqActivity(const Instance *reg,
|
||||
LibertyPort *output);
|
||||
// Activity is toggles per second.
|
||||
PwrActivity findClkedActivity(const Pin *pin);
|
||||
|
||||
protected:
|
||||
void preamble();
|
||||
void ensureActivities();
|
||||
bool hasActivity(const Pin *pin);
|
||||
void setActivity(const Pin *pin,
|
||||
PwrActivity &activity);
|
||||
|
||||
void power(const Instance *inst,
|
||||
LibertyCell *cell,
|
||||
|
|
@ -167,8 +169,14 @@ protected:
|
|||
const LibertyPort *cofactor_port);
|
||||
|
||||
private:
|
||||
// Port/pin activities set by set_pin_activity.
|
||||
// set_pin_activity -global
|
||||
PwrActivity global_activity_;
|
||||
// set_pin_activity -input
|
||||
PwrActivity input_activity_;
|
||||
// set_pin_activity -input_ports -pins
|
||||
PwrActivityMap user_activity_map_;
|
||||
// Propagated activities.
|
||||
PwrActivityMap activity_map_;
|
||||
PwrSeqActivityMap seq_activity_map_;
|
||||
bool activities_valid_;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ proc set_power_activity { args } {
|
|||
}
|
||||
}
|
||||
if { [info exists keys(-pins)] } {
|
||||
set ports [get_pins_error "pins" $keys(-pins)]
|
||||
set pins [get_pins $keys(-pins)]
|
||||
foreach pin $pins {
|
||||
if { [get_property $pin "direction"] == "input" } {
|
||||
set_power_pin_activity $pin $activity $duty
|
||||
|
|
|
|||
|
|
@ -4830,8 +4830,8 @@ set_power_pin_activity(const Pin *pin,
|
|||
float activity,
|
||||
float duty)
|
||||
{
|
||||
return Sta::sta()->power()->setPinActivity(pin, activity, duty,
|
||||
PwrActivityOrigin::user);
|
||||
return Sta::sta()->power()->setUserActivity(pin, activity, duty,
|
||||
PwrActivityOrigin::user);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue