report_power regressions pass

This commit is contained in:
James Cherry 2020-05-01 18:40:50 -07:00
parent 8b65b522fb
commit 2bcd61a5df
2 changed files with 70 additions and 29 deletions

View File

@ -160,6 +160,7 @@ protected:
const char *related_pg_pin); const char *related_pg_pin);
FuncExpr *inferedWhen(FuncExpr *expr, FuncExpr *inferedWhen(FuncExpr *expr,
const LibertyPort *from_port); const LibertyPort *from_port);
LibertyPort *findExprOutPort(FuncExpr *expr);
private: private:
PwrActivity global_activity_; PwrActivity global_activity_;

View File

@ -544,55 +544,64 @@ Power::findInstClk(const Instance *inst)
} }
void void
Power::findInputInternalPower(const Pin *from_pin, Power::findInputInternalPower(const Pin *pin,
const LibertyPort *from_port, const LibertyPort *port,
const Instance *inst, const Instance *inst,
LibertyCell *cell, LibertyCell *cell,
PwrActivity &from_activity, PwrActivity &activity,
float load_cap, float load_cap,
const DcalcAnalysisPt *dcalc_ap, const DcalcAnalysisPt *dcalc_ap,
// Return values. // Return values.
PowerResult &result) PowerResult &result)
{ {
auto internal_pwrs = cell->internalPowers(from_port); auto internal_pwrs = cell->internalPowers(port);
if (!internal_pwrs->empty()) { if (!internal_pwrs->empty()) {
debugPrint3(debug_, "power", 2, "internal input %s/%s (%s)\n", debugPrint3(debug_, "power", 2, "internal input %s/%s (%s)\n",
network_->pathName(inst), network_->pathName(inst),
from_port->name(), port->name(),
cell->name()); cell->name());
const Pvt *pvt = dcalc_ap->operatingConditions(); const Pvt *pvt = dcalc_ap->operatingConditions();
Vertex *vertex = graph_->pinLoadVertex(pin);
debugPrint1(debug_, "power", 2, " cap = %s\n", debugPrint1(debug_, "power", 2, " cap = %s\n",
units_->capacitanceUnit()->asString(load_cap)); units_->capacitanceUnit()->asString(load_cap));
debugPrint0(debug_, "power", 2, " when act/ns duty energy power\n"); debugPrint0(debug_, "power", 2, " when act/ns duty energy power\n");
float internal = 0.0; float internal = 0.0;
for (InternalPower *pwr : *internal_pwrs) { for (InternalPower *pwr : *internal_pwrs) {
const char *related_pg_pin = pwr->relatedPgPin(); const char *related_pg_pin = pwr->relatedPgPin();
FuncExpr *when = pwr->when(); float energy = 0.0;
Vertex *from_vertex = graph_->pinLoadVertex(from_pin); int tr_count = 0;
float duty = evalActivity(when, inst).duty(); for (auto rf : RiseFall::range()) {
float port_energy = 0.0; float slew = delayAsFloat(graph_->slew(vertex, rf,
for (auto from_rf : RiseFall::range()) {
float slew = delayAsFloat(graph_->slew(from_vertex,
from_rf,
dcalc_ap->index())); dcalc_ap->index()));
if (!fuzzyInf(slew)) { if (!fuzzyInf(slew)) {
float table_energy = pwr->power(from_rf, pvt, slew, load_cap); float table_energy = pwr->power(rf, pvt, slew, load_cap);
float tr_energy = table_energy * duty; energy += table_energy;
debugPrint4(debug_, "power", 3, " %s energy = %9.2e * %.2f = %9.2e\n", tr_count++;
from_rf->shortName(),
table_energy,
duty,
tr_energy);
port_energy += tr_energy / 2;
} }
} }
float port_internal = port_energy * from_activity.activity(); if (tr_count)
debugPrint7(debug_, "power", 2, " %s %s %.2f %.2f %9.2e %9.2e %s\n", energy /= tr_count; // average non-inf energies
from_port->name(), float duty = 1.0;
FuncExpr *when = pwr->when();
if (when) {
LibertyPort *out_port = findExprOutPort(when);
if (out_port) {
FuncExpr *func = out_port->function();
// eval cofactor of func wrt inputp
FuncExpr *sensitize_expr = inferedWhen(func, port);
if (sensitize_expr)
duty = evalActivity(sensitize_expr, inst).duty();
else
duty = evalActivity(when, inst).duty();
}
}
float port_internal = energy * duty * activity.activity();
debugPrint7(debug_, "power", 2, " %3s %6s %.2f %.2f %9.2e %9.2e %s\n",
port->name(),
when->asString(), when->asString(),
from_activity.activity() * 1e-9, activity.activity() * 1e-9,
duty, duty,
port_energy, energy,
port_internal, port_internal,
related_pg_pin ? related_pg_pin : "no pg_pin"); related_pg_pin ? related_pg_pin : "no pg_pin");
internal += port_internal; internal += port_internal;
@ -601,6 +610,37 @@ Power::findInputInternalPower(const Pin *from_pin,
} }
} }
LibertyPort *
Power::findExprOutPort(FuncExpr *expr)
{
LibertyPort *port;
switch (expr->op()) {
case FuncExpr::op_port:
port = expr->port();
if (port->direction()->isAnyOutput())
return expr->port();
return nullptr;
case FuncExpr::op_not:
port = findExprOutPort(expr->left());
if (port)
return port;
return nullptr;
case FuncExpr::op_or:
case FuncExpr::op_and:
case FuncExpr::op_xor:
port = findExprOutPort(expr->left());
if (port)
return port;
port = findExprOutPort(expr->right());
if (port)
return port;
return nullptr;
case FuncExpr::op_one:
case FuncExpr::op_zero:
return nullptr;
}
}
void void
Power::findOutputInternalPower(const Pin *to_pin, Power::findOutputInternalPower(const Pin *to_pin,
const LibertyPort *to_port, const LibertyPort *to_port,
@ -619,8 +659,6 @@ Power::findOutputInternalPower(const Pin *to_pin,
const Pvt *pvt = dcalc_ap->operatingConditions(); const Pvt *pvt = dcalc_ap->operatingConditions();
debugPrint1(debug_, "power", 2, " cap = %s\n", debugPrint1(debug_, "power", 2, " cap = %s\n",
units_->capacitanceUnit()->asString(load_cap)); units_->capacitanceUnit()->asString(load_cap));
debugPrint0(debug_, "power", 2, " when act/ns duty wgt energy power\n");
float duty_sum = 0.0; float duty_sum = 0.0;
map<const char*, float, StringLessIf> pg_duty_sum; map<const char*, float, StringLessIf> pg_duty_sum;
for (InternalPower *pwr : *cell->internalPowers(to_port)) { for (InternalPower *pwr : *cell->internalPowers(to_port)) {
@ -689,6 +727,7 @@ Power::findOutputInternalPower(const Pin *to_pin,
duty = 0.5; duty = 0.5;
float energy = 0.0; float energy = 0.0;
int tr_count = 0; int tr_count = 0;
debugPrint0(debug_, "power", 2, " when act/ns duty wgt energy power\n");
for (auto to_rf : RiseFall::range()) { for (auto to_rf : RiseFall::range()) {
// Use unateness to find from_rf. // Use unateness to find from_rf.
RiseFall *from_rf = isPositiveUnate(cell, from_port, to_port) RiseFall *from_rf = isPositiveUnate(cell, from_port, to_port)
@ -702,10 +741,11 @@ Power::findOutputInternalPower(const Pin *to_pin,
tr_count++; tr_count++;
} }
} }
energy /= tr_count; // average non-inf energies if (tr_count)
energy /= tr_count; // average non-inf energies
float weight = duty / pg_duty_sum[related_pg_pin]; float weight = duty / pg_duty_sum[related_pg_pin];
float port_internal = weight * energy * to_activity.activity(); float port_internal = weight * energy * to_activity.activity();
debugPrint9(debug_, "power", 2, " %s -> %s %6s %.2f %.2f %.2f %9.2e %9.2e %s\n", debugPrint9(debug_, "power", 2, "%3s -> %-3s %6s %.2f %.2f %.2f %9.2e %9.2e %s\n",
from_port->name(), from_port->name(),
to_port->name(), to_port->name(),
when ? when->asString() : (infered_when ? infered_when->asString() : " "), when ? when->asString() : (infered_when ? infered_when->asString() : " "),