From 1def4110c04697a441401fd1bbc6f65a0a3dae39 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Wed, 19 Jun 2019 07:55:04 -0700 Subject: [PATCH] report_power NaN --- search/Power.cc | 122 +++++++++++++++++++++++++-------------------- search/Property.cc | 8 ++- tcl/StaTcl.i | 2 +- 3 files changed, 75 insertions(+), 57 deletions(-) diff --git a/search/Power.cc b/search/Power.cc index 2e4e3e97..fe0d1708 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -1,18 +1,10 @@ -// OpenSTA, Static Timing Analyzer +// Parallax Static Timing Analyzer // Copyright (c) 2019, Parallax Software, Inc. +// All rights reserved. // -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// No part of this document may be copied, transmitted or +// disclosed in any form or fashion without the express +// written consent of Parallax Software, Inc. #include // max #include "Machine.hh" @@ -335,6 +327,8 @@ Power::evalActivity(FuncExpr *expr, Pin *pin = network_->findPin(inst, expr->port()->name()); if (pin) return findActivity(pin); + else + return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant); } case FuncExpr::op_not: { PwrActivity activity1 = evalActivity(expr->left(), inst); @@ -528,6 +522,13 @@ Power::findInstClk(const Instance *inst) return inst_clk; } +void +check(float x) +{ + if (std::isnan(x)) + printf("luse\n"); +} + void Power::findInternalPower(const Pin *to_pin, const LibertyPort *to_port, @@ -569,49 +570,62 @@ Power::findInternalPower(const Pin *to_pin, if ((when && internalPowerMissingWhen(cell, to_port, related_pg_pin)) || pgNameVoltage(cell, related_pg_pin, dcalc_ap) != 0.0) { const Pin *from_pin = network_->findPin(inst, from_port); - Vertex *from_vertex = graph_->pinLoadVertex(from_pin); - float duty; - if (infered_when) { - PwrActivity from_activity = findActivity(from_pin); - PwrActivity to_activity = findActivity(to_pin); - float duty1 = evalActivity(infered_when, inst).duty(); - duty = from_activity.activity() / to_activity.activity() * duty1; - } - else if (when) - duty = evalActivity(when, inst).duty(); - else if (search_->isClock(from_vertex)) - duty = 1.0; - else - duty = 0.5; - float port_energy = 0.0; - TransRiseFallIterator tr_iter; - while (tr_iter.hasNext()) { - TransRiseFall *to_tr = tr_iter.next(); - // Should use unateness to find from_tr. - TransRiseFall *from_tr = to_tr; - float slew = delayAsFloat(graph_->slew(from_vertex, - from_tr, - dcalc_ap->index())); - float table_energy = pwr->power(to_tr, pvt, slew, load_cap); - float tr_energy = table_energy * duty; - debugPrint4(debug_, "power", 3, " %s energy = %9.2e * %.2f = %9.2e\n", - to_tr->shortName(), - table_energy, + if (from_pin) { + Vertex *from_vertex = graph_->pinLoadVertex(from_pin); + float duty; + if (infered_when) { + PwrActivity from_activity = findActivity(from_pin); + PwrActivity to_activity = findActivity(to_pin); + float duty1 = evalActivity(infered_when, inst).duty(); + check(from_activity.activity()); + check(to_activity.activity()); + check(duty1); + if (to_activity.activity() == 0.0) + duty = 0.0; + else + duty = from_activity.activity() / to_activity.activity() * duty1; + check(duty); + } + else if (when) + duty = evalActivity(when, inst).duty(); + else if (search_->isClock(from_vertex)) + duty = 1.0; + else + duty = 0.5; + check(duty); + float port_energy = 0.0; + TransRiseFallIterator tr_iter; + while (tr_iter.hasNext()) { + TransRiseFall *to_tr = tr_iter.next(); + // Should use unateness to find from_tr. + TransRiseFall *from_tr = to_tr; + float slew = delayAsFloat(graph_->slew(from_vertex, + from_tr, + dcalc_ap->index())); + float table_energy = pwr->power(to_tr, pvt, slew, load_cap); + float tr_energy = table_energy * duty; + debugPrint4(debug_, "power", 3, " %s energy = %9.2e * %.2f = %9.2e\n", + to_tr->shortName(), + table_energy, + duty, + tr_energy); + check(slew); + check(table_energy); + check(tr_energy); + port_energy += tr_energy; + } + float port_internal = port_energy * to_activity.activity(); + debugPrint8(debug_, "power", 2, " %s -> %s %s %.2f %.2f %9.2e %9.2e %s\n", + from_port->name(), + to_port->name(), + when ? when->asString() : (infered_when ? infered_when->asString() : " "), + to_activity.activity() * 1e-9, duty, - tr_energy); - port_energy += tr_energy; + port_energy, + port_internal, + related_pg_pin ? related_pg_pin : "no pg_pin"); + internal += port_internal; } - float port_internal = port_energy * to_activity.activity(); - debugPrint8(debug_, "power", 2, " %s -> %s %s %.2f %.2f %9.2e %9.2e %s\n", - from_port->name(), - to_port->name(), - when ? when->asString() : (infered_when ? infered_when->asString() : " "), - to_activity.activity() * 1e-9, - duty, - port_energy, - port_internal, - related_pg_pin ? related_pg_pin : "no pg_pin"); - internal += port_internal; } if (infered_when) infered_when->deleteSubexprs(); diff --git a/search/Property.cc b/search/Property.cc index 7598298d..42277efb 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -640,7 +640,7 @@ portSlackProperty(const Port *port, PropertyValue getProperty(const LibertyPort *port, const char *property, - Sta *) + Sta *sta) { if (stringEqual(property, "name")) return PropertyValue(port->name()); @@ -648,6 +648,10 @@ getProperty(const LibertyPort *port, return PropertyValue(port->name()); else if (stringEqual(property, "direction")) return PropertyValue(port->direction()->name()); + else if (stringEqual(property, "capacitance")) { + float cap = port->capacitance(TransRiseFall::rise(), MinMax::max()); + return PropertyValue(sta->units()->capacitanceUnit()->asString(cap, 6)); + } else throw PropertyUnknown("liberty port", property); } @@ -863,7 +867,7 @@ getProperty(Clock *clk, || stringEqual(property, "full_name")) return PropertyValue(clk->name()); else if (stringEqual(property, "period")) - return PropertyValue(sta->units()->timeUnit()->asString(clk->period(), 8)); + return PropertyValue(sta->units()->timeUnit()->asString(clk->period(), 6)); else if (stringEqual(property, "sources")) return PropertyValue(clk->pins()); else if (stringEqual(property, "propagated")) diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 5b2afce1..6bfd8935 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -1533,7 +1533,7 @@ using namespace sta; Tcl_SetResult(interp, const_cast(value.stringValue()), TCL_VOLATILE); break; case PropertyValue::Type::type_float: { - char *float_string = stringPrint("%.5f", value.floatValue()); + char *float_string = stringPrint("%.6e", value.floatValue()); Tcl_SetResult(interp, float_string, TCL_VOLATILE); stringDelete(float_string); }