report_power internal power

This commit is contained in:
James Cherry 2019-02-18 10:56:38 -08:00
parent bbd18d7bed
commit 63b5d9dd86
5 changed files with 81 additions and 55 deletions

View File

@ -1683,7 +1683,10 @@ DmpCeffDelayCalc::ceff(const LibertyCell *drvr_cell,
gateDelay(drvr_cell, arc, in_slew, load_cap,
drvr_parasitic, related_out_cap, pvt, dcalc_ap,
gate_delay, drvr_slew);
return ceff();
if (dmp_alg_)
return static_cast<float>(dmp_alg_->ceff());
else
return load_cap;
}
void
@ -1706,7 +1709,7 @@ DmpCeffDelayCalc::reportGateDelay(const LibertyCell *drvr_cell,
GateTimingModel *model = gateModel(arc, dcalc_ap);
float c_eff = 0.0;
if (drvr_parasitic_ && dmp_alg_) {
c_eff = ceff();
c_eff = dmp_alg_->ceff();
const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary();
const Units *units = drvr_library->units();
const Unit *cap_unit = units->capacitanceUnit();
@ -1772,15 +1775,6 @@ DmpCeffDelayCalc::loadDelaySlew(const Pin *load_pin,
dmp_alg_->loadDelaySlew(load_pin, elmore, delay, slew);
}
float
DmpCeffDelayCalc::ceff() const
{
if (dmp_alg_)
return static_cast<float>(dmp_alg_->ceff());
else
return 0.0;
}
// Notify algorithm components.
void
DmpCeffDelayCalc::copyState(const StaState *sta)

View File

@ -87,7 +87,6 @@ protected:
double c2,
double rpi,
double c1);
float ceff() const;
bool input_port_;
static bool unsuppored_model_warned_;

View File

@ -50,6 +50,9 @@
namespace sta {
typedef std::pair<float, int> SumCount;
typedef Map<const char*, SumCount, CharPtrLess> SupplySumCounts;
Power::Power(Sta *sta) :
StaState(sta),
sta_(sta),
@ -141,7 +144,7 @@ Power::power(const Instance *inst,
findSwitchingPower(cell, to_port, activity1, load_cap,
dcalc_ap, result);
}
findInternalPower(inst, cell, to_port, activity1, is_clk,
findInternalPower(inst, cell, to_port, activity1,
load_cap, dcalc_ap, result);
}
delete pin_iter;
@ -153,55 +156,44 @@ Power::findInternalPower(const Instance *inst,
LibertyCell *cell,
const LibertyPort *to_port,
float activity,
bool is_clk,
float load_cap,
const DcalcAnalysisPt *dcalc_ap,
// Return values.
PowerResult &result)
{
debugPrint3(debug_, "power", 2, "internal %s/%s %ss\n",
debugPrint3(debug_, "power", 2, "internal %s/%s (%s)\n",
network_->pathName(inst),
to_port->name(),
cell->name());
float port_internal = 0.0;
SupplySumCounts supply_sum_counts;
const Pvt *pvt = dcalc_ap->operatingConditions();
float volt = voltage(cell, to_port, dcalc_ap);
const char *pwr_pin = to_port->relatedPowerPin();
float duty = is_clk ? 1.0 : .5;
debugPrint3(debug_, "power", 2, "cap = %s activity = %.2f/ns duty = %.1f\n",
float duty = 1.0;
debugPrint2(debug_, "power", 2, " cap = %s duty = %.1f\n",
units_->capacitanceUnit()->asString(load_cap),
activity * 1e-9,
duty);
LibertyCellInternalPowerIterator pwr_iter(cell);
while (pwr_iter.hasNext()) {
InternalPower *pwr = pwr_iter.next();
const char *related_pg_pin = pwr->relatedPgPin();
if (pwr->port() == to_port
&& ((related_pg_pin == NULL || pwr_pin == NULL)
|| stringEqual(related_pg_pin, pwr_pin))) {
const LibertyPort *from_port = pwr->relatedPort();
const LibertyPort *from_port = pwr->relatedPort();
if (pwr->port() == to_port) {
if (from_port == NULL)
from_port = to_port;
const Pin *from_pin = network_->findPin(inst, from_port);
Vertex *from_vertex = graph_->pinLoadVertex(from_pin);
float port_internal = 0.0;
TransRiseFallIterator tr_iter;
while (tr_iter.hasNext()) {
TransRiseFall *to_tr = tr_iter.next();
// Need unateness to find from_tr.
// Should use unateness to find from_tr.
float slew = delayAsFloat(sta_->vertexSlew(from_vertex,
to_tr, dcalc_ap));
float energy, tr_internal;
if (from_port) {
float energy1 = pwr->power(to_tr, pvt, slew, load_cap);
// Scale by voltage and rise/fall transition count.
energy = energy1 * volt / 2.0;
}
else {
float energy1 = pwr->power(to_tr, pvt, 0.0, 0.0);
// Scale by voltage and rise/fall transition count.
energy = energy1 * volt / 2.0;
}
tr_internal = energy * activity * duty;
float energy;
if (from_port)
energy = pwr->power(to_tr, pvt, slew, load_cap);
else
energy = pwr->power(to_tr, pvt, 0.0, 0.0);
float tr_internal = energy * activity * duty;
port_internal += tr_internal;
debugPrint5(debug_, "power", 2, " %s -> %s %s %s (%s)\n",
from_port->name(),
@ -209,15 +201,30 @@ Power::findInternalPower(const Instance *inst,
to_port->name(),
pwr->when() ? pwr->when()->asString() : "",
related_pg_pin ? related_pg_pin : "");
debugPrint3(debug_, "power", 2, " slew = %s energy = %.5g pwr = %.5g\n",
debugPrint4(debug_, "power", 2, " slew = %s activity = %.2f/ns energy = %.5g pwr = %.5g\n",
units_->timeUnit()->asString(slew),
activity * 1e-9,
energy,
tr_internal);
}
// Sum/count internal power arcs by supply to average across conditions.
SumCount &supply_sum_count = supply_sum_counts[related_pg_pin];
// Average rise/fall internal power.
supply_sum_count.first += port_internal / 2.0;
supply_sum_count.second++;
}
}
debugPrint1(debug_, "power", 2, " internal = %.5g\n", port_internal);
result.setInternal(result.internal() + port_internal);
float internal = 0.0;
SupplySumCounts::Iterator supply_iter(supply_sum_counts);
while (supply_iter.hasNext()) {
const SumCount &supply_cum_count = supply_iter.next();
float supply_internal = supply_cum_count.first;
int supply_count = supply_cum_count.second;
internal += supply_internal / (supply_count > 0 ? supply_count : 1);
}
debugPrint1(debug_, "power", 2, " internal = %.5g\n", internal);
result.setInternal(result.internal() + internal);
}
float

View File

@ -53,7 +53,6 @@ protected:
LibertyCell *cell,
const LibertyPort *to_port,
float activity,
bool is_clk,
float load_cap,
const DcalcAnalysisPt *dcalc_ap,
// Return values.

View File

@ -43,10 +43,7 @@ proc_redirect report_power {
if { [info exists keys(-instances)] } {
set insts [get_instances_error "-instances" $keys(-instances)]
foreach inst $insts {
report_power_inst $inst $corner $digits
puts ""
}
report_power_insts $insts $corner $digits
} else {
report_power_design $corner $digits
}
@ -54,16 +51,16 @@ proc_redirect report_power {
proc report_power_design { corner digits } {
set power_result [design_power $corner]
puts "Group Internal Switching Leakage Total"
puts " Power Power Power Power (mW)"
puts "-------------------------------------------------------------------"
set totals [lrange $power_result 0 3]
set sequential [lrange $power_result 4 7]
set combinational [lrange $power_result 8 11]
set macro [lrange $power_result 12 15]
set pad [lrange $power_result 16 end]
lassign $totals design_internal design_switching design_leakage design_total
puts "Group Internal Switching Leakage Total"
puts " Power Power Power Power (mW)"
puts "-------------------------------------------------------------------"
report_power_row "Sequential" $sequential $design_total $digits
report_power_row "Combinational" $combinational $design_total $digits
report_power_row "Macro" $macro $design_total $digits
@ -106,14 +103,46 @@ proc report_power_col_percent { col_total total } {
puts -nonewline [format "%9.1f%%" $percent]
}
proc report_power_inst { inst corner digits } {
proc report_power_line { type pwr digits } {
puts [format "%-16s %.${digits}fmW" $type [expr $pwr * 1e+3]]
}
proc report_power_insts { insts corner digits } {
set inst_pwrs {}
foreach inst $insts {
set power_result [instance_power $inst $corner]
lappend inst_pwrs [list $inst $power_result]
}
set inst_pwrs [lsort -command inst_pwr_cmp $inst_pwrs]
foreach inst_pwr $inst_pwrs {
set inst [lindex $inst_pwr 0]
set power [lindex $inst_pwr 1]
report_power_inst $inst $power $digits
puts ""
}
}
proc inst_pwr_cmp { inst_pwr1 inst_pwr2 } {
set pwr1 [lindex $inst_pwr1 1]
set pwr2 [lindex $inst_pwr2 1]
lassign $pwr1 internal1 switching1 leakage1 total1
lassign $pwr2 internal2 switching2 leakage2 total2
if { $total1 < $total2 } {
return 1
} elseif { $total1 == $total2 } {
return 0
} else {
return -1
}
}
proc report_power_inst { inst power_result digits } {
puts "Instance: [get_full_name $inst]"
set cell [get_property $inst "liberty_cell"]
if { $cell != "NULL" } {
puts "Cell: [get_name $cell]"
set library [get_property $cell "library"]
puts "Library file: [get_property $library filename]"
set power_result [instance_power $inst $corner]
lassign $power_result internal switching leakage total
report_power_line "Internal power" $internal $digits
report_power_line "Switching power" $switching $digits
@ -124,9 +153,7 @@ proc report_power_inst { inst corner digits } {
}
}
proc report_power_line { type pwr digits } {
puts [format "%-16s %.${digits}fmW" $type [expr $pwr * 1e+3]]
}
################################################################
set ::power_default_signal_toggle_rate 0.1