diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index f7b233da4..ada783017 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1331,6 +1331,9 @@ public: // TCL variable sta_input_port_default_clock. bool useDefaultArrivalClock() const; void setUseDefaultArrivalClock(bool enable); + // TCL variable sta_strip_escaped_bus. + bool stripEscapedBus() const; + void setStripEscapedBus(bool enable); //////////////////////////////////////////////////////////////// Properties &properties() { return properties_; } diff --git a/include/sta/Variables.hh b/include/sta/Variables.hh index 1d60408ec..eaadc6976 100644 --- a/include/sta/Variables.hh +++ b/include/sta/Variables.hh @@ -78,6 +78,9 @@ public: void setUseDefaultArrivalClock(bool enable); bool pocvEnabled() const { return pocv_enabled_; } void setPocvEnabled(bool enabled); + // TCL variable sta_strip_escaped_bus. + bool stripEscapedBus() const { return strip_escaped_bus_; } + void setStripEscapedBus(bool enable) { strip_escaped_bus_ = enable; } private: bool crpr_enabled_; @@ -94,6 +97,7 @@ private: bool propagate_all_clks_; bool use_default_arrival_clock_; bool pocv_enabled_; + bool strip_escaped_bus_; }; } // namespace diff --git a/sdc/Variables.cc b/sdc/Variables.cc index 1cb10bd0a..f5d32ecd5 100644 --- a/sdc/Variables.cc +++ b/sdc/Variables.cc @@ -40,7 +40,8 @@ Variables::Variables() : dynamic_loop_breaking_(false), propagate_all_clks_(false), use_default_arrival_clock_(false), - pocv_enabled_(false) + pocv_enabled_(false), + strip_escaped_bus_(false) { } diff --git a/search/Search.i b/search/Search.i index 3e2e761aa..fcd97ae8c 100644 --- a/search/Search.i +++ b/search/Search.i @@ -1182,6 +1182,19 @@ levelize() sta->levelize()->levelize(); } +bool +strip_escaped_bus() +{ + return Sta::sta()->stripEscapedBus(); +} + +void +set_strip_escaped_bus(bool enable) +{ + Sta::sta()->setStripEscapedBus(enable); +} + + %} // inline //////////////////////////////////////////////////////////////// diff --git a/search/Sta.cc b/search/Sta.cc index 99675388a..94eb17a9b 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2401,6 +2401,19 @@ Sta::setClkThruTristateEnabled(bool enable) } } +bool +Sta::stripEscapedBus() const +{ + return variables_->stripEscapedBus(); +} + +void +Sta::setStripEscapedBus(bool enable) +{ + variables_->setStripEscapedBus(enable); +} + + //////////////////////////////////////////////////////////////// Corner * diff --git a/tcl/Variables.tcl b/tcl/Variables.tcl index a019c2959..04ede46fa 100644 --- a/tcl/Variables.tcl +++ b/tcl/Variables.tcl @@ -168,6 +168,14 @@ proc trace_pocv_enabled { name1 name2 op } { pocv_enabled set_pocv_enabled } +trace variable ::sta_strip_escaped_bus "rw" \ + sta::trace_strip_escaped_bus + +proc trace_strip_escaped_bus { name1 name2 op } { + trace_boolean_var $op ::sta_strip_escaped_bus \ + strip_escaped_bus set_strip_escaped_bus +} + # Report path numeric field width is digits + extra. set report_path_field_width_extra 5 diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index f3eb42e97..005a9f8b2 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -158,6 +158,7 @@ record_sta_tests { report_checks_src_attr report_json1 report_json2 + sdc_strip_escaped_bus suppress_msg verilog_attribute verilog_specify diff --git a/test/sdc_strip_escaped_bus.ok b/test/sdc_strip_escaped_bus.ok new file mode 100644 index 000000000..369616281 --- /dev/null +++ b/test/sdc_strip_escaped_bus.ok @@ -0,0 +1,2 @@ +Error: sdc_strip_escaped_bus.tcl line 11, pin 'a' not found. +Error: sdc_strip_escaped_bus.tcl line 12, pin 'y' not found. diff --git a/test/sdc_strip_escaped_bus.tcl b/test/sdc_strip_escaped_bus.tcl new file mode 100644 index 000000000..a852b48d3 --- /dev/null +++ b/test/sdc_strip_escaped_bus.tcl @@ -0,0 +1,21 @@ +# sdc clock annotation for 2d array + +# Load design and create clock +set sta_continue_on_error 1 +read_verilog sdc_strip_escaped_bus.v +link_design sdc_strip_escaped_bus +create_clock -name clk -period 1000 + +# sta_strip_escaped_bus 0: should produce errors for { a } and { y } +set sta_strip_escaped_bus 0 +set_input_delay -clock clk 3 { a } +set_output_delay -clock clk 3 { y } +set_input_delay -clock clk 4 { a[0] } +set_output_delay -clock clk 4 { y[0] } + +# sta_strip_escaped_bus 1 +set sta_strip_escaped_bus 1 +set_input_delay -clock clk 0 { a } +set_output_delay -clock clk 0 { y } +set_input_delay -clock clk 1 { a[0] } +set_output_delay -clock clk 1 { y[0] } diff --git a/test/sdc_strip_escaped_bus.v b/test/sdc_strip_escaped_bus.v new file mode 100644 index 000000000..ba81f2463 --- /dev/null +++ b/test/sdc_strip_escaped_bus.v @@ -0,0 +1,22 @@ +module sdc_strip_escaped_bus(\a[3] , \a[2] , \a[1] , \a[0] , \y[3] , \y[2] , \y[1] , \y[0] ); + input [3:0] \a[0] ; + wire [3:0] \a[0] ; + input [3:0] \a[1] ; + wire [3:0] \a[1] ; + input [3:0] \a[2] ; + wire [3:0] \a[2] ; + input [3:0] \a[3] ; + wire [3:0] \a[3] ; + output [3:0] \y[0] ; + wire [3:0] \y[0] ; + output [3:0] \y[1] ; + wire [3:0] \y[1] ; + output [3:0] \y[2] ; + wire [3:0] \y[2] ; + output [3:0] \y[3] ; + wire [3:0] \y[3] ; + assign \y[0] = \a[0] ; + assign \y[1] = \a[1] ; + assign \y[2] = \a[2] ; + assign \y[3] = \a[3] ; +endmodule diff --git a/util/PatternMatch.cc b/util/PatternMatch.cc index 2dd32df92..d875c19ba 100644 --- a/util/PatternMatch.cc +++ b/util/PatternMatch.cc @@ -23,11 +23,14 @@ // This notice may not be removed or altered from any source distribution. #include "PatternMatch.hh" +#include "Sta.hh" #include +#include #include namespace sta { +using std::regex; using std::string; PatternMatch::PatternMatch(const char *pattern, @@ -117,13 +120,35 @@ PatternMatch::match(const string &str) const return match(str.c_str()); } +string +stripEscapedBus(string str) +{ + // strip escaped bus indices from str + // bus\[8\] -> bus + // bus\[8\]\[7\] -> bus + // bus\[8\]\[7\]\[6\] -> bus + // bus\[8\].hello -> bus\[8\].hello + // bus\[hello\].world -> bus\[hello\].world + // etc. + string result = str; + regex trailing_numeric_pattern(R"(\\\[\s*\d+\s*\\\]$)"); + string prev_result; + do { + prev_result = result; + result = std::regex_replace(result, trailing_numeric_pattern, ""); + } while (result != prev_result); + return result; +} + bool PatternMatch::match(const char *str) const { if (regexp_) return Tcl_RegExpExec(nullptr, regexp_, str, str) == 1; else - return patternMatch(pattern_, str); + return patternMatch(pattern_, str) + || (Sta::sta()->stripEscapedBus() && + patternMatch(pattern_, stripEscapedBus(str).c_str())); } bool @@ -132,7 +157,9 @@ PatternMatch::matchNoCase(const char *str) const if (regexp_) return Tcl_RegExpExec(0, regexp_, str, str) == 1; else - return patternMatchNoCase(pattern_, str, nocase_); + return patternMatchNoCase(pattern_, str, nocase_) + || (Sta::sta()->stripEscapedBus() && + patternMatchNoCase(pattern_, stripEscapedBus(str).c_str(), nocase_)); } ////////////////////////////////////////////////////////////////