// OpenSTA, Static Timing Analyzer // Copyright (c) 2025, 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. #pragma once #include #include "StringSeq.hh" #include "SearchClass.hh" #include "PathEnd.hh" namespace sta { class Corner; class DcalcAnalysisPt; class PathExpanded; class ReportField; typedef Vector ReportFieldSeq; class ReportPath : public StaState { public: ReportPath(StaState *sta); virtual ~ReportPath(); ReportPathFormat pathFormat() const { return format_; } void setPathFormat(ReportPathFormat format); void setReportFieldOrder(StringSeq *field_names); void setReportFields(bool report_input_pin, bool report_hier_pins, bool report_net, bool report_cap, bool report_slew, bool report_fanout, bool report_src_attr); int digits() const { return digits_; } void setDigits(int digits); void setNoSplit(bool no_split); bool reportSigmas() const { return report_sigmas_; } void setReportSigmas(bool report); ReportField *findField(const char *name) const; // Header above reportPathEnd results. void reportPathEndHeader() const; // Footer below reportPathEnd results. void reportPathEndFooter() const; void reportPathEnd(const PathEnd *end) const; // Format report_path_endpoint only: // Previous path end is used to detect path group changes // so headers are reported by group. void reportPathEnd(const PathEnd *end, const PathEnd *prev_end, bool last) const; void reportPathEnds(const PathEndSeq *ends) const; void reportPath(const Path *path) const; void reportShort(const PathEndUnconstrained *end) const; void reportShort(const PathEndCheck *end) const; void reportShort(const PathEndLatchCheck *end) const; void reportShort(const PathEndPathDelay *end) const; void reportShort(const PathEndOutputDelay *end) const; void reportShort(const PathEndGatedClock *end) const; void reportShort(const PathEndDataCheck *end) const; void reportFull(const PathEndUnconstrained *end) const; void reportFull(const PathEndCheck *end) const; void reportFull(const PathEndLatchCheck *end) const; void reportFull(const PathEndPathDelay *end) const; void reportFull(const PathEndOutputDelay *end) const; void reportFull(const PathEndGatedClock *end) const; void reportFull(const PathEndDataCheck *end) const; void reportJsonHeader() const; void reportJsonFooter() const; void reportJson(const PathEnd *end, bool last) const; void reportJson(const Path *path) const; void reportJson(const Path *path, const char *path_name, int indent, bool trailing_comma, std::string &result) const; void reportJson(const PathExpanded &expanded, const char *path_name, int indent, bool trailing_comma, std::string &result) const; void reportEndHeader() const; void reportEndLine(const PathEnd *end) const; void reportSummaryHeader() const; void reportSummaryLine(const PathEnd *end) const; void reportSlackOnlyHeader() const; void reportSlackOnly(const PathEnd *end) const; void reportMpwCheck(const MinPulseWidthCheck *check, bool verbose) const; void reportMpwChecks(const MinPulseWidthCheckSeq *checks, bool verbose) const; void reportMpwHeaderShort() const; void reportShort(const MinPulseWidthCheck *check) const; void reportVerbose(const MinPulseWidthCheck *check) const; void reportCheck(const MinPeriodCheck *check, bool verbose) const; void reportChecks(const MinPeriodCheckSeq *checks, bool verbose) const; void reportPeriodHeaderShort() const; void reportShort(const MinPeriodCheck *check) const; void reportVerbose(const MinPeriodCheck *check) const; void reportCheck(const MaxSkewCheck *check, bool verbose) const; void reportChecks(const MaxSkewCheckSeq *checks, bool verbose) const; void reportMaxSkewHeaderShort() const; void reportShort(const MaxSkewCheck *check) const; void reportVerbose(const MaxSkewCheck *check) const; void reportLimitShortHeader(const ReportField *field) const; void reportLimitShort(const ReportField *field, Pin *pin, float value, float limit, float slack) const; void reportLimitVerbose(const ReportField *field, Pin *pin, const RiseFall *rf, float value, float limit, float slack, const Corner *corner, const MinMax *min_max) const; ReportField *fieldSlew() const { return field_slew_; } ReportField *fieldFanout() const { return field_fanout_; } ReportField *fieldCapacitance() const { return field_capacitance_; } ReportField *fieldSrcAttr() const { return field_src_attr_; } protected: void makeFields(); ReportField *makeField(const char *name, const char *title, int width, bool left_justify, Unit *unit, bool enabled); void reportEndpointHeader(const PathEnd *end, const PathEnd *prev_end) const; void reportShort(const PathEndUnconstrained *end, const PathExpanded &expanded) const; void reportShort(const PathEndCheck *end, const PathExpanded &expanded) const; void reportShort(const PathEndLatchCheck *end, const PathExpanded &expanded) const; void reportShort(const PathEndPathDelay *end, const PathExpanded &expanded) const; void reportShort(const PathEndOutputDelay *end, const PathExpanded &expanded) const; void reportShort(const PathEndGatedClock *end, const PathExpanded &expanded) const; void reportShort(const PathEndDataCheck *end, const PathExpanded &expanded) const; void reportEndpoint(const PathEndOutputDelay *end) const; void reportEndpointOutputDelay(const PathEndClkConstrained *end) const; void reportEndpoint(const PathEndPathDelay *end) const; void reportEndpoint(const PathEndGatedClock *end) const; std::string pathEndpoint(const PathEnd *end) const; std::string pathStartpoint(const PathEnd *end, const PathExpanded &expanded) const; void reportBorrowing(const PathEndLatchCheck *end, Arrival &borrow, Arrival &time_given_to_startpoint) const; void reportEndpoint(const PathEndDataCheck *end) const; const char *clkNetworkDelayIdealProp(bool is_ideal) const; std::string checkRoleReason(const PathEnd *end) const; std::string checkRoleString(const PathEnd *end) const; virtual void reportGroup(const PathEnd *end) const; void reportStartpoint(const PathEnd *end, const PathExpanded &expanded) const; void reportUnclockedEndpoint(const PathEnd *end, const char *default_reason) const; void reportEndpoint(const PathEndCheck *end) const; void reportEndpoint(const PathEndLatchCheck *end) const; const char *latchDesc(const PathEndLatchCheck *end) const; void reportStartpoint(const char *start, const std::string reason) const; void reportEndpoint(const char *end, const std::string reason) const; void reportStartEndPoint(const char *pt, const std::string reason, const char *key) const; std::string tgtClkName(const PathEnd *end) const; const char *clkRegLatchDesc(const PathEnd *end) const; void reportSrcPath(const PathEnd *end, const PathExpanded &expanded) const; void reportTgtClk(const PathEnd *end) const; void reportTgtClk(const PathEnd *end, float prev_time) const; void reportTgtClk(const PathEnd *end, float prev_time, bool is_prop) const; void reportTgtClk(const PathEnd *end, float prev_time, float src_offset, bool is_prop) const; bool pathFromGenPropClk(const Path *clk_path, const EarlyLate *early_late) const; bool isGenPropClk(const Clock *clk, const RiseFall *clk_rf, const MinMax *min_max, const EarlyLate *early_late) const; void reportSrcClkAndPath(const Path *path, const PathExpanded &expanded, float time_offset, Arrival clk_insertion, Arrival clk_latency, bool is_path_delay) const; bool reportGenClkSrcPath(const Path *clk_path, const Clock *clk, const RiseFall *clk_rf, const MinMax *min_max, const EarlyLate *early_late) const; void reportGenClkSrcAndPath(const Path *path, const Clock *clk, const RiseFall *clk_rf, const EarlyLate *early_late, const PathAnalysisPt *path_ap, float time_offset, float path_time_offset, bool clk_used_as_data) const; bool reportGenClkSrcPath1(const Clock *clk, const Pin *clk_pin, const RiseFall *clk_rf, const EarlyLate *early_late, const PathAnalysisPt *path_ap, float gclk_time, float time_offset, bool clk_used_as_data) const; void reportClkSrcLatency(Arrival insertion, float clk_time, const EarlyLate *early_late) const; void reportPathLine(const Path *path, Delay incr, Arrival time, const char *line_case) const; void reportCommonClkPessimism(const PathEnd *end, Arrival &clk_arrival) const ; void reportClkUncertainty(const PathEnd *end, Arrival &clk_arrival) const ; void reportClkLine(const Clock *clk, const char *clk_name, const RiseFall *clk_rf, Arrival clk_time, const MinMax *min_max) const ; void reportClkLine(const Clock *clk, const char *clk_name, const RiseFall *clk_rf, Arrival prev_time, Arrival clk_time, const MinMax *min_max) const ; void reportRequired(const PathEnd *end, std::string margin_msg) const ; void reportSlack(const PathEnd *end) const ; void reportSlack(Slack slack) const ; void reportSpaceSlack(const PathEnd *end, std::string &line) const ; void reportSpaceSlack(Slack slack, std::string &line) const ; void reportSrcPathArrival(const PathEnd *end, const PathExpanded &expanded) const ; void reportPath(const PathEnd *end, const PathExpanded &expanded) const; void reportPathFull(const Path *path) const; void reportPathHeader() const; void reportPath1(const Path *path, const PathExpanded &expanded, bool clk_used_as_data, float time_offset) const; void reportPath2(const Path *path, const PathExpanded &expanded, bool clk_used_as_data, float time_offset) const; void reportPath3(const Path *path, const PathExpanded &expanded, bool clk_used_as_data, bool report_clk_path, Arrival prev_time, float time_offset) const; void reportPath4(const Path *path, const PathExpanded &expanded, bool clk_used_as_data, bool skip_first_path, bool skip_last_path, float time_offset) const; void reportPath5(const Path *path, const PathExpanded &expanded, size_t path_first_index, size_t path_last_index, bool propagated_clk, bool report_clk_path, Arrival prev_time, float time_offset) const; void reportHierPinsThru(const Path *path) const; void reportInputExternalDelay(const Path *path, float time_offset) const; void reportLine(const char *what, Delay total, const EarlyLate *early_late) const; void reportLineNegative(const char *what, Delay total, const EarlyLate *early_late) const; void reportLine(const char *what, Delay total, const EarlyLate *early_late, const RiseFall *rf) const; void reportLine(const char *what, Delay incr, Delay total, const EarlyLate *early_late) const; void reportLine(const char *what, Delay incr, Delay total, const EarlyLate *early_late, const RiseFall *rf) const; void reportLine(const char *what, Slew slew, Delay incr, Delay total, const EarlyLate *early_late) const; void reportLine(const char *what, float cap, Slew slew, float fanout, Delay incr, Delay total, bool total_with_minus, const EarlyLate *early_late, const RiseFall *rf, std::string src_attr, const char *line_case) const; void reportLineTotal(const char *what, Delay incr, const EarlyLate *early_late) const; void reportLineTotalMinus(const char *what, Delay decr, const EarlyLate *early_late) const; void reportLineTotal1(const char *what, Delay incr, bool incr_with_minus, const EarlyLate *early_late) const; void reportDashLineTotal() const; void reportDescription(const char *what, std::string &result) const; void reportDescription(const char *what, bool first_field, bool last_field, std::string &result) const; void reportFieldTime(float value, ReportField *field, std::string &result) const; void reportSpaceFieldTime(float value, std::string &result) const; void reportSpaceFieldDelay(Delay value, const EarlyLate *early_late, std::string &result) const; void reportFieldDelayMinus(Delay value, const EarlyLate *early_late, const ReportField *field, std::string &result) const; void reportTotalDelay(Delay value, const EarlyLate *early_late, std::string &result) const; void reportFieldDelay(Delay value, const EarlyLate *early_late, const ReportField *field, std::string &result) const; void reportField(float value, const ReportField *field, std::string &result) const; void reportField(const char *value, const ReportField *field, std::string &result) const; void reportFieldBlank(const ReportField *field, std::string &result) const; void reportDashLine() const; void reportDashLine(int line_width) const; void reportBlankLine() const; std::string descriptionField(const Vertex *vertex) const; std::string descriptionField(const Pin *pin) const; std::string descriptionNet(const Pin *pin) const; bool reportClkPath() const; std::string clkName(const Clock *clk, bool inverted) const; bool hasExtInputDriver(const Pin *pin, const RiseFall *rf, const MinMax *min_max) const; float drvrFanout(Vertex *drvr, const Corner *corner, const MinMax *min_max) const; const char *mpwCheckHiLow(const MinPulseWidthCheck *check) const; void reportSkewClkPath(const char *arrival_msg, const Path *clk_path) const; const char *edgeRegLatchDesc(const Edge *edge, const TimingArc *arc) const; const char *checkRegLatchDesc(const TimingRole *role, const RiseFall *clk_rf) const; const char *regDesc(const RiseFall *clk_rf) const; const char *latchDesc(const RiseFall *clk_rf) const; void pathClkPath(const Path *path, const Path &clk_path) const; bool isPropagated(const Path *clk_path) const; bool isPropagated(const Path *clk_path, const Clock *clk) const; bool pathFromClkPin(const PathExpanded &expanded) const; bool pathFromClkPin(const Path *path, const Pin *start_pin) const; void latchPaths(const Path *path, // Return values. Path &d_path, Path &q_path, Edge *&d_q_edge) const; bool nextArcAnnotated(const Path *next_path, size_t next_index, const PathExpanded &expanded, DcalcAPIndex ap_index) const; float tgtClkInsertionOffet(const Path *clk_path, const EarlyLate *early_late, const PathAnalysisPt *path_ap) const; // InputDelay used to seed path root. InputDelay *pathInputDelay(const Path *path) const; void pathInputDelayRefPath(const Path *path, const InputDelay *input_delay, // Return value. Path &ref_path) const; const char *asRisingFalling(const RiseFall *rf) const; const char *asRiseFall(const RiseFall *rf) const; Delay delayIncr(Delay time, Delay prev, const MinMax *min_max) const; // Path options. ReportPathFormat format_; ReportFieldSeq fields_; bool report_input_pin_; bool report_hier_pins_; bool report_net_; bool no_split_; int digits_; bool report_sigmas_; int start_end_pt_width_; ReportField *field_description_; ReportField *field_total_; ReportField *field_incr_; ReportField *field_capacitance_; ReportField *field_slew_; ReportField *field_fanout_; ReportField *field_src_attr_; ReportField *field_edge_; ReportField *field_case_; const char *plus_zero_; const char *minus_zero_; static const float field_blank_; static const float field_skip_; }; class ReportField { public: ReportField(const char *name, const char *title, int width, bool left_justify, Unit *unit, bool enabled); ~ReportField(); void setProperties(const char *title, int width, bool left_justify); const char *name() const { return name_; } const char *title() const { return title_; } int width() const { return width_; } void setWidth(int width); bool leftJustify() const { return left_justify_; } Unit *unit() const { return unit_; } const char *blank() const { return blank_; } void setEnabled(bool enabled); bool enabled() const { return enabled_; } protected: const char *name_; const char *title_; int width_; bool left_justify_; Unit *unit_; bool enabled_; char *blank_; }; } // namespace