// OpenSTA, Static Timing Analyzer // Copyright (c) 2026, Parallax Software, Inc. // // 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 . // // The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. // // Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // This notice may not be removed or altered from any source distribution. #include "ReportPower.hh" #include #include #include "Report.hh" #include "Network.hh" #include "Format.hh" namespace sta { ReportPower::ReportPower(StaState *sta) : StaState(sta) { } void ReportPower::reportDesign(PowerResult &total, PowerResult &sequential, PowerResult &combinational, PowerResult &clock, PowerResult ¯o, PowerResult &pad, int digits) { float design_internal = total.internal(); float design_switching = total.switching(); float design_leakage = total.leakage(); float design_total = total.total(); int field_width = std::max(digits + 6, 10); reportTitle5("Group", "Internal", "Switching", "Leakage", "Total", field_width); reportTitle5Units(" ", "Power", "Power", "Power", "Power", "(Watts)", field_width); reportTitleDashes5(field_width); reportRow("Sequential", sequential, design_total, field_width, digits); reportRow("Combinational", combinational, design_total, field_width, digits); reportRow("Clock", clock, design_total, field_width, digits); reportRow("Macro", macro, design_total, field_width, digits); reportRow("Pad", pad, design_total, field_width, digits); reportTitleDashes5(field_width); // Report total row using the totals PowerResult reportRow("Total", total, design_total, field_width, digits); // Report percentage line std::string percent_line = sta::format("{:<20}", ""); percent_line += powerColPercent(design_internal, design_total, field_width); percent_line += powerColPercent(design_switching, design_total, field_width); percent_line += powerColPercent(design_leakage, design_total, field_width); report_->reportLine(percent_line); } void ReportPower::reportInsts(const InstPowers &inst_pwrs, int digits) { int field_width = std::max(digits + 6, 10); reportTitle4("Internal", "Switching", "Leakage", "Total", field_width); reportTitle4Units("Power", "Power", "Power", "Power", "(Watts)", field_width); reportTitleDashes4(field_width); for (const InstPower &inst_pwr : inst_pwrs) { reportInst(inst_pwr.first, inst_pwr.second, field_width, digits); } } void ReportPower::reportInst(const Instance *inst, const PowerResult &power, int field_width, int digits) { float internal = power.internal(); float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); std::string line = powerCol(internal, field_width, digits); line += powerCol(switching, field_width, digits); line += powerCol(leakage, field_width, digits); line += powerCol(total, field_width, digits); line += " "; line += network_->pathName(inst); report_->reportLine(line); } std::string ReportPower::powerCol(float pwr, int field_width, int digits) { if (std::isnan(pwr)) return sta::format(" {:>{}}", "NaN", field_width); else return sta::format(" {:{}.{}e}", pwr, field_width, digits); } std::string ReportPower::powerColPercent(float col_total, float total, int field_width) { float percent = 0.0; if (total != 0.0 && !std::isnan(total)) { percent = col_total / total * 100.0; } return sta::format("{:{}.1f}%", percent, field_width); } void ReportPower::reportTitle5(std::string_view title1, std::string_view title2, std::string_view title3, std::string_view title4, std::string_view title5, int field_width) { report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}}", title1, title2, field_width, title3, field_width, title4, field_width, title5, field_width); } void ReportPower::reportTitle5Units(std::string_view title1, std::string_view title2, std::string_view title3, std::string_view title4, std::string_view title5, std::string_view units, int field_width) { report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, title2, field_width, title3, field_width, title4, field_width, title5, field_width, units); } void ReportPower::reportTitleDashes5(int field_width) { int count = 20 + (field_width + 1) * 4; std::string dashes(count, '-'); report_->reportLine(dashes); } void ReportPower::reportRow(std::string_view type, const PowerResult &power, float design_total, int field_width, int digits) { float internal = power.internal(); float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); float percent = 0.0; if (design_total != 0.0 && !std::isnan(design_total)) percent = total / design_total * 100.0; std::string line = sta::format("{:<20}", std::string(type)); line += powerCol(internal, field_width, digits); line += powerCol(switching, field_width, digits); line += powerCol(leakage, field_width, digits); line += powerCol(total, field_width, digits); line += sta::format(" {:5.1f}%", percent); report_->reportLine(line); } void ReportPower::reportTitle4(std::string_view title1, std::string_view title2, std::string_view title3, std::string_view title4, int field_width) { report_->report(" {:>{}} {:>{}} {:>{}} {:>{}}", title1, field_width, title2, field_width, title3, field_width, title4, field_width); } void ReportPower::reportTitle4Units(std::string_view title1, std::string_view title2, std::string_view title3, std::string_view title4, std::string_view units, int field_width) { report_->report(" {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, field_width, title2, field_width, title3, field_width, title4, field_width, units); } void ReportPower::reportTitleDashes4(int field_width) { int count = (field_width + 1) * 4; std::string dashes(count, '-'); report_->reportLine(dashes); } } // namespace sta