From 3bfb54ae24062b0181f9699c83a0498d6e975b93 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Mon, 6 Jul 2026 03:02:42 -0700 Subject: [PATCH] Small SDC fixes --- tcl/Collections.tcl | 9 +++- tcl/Extras.tcl | 5 ++ test/collections.ok | 36 ++++++++++++++ test/collections.tcl | 9 ++++ test/regression_vars.tcl | 1 + test/remove_input_delay.ok | 35 +++++++++++++ test/remove_input_delay.tcl | 98 +++++++++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 test/remove_input_delay.ok create mode 100644 test/remove_input_delay.tcl diff --git a/tcl/Collections.tcl b/tcl/Collections.tcl index 31feb77ac..a7f8b0f89 100644 --- a/tcl/Collections.tcl +++ b/tcl/Collections.tcl @@ -39,7 +39,7 @@ proc foreach_in_collection {variable_name collection body} { set rc 0 while {[$it has_next]} { set current [$it next] - uplevel 1 set $variable_name $current + uplevel 1 [list set $variable_name $current] set rc [catch {uplevel 1 $body} result options] if {$rc == 1} { # error - finish iterator, then re-throw @@ -58,7 +58,7 @@ proc foreach_in_collection {variable_name collection body} { $it finish } else { foreach current $collection { - uplevel 1 set $variable_name $current + uplevel 1 [list set $variable_name $current] uplevel 1 $body } } @@ -191,6 +191,11 @@ proc append_to_collection { args } { upvar 1 $collection coll + # If the target variable does not exist yet, auto-initialize it + if { ![info exists coll] } { + set coll {} + } + if { [sta::is_collection $coll] } { sta::collection_append_inplace $coll $objects [info exists flags(-unique)] } else { diff --git a/tcl/Extras.tcl b/tcl/Extras.tcl index 73055d97a..9317a19ec 100644 --- a/tcl/Extras.tcl +++ b/tcl/Extras.tcl @@ -206,6 +206,11 @@ proc get_lib_timing_arcs { args } { return [list] } +# Suppress message (ignore/to be implemented) +proc suppress_message { args } { + puts "Warning: suppress_message not supported, command ignored" +} + ################################################################ # TCL extras ################################################################ diff --git a/test/collections.ok b/test/collections.ok index 434d5a0a3..f670dbdd0 100644 --- a/test/collections.ok +++ b/test/collections.ok @@ -178,6 +178,42 @@ resp_msg[9] resp_rdy resp_val append_to_collection -unique: size changed? 0 + append_to_collection (auto-initialize unset variable): + sizeof_collection: 34 +req_msg[0] +req_msg[10] +req_msg[11] +req_msg[12] +req_msg[13] +req_msg[14] +req_msg[15] +req_msg[16] +req_msg[17] +req_msg[18] +req_msg[19] +req_msg[1] +req_msg[20] +req_msg[21] +req_msg[22] +req_msg[23] +req_msg[24] +req_msg[25] +req_msg[26] +req_msg[27] +req_msg[28] +req_msg[29] +req_msg[2] +req_msg[30] +req_msg[31] +req_msg[3] +req_msg[4] +req_msg[5] +req_msg[6] +req_msg[7] +req_msg[8] +req_msg[9] +req_rdy +req_val index_collection (single): req_val index_collection (slice): diff --git a/test/collections.tcl b/test/collections.tcl index af7e1c722..1d95d1449 100644 --- a/test/collections.tcl +++ b/test/collections.tcl @@ -48,6 +48,15 @@ set before [sizeof_collection $appendable] append_to_collection -unique appendable [get_ports resp_*] puts "[expr $before != [sizeof_collection $appendable]]" +# appending to an unset variable should auto-initialize it (create the collection) +puts "\tappend_to_collection (auto-initialize unset variable): " +unset -nocomplain fresh +append_to_collection fresh [get_ports req_*] +assert {[info exists fresh]} "append_to_collection did not create the unset variable" +assert {[sta::is_collection $fresh] == $sta_enable_collections} "append_to_collection created incorrect format: $fresh" +puts "\tsizeof_collection: [sizeof_collection $fresh]" +report_object_full_names $fresh + puts "\tindex_collection (single): " set index_single_result [index_collection $collection 1] assert {[sta::is_collection $index_single_result] == $sta_enable_collections} "index_collection returned incorrect format: $index_single_result" diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 8fad1a59c..72d62380b 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -182,6 +182,7 @@ record_public_tests { power_json prima3 read_saif_null_instance + remove_input_delay report_checks_sorted report_checks_src_attr report_json1 diff --git a/test/remove_input_delay.ok b/test/remove_input_delay.ok new file mode 100644 index 000000000..9d23ff8b5 --- /dev/null +++ b/test/remove_input_delay.ok @@ -0,0 +1,35 @@ +Warning 198: ../examples/gcd_sky130hd.v line 527, module sky130_fd_sc_hd__tapvpwrvgnd_1 not found. Creating black box for TAP_11. +-- single-bit port, collection passed directly -- +after set: 1 +after remove (direct): 0 +ok +-- single-bit port, collection wrapped in a list -- +after remove (list): 0 +ok +-- multi-bit bus, collection passed directly -- +after set: 32 +after remove (direct): 0 +ok +-- multi-bit bus, collection wrapped in a list -- +after remove (list): 0 +ok +-- reset_input_delay alias, collection passed directly -- +after reset (direct): 0 +ok +-- output: single-bit port, collection passed directly -- +after set: 1 +after remove (direct): 0 +ok +-- output: single-bit port, collection wrapped in a list -- +after remove (list): 0 +ok +-- output: multi-bit bus, collection passed directly -- +after set: 16 +after remove (direct): 0 +ok +-- output: multi-bit bus, collection wrapped in a list -- +after remove (list): 0 +ok +-- reset_output_delay alias, collection passed directly -- +after reset (direct): 0 +ok diff --git a/test/remove_input_delay.tcl b/test/remove_input_delay.tcl new file mode 100644 index 000000000..1fbcfea51 --- /dev/null +++ b/test/remove_input_delay.tcl @@ -0,0 +1,98 @@ +# remove_input_delay/remove_output_delay (and reset_* aliases) with a collection +# passed directly (not wrapped in a list). Regression for collection argument +# handling that previously only worked when the collection was wrapped with +# [list ...]. +read_liberty ../examples/sky130hd_tt.lib.gz +read_verilog ../examples/gcd_sky130hd.v +link_design gcd +create_clock -name clk -period 10 [get_ports clk] + +set clk [lindex [get_clocks clk] 0] + +# Count the set_input_delay/set_output_delay lines currently in effect. +proc port_delay_count { sdc_cmd } { + write_sdc results/remove_input_delay.sdc + set fp [open results/remove_input_delay.sdc r] + set count 0 + foreach line [split [read $fp] "\n"] { + if { [string match "$sdc_cmd*" $line] } { incr count } + } + close $fp + return $count +} + +proc input_delay_count {} { + return [port_delay_count "set_input_delay"] +} + +proc output_delay_count {} { + return [port_delay_count "set_output_delay"] +} + +puts "-- single-bit port, collection passed directly --" +set port [get_ports req_msg[0]] +set_input_delay -clock [get_object_name $clk] 100 $port +puts "after set: [input_delay_count]" +remove_input_delay -clock [get_object_name $clk] $port +puts "after remove (direct): [input_delay_count]" +puts "ok" + +puts "-- single-bit port, collection wrapped in a list --" +set_input_delay -clock [get_object_name $clk] 100 $port +remove_input_delay -clock [get_object_name $clk] [list $port] +puts "after remove (list): [input_delay_count]" +puts "ok" + +puts "-- multi-bit bus, collection passed directly --" +set bus [get_ports req_msg*] +set_input_delay -clock [get_object_name $clk] 100 $bus +puts "after set: [input_delay_count]" +remove_input_delay -clock [get_object_name $clk] $bus +puts "after remove (direct): [input_delay_count]" +puts "ok" + +puts "-- multi-bit bus, collection wrapped in a list --" +set_input_delay -clock [get_object_name $clk] 100 $bus +remove_input_delay -clock [get_object_name $clk] [list $bus] +puts "after remove (list): [input_delay_count]" +puts "ok" + +puts "-- reset_input_delay alias, collection passed directly --" +set_input_delay -clock [get_object_name $clk] 100 $bus +reset_input_delay -clock [get_object_name $clk] $bus +puts "after reset (direct): [input_delay_count]" +puts "ok" + +puts "-- output: single-bit port, collection passed directly --" +set oport [get_ports resp_msg[0]] +set_output_delay -clock [get_object_name $clk] 100 $oport +puts "after set: [output_delay_count]" +remove_output_delay -clock [get_object_name $clk] $oport +puts "after remove (direct): [output_delay_count]" +puts "ok" + +puts "-- output: single-bit port, collection wrapped in a list --" +set_output_delay -clock [get_object_name $clk] 100 $oport +remove_output_delay -clock [get_object_name $clk] [list $oport] +puts "after remove (list): [output_delay_count]" +puts "ok" + +puts "-- output: multi-bit bus, collection passed directly --" +set obus [get_ports resp_msg*] +set_output_delay -clock [get_object_name $clk] 100 $obus +puts "after set: [output_delay_count]" +remove_output_delay -clock [get_object_name $clk] $obus +puts "after remove (direct): [output_delay_count]" +puts "ok" + +puts "-- output: multi-bit bus, collection wrapped in a list --" +set_output_delay -clock [get_object_name $clk] 100 $obus +remove_output_delay -clock [get_object_name $clk] [list $obus] +puts "after remove (list): [output_delay_count]" +puts "ok" + +puts "-- reset_output_delay alias, collection passed directly --" +set_output_delay -clock [get_object_name $clk] 100 $obus +reset_output_delay -clock [get_object_name $clk] $obus +puts "after reset (direct): [output_delay_count]" +puts "ok"