diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index b9516786..adfee96a 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 7aa1f055..5c1a51e6 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index fa735883..f42fe4e2 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -892,7 +892,8 @@ public: bool report_net, bool report_cap, bool report_slew, - bool report_fanout); + bool report_fanout, + bool report_src_attr); ReportField *findReportPathField(const char *name); void setReportPathDigits(int digits); void setReportPathNoSplit(bool no_split); diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 1a773740..04e9d71b 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -122,7 +122,7 @@ ReportPath::ReportPath(StaState *sta) : { setDigits(2); makeFields(); - setReportFields(false, false, false, false, false); + setReportFields(false, false, false, false, false, false); } ReportPath::~ReportPath() @@ -133,6 +133,7 @@ ReportPath::~ReportPath() delete field_capacitance_; delete field_slew_; delete field_fanout_; + delete field_src_attr_; delete field_edge_; delete field_case_; @@ -156,6 +157,8 @@ ReportPath::makeFields() field_case_ = makeField("case", "case", 11, false, nullptr, false); field_description_ = makeField("description", "Description", 36, true, nullptr, true); + field_src_attr_ = makeField("src_attr", "Src Attr", 40, + true, nullptr, true); } ReportField * @@ -225,15 +228,16 @@ ReportPath::setReportFields(bool report_input_pin, bool report_net, bool report_cap, bool report_slew, - bool report_fanout) + bool report_fanout, + bool report_src_attr) { report_input_pin_ = report_input_pin; report_net_ = report_net; - field_fanout_->setEnabled(report_net_); field_capacitance_->setEnabled(report_cap); field_slew_->setEnabled(report_slew); field_fanout_->setEnabled(report_fanout); + field_src_attr_->setEnabled(report_src_attr); // for debug field_case_->setEnabled(false); } @@ -2404,11 +2408,16 @@ ReportPath::reportPathLine(const Path *path, DcalcAPIndex ap_index = dcalc_ap->index(); Slew slew = graph_->slew(vertex, rf, ap_index); float cap = field_blank_; + Instance *inst = network_->instance(pin); + string src_attr = ""; + if (inst) + src_attr = network_->getAttribute(inst, "src"); // Don't show capacitance field for input pins. if (is_driver && field_capacitance_->enabled()) cap = graph_delay_calc_->loadCap(pin, rf, dcalc_ap); reportLine(what.c_str(), cap, slew, field_blank_, - incr, time, false, early_late, rf, line_case); + incr, time, false, early_late, rf, src_attr, + line_case); } void @@ -2664,6 +2673,10 @@ ReportPath::reportPath5(const Path *path, const char *line_case = nullptr; bool is_clk_start = path1->vertex(this) == clk_start; bool is_clk = path1->isClock(search_); + Instance *inst = network_->instance(pin); + string src_attr = ""; + if (inst) + src_attr = network_->getAttribute(inst, "src"); // Always show the search start point (register clk pin). // Skip reporting the clk tree unless it is requested. if (is_clk_start @@ -2759,7 +2772,8 @@ ReportPath::reportPath5(const Path *path, auto what = descriptionField(vertex); if (report_net_ && is_driver) { reportLine(what.c_str(), cap, slew, fanout, - incr, time, false, min_max, rf, line_case); + incr, time, false, min_max, rf, + src_attr, line_case); string what2; if (network_->isTopLevelPort(pin)) { const char *pin_name = cmd_network_->pathName(pin); @@ -2777,11 +2791,12 @@ ReportPath::reportPath5(const Path *path, } reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, false, min_max, - nullptr, line_case); + nullptr, src_attr, line_case); } else reportLine(what.c_str(), cap, slew, fanout, - incr, time, false, min_max, rf, line_case); + incr, time, false, min_max, rf, src_attr, + line_case); prev_time = time; } } @@ -2965,7 +2980,8 @@ ReportPath::reportLine(const char *what, const EarlyLate *early_late) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, false, early_late, nullptr, nullptr); + field_blank_, total, false, early_late, nullptr, + "", nullptr); } // Report negative total. @@ -2975,7 +2991,8 @@ ReportPath::reportLineNegative(const char *what, const EarlyLate *early_late) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, true, early_late, nullptr, nullptr); + field_blank_, total, true, early_late, nullptr, + "", nullptr); } // Report total, and transition suffix. @@ -2986,7 +3003,8 @@ ReportPath::reportLine(const char *what, const RiseFall *rf) { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, total, false, early_late, rf, nullptr); + field_blank_, total, false, early_late, rf, "", + nullptr); } // Report increment, and total. @@ -2997,7 +3015,8 @@ ReportPath::reportLine(const char *what, const EarlyLate *early_late) { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, total, false, early_late, nullptr, nullptr); + incr, total, false, early_late, nullptr, "", + nullptr); } // Report increment, total, and transition suffix. @@ -3009,7 +3028,8 @@ ReportPath::reportLine(const char *what, const RiseFall *rf) { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, total, false, early_late, rf, nullptr); + incr, total, false, early_late, rf, "", + nullptr); } // Report slew, increment, and total. @@ -3021,7 +3041,8 @@ ReportPath::reportLine(const char *what, const EarlyLate *early_late) { reportLine(what, field_blank_, slew, field_blank_, - incr, total, false, early_late, nullptr, nullptr); + incr, total, false, early_late, nullptr, + "", nullptr); } void @@ -3034,6 +3055,7 @@ ReportPath::reportLine(const char *what, bool total_with_minus, const EarlyLate *early_late, const RiseFall *rf, + string src_attr, const char *line_case) { ReportFieldSeq::Iterator field_iter(fields_); @@ -3073,8 +3095,13 @@ ReportPath::reportLine(const char *what, else if (field == field_edge_) { if (rf) reportField(rf->shortName(), field, line); - // Compatibility kludge; suppress trailing spaces. - else if (field_iter.hasNext()) + else + reportFieldBlank(field, line); + } + else if (field == field_src_attr_) { + if (src_attr != "") + reportField(src_attr.c_str(), field, line); + else reportFieldBlank(field, line); } else if (field == field_case_ && line_case) @@ -3084,7 +3111,10 @@ ReportPath::reportLine(const char *what, } field_index++; } - report_->reportLineString(line); + // Trim trailing spaces and report the line. + string line_stdstr = line; + trimRight(line_stdstr); + report_->reportLineString(line_stdstr.c_str()); } //////////////////////////////////////////////////////////////// diff --git a/search/ReportPath.hh b/search/ReportPath.hh index 90cd9bd1..e86b7e2a 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -44,7 +44,8 @@ public: bool report_net, bool report_cap, bool report_slew, - bool report_fanout); + bool report_fanout, + bool report_src_attr); int digits() const { return digits_; } void setDigits(int digits); void setNoSplit(bool no_split); @@ -148,6 +149,7 @@ public: 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(); @@ -349,6 +351,7 @@ protected: bool total_with_minus, const EarlyLate *early_late, const RiseFall *rf, + string src_attr, const char *line_case); void reportLineTotal(const char *what, Delay incr, @@ -465,6 +468,7 @@ protected: ReportField *field_capacitance_; ReportField *field_slew_; ReportField *field_fanout_; + ReportField *field_src_attr_; ReportField *field_edge_; ReportField *field_case_; diff --git a/search/Search.i b/search/Search.i index e90f03a8..af12f7ea 100644 --- a/search/Search.i +++ b/search/Search.i @@ -504,13 +504,15 @@ set_report_path_fields(bool report_input_pin, bool report_net, bool report_cap, bool report_slew, - bool report_fanout) + bool report_fanout, + bool report_src_attr) { Sta::sta()->setReportPathFields(report_input_pin, report_net, report_cap, report_slew, - report_fanout); + report_fanout, + report_src_attr); } void diff --git a/search/Search.tcl b/search/Search.tcl index 76689129..381da541 100644 --- a/search/Search.tcl +++ b/search/Search.tcl @@ -401,8 +401,8 @@ define_cmd_args "report_checks" \ [-slack_min slack_min]\ [-sort_by_slack]\ [-path_group group_name]\ - [-format full|full_clock|full_clock_expanded|short|end|summary]\ - [-fields capacitance|slew|input_pin|net]\ + [-format full|full_clock|full_clock_expanded|short|end|slack_only|summary|json]\ + [-fields capacitance|slew|input_pin|net|src_attr]\ [-digits digits]\ [-no_line_splits]\ [> filename] [>> filename]} @@ -903,15 +903,17 @@ proc parse_report_path_options { cmd args_var default_format set report_net [expr [lsearch $fields "net*"] != -1] set report_slew [expr [lsearch $fields "slew*"] != -1] set report_fanout [expr [lsearch $fields "fanout*"] != -1] + set report_src_attr [expr [lsearch $fields "src_attr*"] != -1] } else { set report_input_pin 0 set report_cap 0 set report_net 0 set report_slew 0 set report_fanout 0 + set report_src_attr 0 } set_report_path_fields $report_input_pin $report_net \ - $report_cap $report_slew $report_fanout + $report_cap $report_slew $report_fanout $report_src_attr set_report_path_no_split [info exists path_options(-no_line_splits)] } diff --git a/search/Sta.cc b/search/Sta.cc index 175d1215..5ca62620 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2488,10 +2488,11 @@ Sta::setReportPathFields(bool report_input_pin, bool report_net, bool report_cap, bool report_slew, - bool report_fanout) + bool report_fanout, + bool report_src_attr) { report_path_->setReportFields(report_input_pin, report_net, report_cap, - report_slew, report_fanout); + report_slew, report_fanout, report_src_attr); } ReportField * diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index e19cf59c..c97102f1 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -129,6 +129,7 @@ record_sta_tests { get_filter get_noargs get_objrefs + report_checks_src_attr } define_test_group fast [group_tests all] diff --git a/test/report_checks_src_attr.ok b/test/report_checks_src_attr.ok new file mode 100644 index 00000000..f830cbe9 --- /dev/null +++ b/test/report_checks_src_attr.ok @@ -0,0 +1,28 @@ +Startpoint: in (input port clocked by clk) +Endpoint: _1415_ (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Cap Slew Delay Time Description Src Attr +--------------------------------------------------------------------------------------------------------------- + 0.00 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 v input external delay + 0.00 0.00 0.00 0.00 v in (in) + in (net) + 0.00 0.00 0.00 v _1415_/D (sky130_fd_sc_hd__dfrtp_1) synthesis/tests/counter.v:22.3-28.6 + 0.00 data arrival time + + 0.00 10.00 10.00 clock clk (rise edge) + 0.00 10.00 clock network delay (ideal) + 0.00 10.00 clock reconvergence pessimism + 10.00 ^ _1415_/CLK (sky130_fd_sc_hd__dfrtp_1) + -0.10 9.90 library setup time + 9.90 data required time +--------------------------------------------------------------------------------------------------------------- + 9.90 data required time + -0.00 data arrival time +--------------------------------------------------------------------------------------------------------------- + 9.90 slack (MET) + + diff --git a/test/report_checks_src_attr.tcl b/test/report_checks_src_attr.tcl new file mode 100644 index 00000000..baa67b22 --- /dev/null +++ b/test/report_checks_src_attr.tcl @@ -0,0 +1,7 @@ +# report_checks all fields enabled +read_liberty ../examples/sky130hd_tt.lib.gz +read_verilog verilog_attribute.v +link_design counter +create_clock -name clk -period 10 clk +set_input_delay -clock clk 0 [all_inputs -no_clocks] +report_checks -path_group clk -fields {capacitance slew input_pin net src_attr}