|
| 1 | +# Helper function to split a string into a list of strings and numbers |
| 2 | +proc split {str} { |
| 3 | + set result {} |
| 4 | + foreach {all letters numbers} [regexp -all -inline {(\D*)(\d*)} $str] { |
| 5 | + if {$letters ne ""} { |
| 6 | + lappend result $letters |
| 7 | + } |
| 8 | + if {$numbers ne ""} { |
| 9 | + lappend result [expr {$numbers + 0}] ;# Convert to integer |
| 10 | + } |
| 11 | + } |
| 12 | + return $result |
| 13 | +} |
| 14 | + |
| 15 | +# Custom comparison function |
| 16 | +proc natural_compare {str1 str2} { |
| 17 | + set list1 [split $str1] |
| 18 | + set list2 [split $str2] |
| 19 | + set len [expr {min([llength $list1], [llength $list2])}] |
| 20 | + for {set i 0} {$i < $len} {incr i} { |
| 21 | + set part1 [lindex $list1 $i] |
| 22 | + set part2 [lindex $list2 $i] |
| 23 | + if {$part1 ne $part2} { |
| 24 | + if {[string is integer -strict $part1] && [string is integer -strict $part2]} { |
| 25 | + return [expr {$part1 - $part2}] |
| 26 | + } else { |
| 27 | + return [string compare $part1 $part2] |
| 28 | + } |
| 29 | + } |
| 30 | + } |
| 31 | + return [expr {[llength $list1] - [llength $list2]}] ;# If all parts are equal, compare by length |
| 32 | +} |
| 33 | + |
| 34 | +proc natural_sort {list} { |
| 35 | + return [lsort -command natural_compare $list] |
| 36 | +} |
| 37 | + |
| 38 | +proc match_pins { regex } { |
| 39 | + set pins {} |
| 40 | + # The regex for get_ports is not the tcl regex |
| 41 | + foreach pin [get_ports -regex .*] { |
| 42 | + set input [get_property $pin name] |
| 43 | + # We want the Tcl regex |
| 44 | + if {![regexp $regex $input]} { |
| 45 | + continue |
| 46 | + } |
| 47 | + lappend pins [get_property $pin name] |
| 48 | + } |
| 49 | + return [natural_sort $pins] |
| 50 | +} |
0 commit comments