From 695b0bed2f6c43cdff51c8b1ba43653b01313150 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Thu, 19 Jan 2023 12:26:21 -0700 Subject: [PATCH] reorg tcl cmds Signed-off-by: James Cherry --- CMakeLists.txt | 7 +- dcalc/DelayCalc.tcl | 243 +++++++ doc/ApiChanges.txt | 2 +- doc/ChangeLog.txt | 5 + doc/OpenSTA.odt | Bin 94646 -> 94590 bytes tcl/{Cmds.tcl => CmdArgs.tcl} | 0 tcl/CmdUtil.tcl | 307 +++++++++ tcl/Exception.i | 4 - tcl/Network.tcl | 91 --- tcl/NetworkEdit.tcl | 145 ++-- tcl/Property.tcl | 116 ++++ tcl/Sdc.tcl | 596 ++++++++++++++-- tcl/Search.tcl | 35 + tcl/Sta.tcl | 1206 +-------------------------------- tcl/Util.tcl | 72 -- tcl/WritePathSpice.tcl | 99 +++ 16 files changed, 1433 insertions(+), 1495 deletions(-) rename tcl/{Cmds.tcl => CmdArgs.tcl} (100%) create mode 100644 tcl/CmdUtil.tcl create mode 100644 tcl/Property.tcl create mode 100644 tcl/WritePathSpice.tcl diff --git a/CMakeLists.txt b/CMakeLists.txt index dc61b90f..182c22d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,17 +221,20 @@ set(STA_SOURCE set(STA_TCL_FILES tcl/Init.tcl tcl/Util.tcl + tcl/CmdArgs.tcl + tcl/CmdUtil.tcl tcl/Graph.tcl tcl/Liberty.tcl tcl/Link.tcl tcl/Network.tcl tcl/NetworkEdit.tcl + tcl/Property.tcl tcl/Sdc.tcl tcl/Search.tcl - tcl/Cmds.tcl - tcl/Variables.tcl tcl/Sta.tcl tcl/Splash.tcl + tcl/Variables.tcl + tcl/WritePathSpice.tcl dcalc/DelayCalc.tcl parasitics/Parasitics.tcl power/Power.tcl diff --git a/dcalc/DelayCalc.tcl b/dcalc/DelayCalc.tcl index 92e06b89..28b98e7c 100644 --- a/dcalc/DelayCalc.tcl +++ b/dcalc/DelayCalc.tcl @@ -120,5 +120,248 @@ proc set_delay_calculator { alg } { } } +define_cmd_args "set_pocv_sigma_factor" { factor } + +################################################################ + +define_cmd_args "set_assigned_delay" \ + {-cell|-net [-rise] [-fall] [-corner corner] [-min] [-max]\ + [-from from_pins] [-to to_pins] delay} + +# Change the delay for timing arcs between from_pins and to_pins matching +# on cell (instance) or net. +proc set_assigned_delay { args } { + set_assigned_delay_cmd "set_assigned_delay" $args +} + +proc set_assigned_delay_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args keys {-corner -from -to} \ + flags {-cell -net -rise -fall -max -min} + check_argc_eq1 $cmd $cmd_args + set corner [parse_corner keys] + set min_max [parse_min_max_all_check_flags flags] + set to_rf [parse_rise_fall_flags flags] + + if [info exists keys(-from)] { + set from_pins [get_port_pins_error "from_pins" $keys(-from)] + } else { + sta_error 442 "$cmd missing -from argument." + } + if [info exists keys(-to)] { + set to_pins [get_port_pins_error "to_pins" $keys(-to)] + } else { + sta_error 443 "$cmd missing -to argument." + } + + set delay [lindex $cmd_args 0] + if {![string is double $delay]} { + sta_error 444 "$cmd delay is not a float." + } + set delay [time_ui_sta $delay] + + if {[info exists flags(-cell)] && [info exists flags(-net)]} { + sta_error 445 "set_annotated_delay -cell and -net options are mutually excluive." + } elseif {[info exists flags(-cell)]} { + if { $from_pins != {} } { + set inst [[lindex $from_pins 0] instance] + foreach pin $from_pins { + if {[$pin instance] != $inst} { + sta_error 446 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]." + } + } + foreach pin $to_pins { + if {[$pin instance] != $inst} { + sta_error 447 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]" + } + } + } + } elseif {![info exists flags(-net)]} { + sta_error 448 "$cmd -cell or -net required." + } + foreach from_pin $from_pins { + set from_vertices [$from_pin vertices] + set_assigned_delay1 [lindex $from_vertices 0] \ + $to_pins $to_rf $corner $min_max $delay + if { [llength $from_vertices] == 2 } { + set_assigned_delay1 [lindex $from_vertices 1] \ + $to_pins $to_rf $corner $min_max $delay + } + } +} + +proc set_assigned_delay1 { from_vertex to_pins to_rf corner min_max delay } { + foreach to_pin $to_pins { + set to_vertices [$to_pin vertices] + set_assigned_delay2 $from_vertex [lindex $to_vertices 0] \ + $to_rf $corner $min_max $delay + if { [llength $to_vertices] == 2 } { + # Bidirect driver. + set_assigned_delay2 $from_vertex [lindex $to_vertices 1] \ + $to_rf $corner $min_max $delay + } + } +} + +proc set_assigned_delay2 {from_vertex to_vertex to_rf corner min_max delay} { + set edge_iter [$from_vertex out_edge_iterator] + while {[$edge_iter has_next]} { + set edge [$edge_iter next] + if { [$edge to] == $to_vertex \ + && ![timing_role_is_check [$edge role]] } { + foreach arc [$edge timing_arcs] { + if { $to_rf == "rise_fall" \ + || $to_rf eq [$arc to_edge_name] } { + set_arc_delay $edge $arc $corner $min_max $delay + } + } + } + } + $edge_iter finish +} + +################################################################ + +define_cmd_args "set_assigned_check" \ + {-setup|-hold|-recovery|-removal [-rise] [-fall]\ + [-corner corner] [-min] [-max]\ + [-from from_pins] [-to to_pins] [-clock rise|fall]\ + [-cond sdf_cond] check_value} + +proc set_assigned_check { args } { + set_assigned_check_cmd "set_assigned_check" $args +} + +proc set_assigned_check_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args \ + keys {-from -to -corner -clock -cond} \ + flags {-setup -hold -recovery -removal -rise -fall -max -min} + check_argc_eq1 $cmd $cmd_args + + if { [info exists keys(-from)] } { + set from_pins [get_port_pins_error "from_pins" $keys(-from)] + } else { + sta_error 449 "$cmd missing -from argument." + } + set from_rf "rise_fall" + if { [info exists keys(-clock)] } { + set clk_arg $keys(-clock) + if { $clk_arg eq "rise" \ + || $clk_arg eq "fall" } { + set from_rf $clk_arg + } else { + sta_error 450 "$cmd -clock must be rise or fall." + } + } + + if { [info exists keys(-to)] } { + set to_pins [get_port_pins_error "to_pins" $keys(-to)] + } else { + sta_error 451 "$cmd missing -to argument." + } + set to_rf [parse_rise_fall_flags flags] + set corner [parse_corner keys] + set min_max [parse_min_max_all_check_flags flags] + + if { [info exists flags(-setup)] } { + set role "setup" + } elseif { [info exists flags(-hold)] } { + set role "hold" + } elseif { [info exists flags(-recovery)] } { + set role "recovery" + } elseif { [info exists flags(-removal)] } { + set role "removal" + } else { + sta_error 452 "$cmd missing -setup|-hold|-recovery|-removal check type.." + } + set cond "" + if { [info exists key(-cond)] } { + set cond $key(-cond) + } + set check_value [lindex $cmd_args 0] + if { ![string is double $check_value] } { + sta_error 453 "$cmd check_value is not a float." + } + set check_value [time_ui_sta $check_value] + + foreach from_pin $from_pins { + set from_vertices [$from_pin vertices] + set_assigned_check1 [lindex $from_vertices 0] $from_rf \ + $to_pins $to_rf $role $corner $min_max $cond $check_value + if { [llength $from_vertices] == 2 } { + set_assigned_check1 [lindex $from_vertices 1] $from_rf \ + $to_pins $to_rf $role $corner $min_max $cond $check_value + } + } +} + +proc set_assigned_check1 { from_vertex from_rf to_pins to_rf \ + role corner min_max cond check_value } { + foreach to_pin $to_pins { + set to_vertices [$to_pin vertices] + set_assigned_check2 $from_vertex $from_rf [lindex $to_vertices 0] \ + $to_rf $role $corner $min_max $cond $check_value + if { [llength $to_vertices] == 2 } { + # Bidirect driver. + set_assigned_check2 $from_vertex $from_rf \ + [lindex $to_vertices 1] $to_rf $role $corner $min_max \ + $cond $check_value + } + } +} + +proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \ + role corner min_max cond check_value } { + set edge_iter [$from_vertex out_edge_iterator] + while {[$edge_iter has_next]} { + set edge [$edge_iter next] + if { [$edge to] == $to_vertex } { + foreach arc [$edge timing_arcs] { + if { ($from_rf eq "rise_fall" \ + || $from_rf eq [$arc from_edge_name]) \ + && ($to_rf eq "rise_fall" \ + || $to_rf eq [$arc to_edge_name]) \ + && [$arc role] eq $role \ + && ($cond eq "" || [$arc sdf_cond] eq $cond) } { + set_arc_delay $edge $arc $corner $min_max $check_value + } + } + } + } + $edge_iter finish +} + +################################################################a + +define_cmd_args "set_assigned_transition" \ + {[-rise] [-fall] [-corner corner] [-min] [-max] slew pins} + +# Change the slew on a list of ports. +proc set_assigned_transition { args } { + parse_key_args "set_assigned_transition" args keys {-corner} \ + flags {-rise -fall -max -min} + + set corner [parse_corner keys] + set min_max [parse_min_max_all_check_flags flags] + set tr [parse_rise_fall_flags flags] + check_argc_eq2 "set_assigned_transition" $args + + set slew [lindex $args 0] + if {![string is double $slew]} { + sta_error 428 "set_assigned_transition transition is not a float." + } + set slew [time_ui_sta $slew] + set pins [get_port_pins_error "pins" [lindex $args 1]] + foreach pin $pins { + set vertices [$pin vertices] + set vertex [lindex $vertices 0] + set_annotated_slew $vertex $corner $min_max $tr $slew + if { [llength $vertices] == 2 } { + # Bidirect driver. + set vertex [lindex $vertices 1] + set_annotated_slew $vertex $min_max $tr $slew + } + } +} + # sta namespace end } diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt index 3709eae3..fae86a3f 100644 --- a/doc/ApiChanges.txt +++ b/doc/ApiChanges.txt @@ -16,7 +16,7 @@ This file summarizes STA API changes for each release. -Release 2.4.0 2023/01/?? +Release 2.4.0 2023/01/19 ------------------------- The Network API and associated containers now 'const' the network class objects. diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt index c68c054c..fea750c3 100644 --- a/doc/ChangeLog.txt +++ b/doc/ChangeLog.txt @@ -3,6 +3,9 @@ OpenSTA Timing Analyzer Release Notes This file summarizes user visible changes for each release. +Release 2.4.0 2023/01/19 +------------------------- + The report_parasitics_annotation command reports SPEF annotation completeness. report_parasitics_annotation [-report_unannotated] @@ -12,6 +15,8 @@ pin activities for power analysis. read_power_activities -vcd filename +The report_cell command has been removed; use report_instance. + Release 2.3.3 2022/09/24 ------------------------- diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 78ea3b1793dee544c416cc2a75b209d0dbfb89aa..b6a82082b9fe9b46830e23eb1188c2978905daa4 100644 GIT binary patch delta 61405 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 ZI=KC3xjw-ClViR=PVXA;?cP;G{U5zrGywnr delta 61347 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
lNwOxuJHW;>Bg4YaMRSc3HnH#**|1o%Cs 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%0Di=N>8@KEds8P9H( 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 H$3Xud9X>MB diff --git a/tcl/Cmds.tcl b/tcl/CmdArgs.tcl similarity index 100% rename from tcl/Cmds.tcl rename to tcl/CmdArgs.tcl diff --git a/tcl/CmdUtil.tcl b/tcl/CmdUtil.tcl new file mode 100644 index 00000000..ec5122bd --- /dev/null +++ b/tcl/CmdUtil.tcl @@ -0,0 +1,307 @@ +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2022, 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 . + +namespace eval sta { + +################################################################ +# +# Utility commands +# +################################################################ + +define_cmd_args "help" {[pattern]} + +proc_redirect help { + variable cmd_args + + set arg_count [llength $args] + if { $arg_count == 0 } { + set pattern "*" + } elseif { $arg_count == 1 } { + set pattern [lindex $args 0] + } else { + cmd_usage_error "help" + } + set matches [array names cmd_args $pattern] + if { $matches != {} } { + foreach cmd [lsort $matches] { + show_cmd_args $cmd + } + } else { + sta_warn 300 "no commands match '$pattern'." + } +} + +proc show_cmd_args { cmd } { + variable cmd_args + + set max_col 80 + set indent 2 + set indent_str " " + set line $cmd + set col [string length $cmd] + set arglist $cmd_args($cmd) + # Break the arglist up into max_col length lines. + while {1} { + if {[regexp {(^[\n ]*)([a-zA-Z0-9_\\\|\-]+|\[[^\[]+\])(.*)} \ + $arglist ignore space arg rest]} { + set arg_length [string length $arg] + if { $col + $arg_length < $max_col } { + set line "$line $arg" + set col [expr $col + $arg_length + 1] + } else { + report_line $line + set line "$indent_str $arg" + set col [expr $indent + $arg_length + 1] + } + set arglist $rest + } else { + report_line $line + break + } + } +} + +# This is used in lieu of command completion to make sdc commands +# like get_ports be abbreviated get_port. +proc define_cmd_alias { alias cmd } { + eval "proc $alias { args } { eval [concat $cmd \$args] }" + namespace export $alias +} + +proc cmd_usage_error { cmd } { + variable cmd_args + + if [info exists cmd_args($cmd)] { + sta_error 404 "Usage: $cmd $cmd_args($cmd)" + } else { + sta_error 405 "Usage: $cmd argument error" + } +} + +################################################################ + +define_cmd_args "with_output_to_variable" { var { cmds }} + +# with_output_to_variable variable { command args... } +proc with_output_to_variable { var_name args } { + upvar 1 $var_name var + + set body [lindex $args 0] + sta::redirect_string_begin; + catch $body ret + set var [sta::redirect_string_end] + return $ret +} + +################################################################ + +define_cmd_args "report_units" {} + +proc report_units { args } { + check_argc_eq0 "report_units" $args + foreach unit {"time" "capacitance" "resistance" "voltage" "current" "power" "distance"} { + report_line " $unit 1[unit_scale_abreviation $unit][unit_suffix $unit]" + } +} + +################################################################ + +define_cmd_args "set_cmd_units" \ + {[-capacitance cap_unit] [-resistance res_unit] [-time time_unit]\ + [-voltage voltage_unit] [-current current_unit] [-power power_unit]\ + [-distance distance_unit]} + +proc set_cmd_units { args } { + parse_key_args "set_cmd_units" args \ + keys {-capacitance -resistance -time -voltage -current -power \ + -distance -digits -suffix} \ + flags {} + + check_argc_eq0 "set_cmd_units" $args + set_unit_values "capacitance" -capacitance "f" keys + set_unit_values "time" -time "s" keys + set_unit_values "voltage" -voltage "v" keys + set_unit_values "current" -current "A" keys + set_unit_values "resistance" -resistance "ohm" keys + set_unit_values "distance" -distance "m" keys +} + +proc set_unit_values { unit key unit_name key_var } { + upvar 1 $key_var keys + if { [info exists keys($key)] } { + set value $keys($key) + if { [string equal -nocase $value $unit_name] } { + set_cmd_unit_scale $unit 1.0 + } else { + set prefix [string index $value 0] + set suffix [string range $value 1 end] + # unit includes "1" prefix + if { [string is digit $prefix] } { + set prefix [string index $value 1] + set suffix [string range $value 2 end] + } + if { [string equal -nocase $suffix $unit_name] } { + set scale [unit_prefix_scale $unit $prefix] + set_cmd_unit_scale $unit $scale + } else { + sta_error 515 "unknown $unit unit '$suffix'." + } + } + if [info exists keys(-digits)] { + set_cmd_unit_digits $unit $keys(-digits) + } + if [info exists keys(-suffix)] { + set_cmd_unit_suffix $unit $keys(-suffix) + } + } +} + +################################################################ + +define_cmd_args "delete_from_list" {list objs} + +proc delete_from_list { list objects } { + delete_objects_from_list_cmd $list $objects +} + +proc delete_objects_from_list_cmd { list objects } { + set list0 [lindex $list 0] + set list_is_object [is_object $list0] + set list_type [object_type $list0] + foreach obj $objects { + # If the list is a collection of tcl objects (returned by get_*), + # convert the obj to be removed from a name to an object of the same + # type. + if {$list_is_object && ![is_object $obj]} { + if {$list_type == "Clock"} { + set obj [find_clock $obj] + } elseif {$list_type == "Port"} { + set top_instance [top_instance] + set top_cell [$top_instance cell] + set obj [$top_cell find_port $obj] + } elseif {$list_type == "Pin"} { + set obj [find_pin $obj] + } elseif {$list_type == "Instance"} { + set obj [find_instance $obj] + } elseif {$list_type == "Net"} { + set obj [find_net $obj] + } elseif {$list_type == "LibertyLibrary"} { + set obj [find_liberty $obj] + } elseif {$list_type == "LibertyCell"} { + set obj [find_liberty_cell $obj] + } elseif {$list_type == "LibertyPort"} { + set obj [get_lib_pins $obj] + } else { + sta_error 439 "unsupported object type $list_type." + } + } + set index [lsearch $list $obj] + if { $index != -1 } { + set list [lreplace $list $index $index] + } + } + return $list +} + +################################################################ + +proc set_cmd_namespace { namespc } { + if { $namespc == "sdc" || $namespc == "sta" } { + set_cmd_namespace_cmd $namespc + } else { + sta_error 589 "unknown namespace $namespc." + } +} + +################################################################ + +define_cmd_args "report_object_full_names" {objects} + +proc report_object_full_names { objects } { + foreach obj [sort_by_full_name $objects] { + report_line [get_full_name $obj] + } +} + +define_cmd_args "report_object_names" {objects} + +proc report_object_names { objects } { + foreach obj [sort_by_name $objects] { + report_line [get_name $obj] + } +} + +################################################################ + +define_cmd_args "get_name" {object} +define_cmd_args "get_full_name" {object} + +################################################################ + +proc get_name { object } { + return [get_object_property $object "name"] +} + +proc get_full_name { object } { + return [get_object_property $object "full_name"] +} + +proc sort_by_name { objects } { + return [lsort -command name_cmp $objects] +} + +proc name_cmp { obj1 obj2 } { + return [string compare [get_name $obj1] [get_name $obj2]] +} + +proc sort_by_full_name { objects } { + return [lsort -command full_name_cmp $objects] +} + +proc full_name_cmp { obj1 obj2 } { + return [string compare [get_full_name $obj1] [get_full_name $obj2]] +} + +proc get_object_type { obj } { + set object_type [object_type $obj] + if { $object_type == "Clock" } { + return "clock" + } elseif { $object_type == "LibertyCell" } { + return "lib_cell" + } elseif { $object_type == "LibertyPort" } { + return "lib_pin" + } elseif { $object_type == "Cell" } { + return "cell" + } elseif { $object_type == "Instance" } { + return "instance" + } elseif { $object_type == "Port" } { + return "port" + } elseif { $object_type == "Pin" } { + return "pin" + } elseif { $object_type == "Net" } { + return "net" + } elseif { $object_type == "Edge" } { + return "timing_arc" + } elseif { $object_type == "TimingArcSet" } { + return "timing_arc" + } else { + return "?" + } +} + +# sta namespace end. +} diff --git a/tcl/Exception.i b/tcl/Exception.i index 0854be02..d8b9ca5b 100644 --- a/tcl/Exception.i +++ b/tcl/Exception.i @@ -1,5 +1,3 @@ -%{ - // OpenSTA, Static Timing Analyzer // Copyright (c) 2022, Parallax Software, Inc. // @@ -16,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -%} - %exception { try { $function } catch (std::bad_alloc &) { diff --git a/tcl/Network.tcl b/tcl/Network.tcl index b5f4e0cd..98f515e2 100644 --- a/tcl/Network.tcl +++ b/tcl/Network.tcl @@ -18,26 +18,6 @@ namespace eval sta { -proc set_cmd_namespace { namespc } { - if { $namespc == "sdc" || $namespc == "sta" } { - set_cmd_namespace_cmd $namespc - } else { - sta_error 589 "unknown namespace $namespc." - } -} - -################################################################ - -define_cmd_args "report_cell" \ - {[-connections] [-verbose] instance_path [> filename] [>> filename]} - -# Alias for report_instance. -proc_redirect report_cell { - eval report_instance $args -} - -################################################################ - define_cmd_args "report_instance" \ {[-connections] [-verbose] instance_path [> filename] [>> filename]} @@ -224,28 +204,6 @@ proc report_cell_ { cell } { $iter finish } -define_cmd_args "report_pin" {[-corner corner] [-digits digits] pin\ - [> filename] [>> filename]} - -proc_redirect report_pin { - global sta_report_default_digits - - parse_key_args "report_pin" args keys {-corner -digits} \ - flags {-connections -verbose -hier_pins} - set corner [parse_corner_or_all keys] - set digits $sta_report_default_digits - if { [info exists keys(-digits)] } { - set digits $keys(-digits) - } - check_argc_eq1 "report_pin" $args - set pin_path [lindex $args 0] - set pin [get_pin_warn "pin" $pin_path] - - if { $pin != "NULL" } { - report_pin_ $pin $corner $digits - } -} - ################################################################ define_cmd_args "report_net" \ @@ -497,54 +455,5 @@ proc capacitances_str { cap_r_min cap_r_max cap_f_min cap_f_max digits } { } } -################################################################ -# -# Debugging functions -# -################################################################ - -proc_redirect report_network { - report_hierarchy [top_instance] -} - -proc report_hierarchy { inst } { - report_instance1 $inst 1 1 - foreach child [instance_sorted_children $inst] { - report_hierarchy $child - } -} - -proc port_direction_any_input { dir } { - return [expr { $dir == "input" || $dir == "bidirect" } ] -} - -proc port_direction_any_output { dir } { - return [expr { $dir == "output" \ - || $dir == "bidirect" \ - || $dir == "tristate" } ] -} - -# collect instance pins into list -proc instance_pins { instance } { - set pins {} - set iter [$instance pin_iterator] - while {[$iter has_next]} { - lappend pins [$iter next] - } - $iter finish - return $pins -} - -# collect ports into a list -proc cell_ports { cell } { - set ports {} - set iter [$cell port_iterator] - while {[$iter has_next]} { - lappend ports [$iter next] - } - $iter finish - return $ports -} - # sta namespace end } diff --git a/tcl/NetworkEdit.tcl b/tcl/NetworkEdit.tcl index 714dd483..4757134d 100644 --- a/tcl/NetworkEdit.tcl +++ b/tcl/NetworkEdit.tcl @@ -18,6 +18,55 @@ namespace eval sta { +define_cmd_args "make_instance" {inst_path lib_cell} + +proc make_instance { inst_path lib_cell } { + set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell] + if { $lib_cell != "NULL" } { + set path_regexp [path_regexp] + if {[regexp $path_regexp $inst_path ignore path_name inst_name]} { + set parent [find_instance $path_name] + if { $parent == "NULL" } { + # Parent instance not found. This could be a typo, but since + # SDC does not escape hierarchy dividers it can also be + # an escaped name. + set inst_name $inst_path + set parent [top_instance] + } + } else { + set inst_name $inst_path + set parent [top_instance] + } + return [make_instance_cmd $inst_name $lib_cell $parent] + } else { + return 0 + } +} + +################################################################ + +define_cmd_args "make_net" {} + +proc make_net { net_path } { + # Copy backslashes that will be removed by foreach. + set net_path [string map {\\ \\\\} $net_path] + set path_regexp [path_regexp] + if {[regexp $path_regexp $net_path ignore path_name net_name]} { + set parent [find_instance $path_name] + if { $parent == "NULL" } { + return 0 + } + } else { + set parent [top_instance] + set net_name $net_path + } + return [make_net_cmd $net_name $parent] +} + +################################################################ + +define_cmd_args "connect_pin" {net pin} + proc connect_pin { net pin } { set insts_port [parse_connect_pin $pin] if { $insts_port == 0 } { @@ -110,39 +159,7 @@ proc parse_connect_pins { arg } { ################################################################ -proc delete_instance { instance } { - if { [is_object $instance] } { - set object_type [object_type $instance] - if { $object_type == "Instance" } { - set inst $instance - } else { - sta_error 587 "unsupported object type $object_type." - } - } else { - set inst [find_instance $instance] - } - if { $inst != "NULL" } { - delete_instance_cmd $inst - } -} - -################################################################ - -proc delete_net { net } { - if { [is_object $net] } { - set object_type [object_type $net] - if { $object_type != "Net" } { - sta_error 588 "unsupported object type $object_type." - } - } else { - set net [find_net $net] - } - if { $net != "NULL" } { - delete_net_cmd $net - } -} - -################################################################ +define_cmd_args "disconnect_pin" {net -all|pin} proc disconnect_pin { net pin } { set net [get_net_warn "net" $net] @@ -168,58 +185,48 @@ proc disconnect_pin { net pin } { } } -proc disconnect_pins { net pins } { - sta_warn 603 "disconnect_pins is deprecated. Use disconnect_pin." - foreach pin $pins { - disconnect_pin $net $pins - } -} - ################################################################ -proc make_instance { inst_path lib_cell } { - set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell] - if { $lib_cell != "NULL" } { - set path_regexp [path_regexp] - if {[regexp $path_regexp $inst_path ignore path_name inst_name]} { - set parent [find_instance $path_name] - if { $parent == "NULL" } { - # Parent instance not found. This could be a typo, but since - # SDC does not escape hierarchy dividers it can also be - # an escaped name. - set inst_name $inst_path - set parent [top_instance] - } +define_cmd_args "delete_instance" {inst} + +proc delete_instance { instance } { + if { [is_object $instance] } { + set object_type [object_type $instance] + if { $object_type == "Instance" } { + set inst $instance } else { - set inst_name $inst_path - set parent [top_instance] + sta_error 587 "unsupported object type $object_type." } - return [make_instance_cmd $inst_name $lib_cell $parent] } else { - return 0 + set inst [find_instance $instance] + } + if { $inst != "NULL" } { + delete_instance_cmd $inst } } ################################################################ -proc make_net { net_path } { - # Copy backslashes that will be removed by foreach. - set net_path [string map {\\ \\\\} $net_path] - set path_regexp [path_regexp] - if {[regexp $path_regexp $net_path ignore path_name net_name]} { - set parent [find_instance $path_name] - if { $parent == "NULL" } { - return 0 +define_cmd_args "delete_net" {net} + +proc delete_net { net } { + if { [is_object $net] } { + set object_type [object_type $net] + if { $object_type != "Net" } { + sta_error 588 "unsupported object type $object_type." } } else { - set parent [top_instance] - set net_name $net_path + set net [find_net $net] + } + if { $net != "NULL" } { + delete_net_cmd $net } - return [make_net_cmd $net_name $parent] } ################################################################ +define_cmd_args "replace_cell" {instance lib_cell} + proc replace_cell { instance lib_cell } { set cell [get_lib_cell_warn "lib_cell" $lib_cell] if { $cell != "NULL" } { @@ -236,6 +243,8 @@ proc replace_cell { instance lib_cell } { } } +################################################################ + proc path_regexp {} { global hierarchy_separator set id_regexp "\[^${hierarchy_separator}\]+" diff --git a/tcl/Property.tcl b/tcl/Property.tcl new file mode 100644 index 00000000..e3fdb20d --- /dev/null +++ b/tcl/Property.tcl @@ -0,0 +1,116 @@ +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2022, 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 . + +namespace eval sta { + +define_cmd_args "get_property" \ + {[-object_type cell|pin|net|port|clock|timing_arc] object property} + +proc get_property { args } { + return [get_property_cmd "get_property" "-object_type" $args] +} + +proc get_property_cmd { cmd type_key cmd_args } { + parse_key_args $cmd cmd_args keys $type_key flags {-quiet} + set quiet [info exists flags(-quiet)] + check_argc_eq2 $cmd $cmd_args + set object [lindex $cmd_args 0] + if { $object == "" } { + sta_error 491 "$cmd object is null." + } elseif { ![is_object $object] } { + if [info exists keys($type_key)] { + set object_type $keys($type_key) + } else { + sta_error 492 "$cmd $type_key must be specified with object name argument." + } + set object [get_property_object_type $object_type $object $quiet] + } + set prop [lindex $cmd_args 1] + return [get_object_property $object $prop] +} + +proc get_object_property { object prop } { + if { [is_object $object] } { + set object_type [object_type $object] + if { $object_type == "Instance" } { + return [instance_property $object $prop] + } elseif { $object_type == "Pin" } { + return [pin_property $object $prop] + } elseif { $object_type == "Net" } { + return [net_property $object $prop] + } elseif { $object_type == "Clock" } { + return [clock_property $object $prop] + } elseif { $object_type == "Port" } { + return [port_property $object $prop] + } elseif { $object_type == "LibertyPort" } { + return [liberty_port_property $object $prop] + } elseif { $object_type == "LibertyCell" } { + return [liberty_cell_property $object $prop] + } elseif { $object_type == "Cell" } { + return [cell_property $object $prop] + } elseif { $object_type == "Library" } { + return [library_property $object $prop] + } elseif { $object_type == "LibertyLibrary" } { + return [liberty_library_property $object $prop] + } elseif { $object_type == "Edge" } { + return [edge_property $object $prop] + } elseif { $object_type == "PathEnd" } { + return [path_end_property $object $prop] + } elseif { $object_type == "PathRef" } { + return [path_ref_property $object $prop] + } elseif { $object_type == "TimingArcSet" } { + return [timing_arc_set_property $object $prop] + } else { + sta_error 606 "get_property unsupported object type $object_type." + } + } else { + sta_error 493 "get_property $object is not an object." + } +} + +proc get_property_object_type { object_type object_name quiet } { + set object "NULL" + if { $object_type == "instance" \ + || $object_type == "cell"} { + set object [get_cells -quiet $object_name] + } elseif { $object_type == "pin" } { + set object [get_pins -quiet $object_name] + } elseif { $object_type == "net" } { + set object [get_nets -quiet $object_name] + } elseif { $object_type == "port" } { + set object [get_ports -quiet $object_name] + } elseif { $object_type == "clock" } { + set object [get_clocks -quiet $object_name] + } elseif { $object_type == "liberty_cell" \ + || $object_type == "lib_cell"} { + set object [get_lib_cells -quiet $object_name] + } elseif { $object_type == "liberty_port" \ + || $object_type == "lib_pin" } { + set object [get_lib_pins -quiet $object_name] + } elseif { $object_type == "library" \ + || $object_type == "lib"} { + set object [get_libs -quiet $object_name] + } else { + sta_error 494 "$object_type not supported." + } + if { $object == "NULL" && !$quiet } { + sta_error 495 "$object_type '$object_name' not found." + } + return [lindex $object 0] +} + +# sta namespace end. +} diff --git a/tcl/Sdc.tcl b/tcl/Sdc.tcl index af7a37d8..cc6e8fc3 100644 --- a/tcl/Sdc.tcl +++ b/tcl/Sdc.tcl @@ -289,58 +289,6 @@ proc check_unit_scale { unit scale } { } } -################################################################ - -define_cmd_args "set_cmd_units" \ - {[-capacitance cap_unit] [-resistance res_unit] [-time time_unit]\ - [-voltage voltage_unit] [-current current_unit] [-power power_unit]\ - [-distance distance_unit]} - -proc set_cmd_units { args } { - parse_key_args "set_cmd_units" args \ - keys {-capacitance -resistance -time -voltage -current -power \ - -distance -digits -suffix} \ - flags {} - - check_argc_eq0 "set_cmd_units" $args - set_unit_values "capacitance" -capacitance "f" keys - set_unit_values "time" -time "s" keys - set_unit_values "voltage" -voltage "v" keys - set_unit_values "current" -current "A" keys - set_unit_values "resistance" -resistance "ohm" keys - set_unit_values "distance" -distance "m" keys -} - -proc set_unit_values { unit key unit_name key_var } { - upvar 1 $key_var keys - if { [info exists keys($key)] } { - set value $keys($key) - if { [string equal -nocase $value $unit_name] } { - set_cmd_unit_scale $unit 1.0 - } else { - set prefix [string index $value 0] - set suffix [string range $value 1 end] - # unit includes "1" prefix - if { [string is digit $prefix] } { - set prefix [string index $value 1] - set suffix [string range $value 2 end] - } - if { [string equal -nocase $suffix $unit_name] } { - set scale [unit_prefix_scale $unit $prefix] - set_cmd_unit_scale $unit $scale - } else { - sta_error 515 "unknown $unit unit '$suffix'." - } - } - if [info exists keys(-digits)] { - set_cmd_unit_digits $unit $keys(-digits) - } - if [info exists keys(-suffix)] { - set_cmd_unit_suffix $unit $keys(-suffix) - } - } -} - ################################################################ # # Object Access Commands @@ -1134,6 +1082,24 @@ proc create_clock { args } { ################################################################ +define_cmd_args "delete_clock" {[-all] clocks} + +proc delete_clock { args } { + parse_key_args "delete_clock" args keys {} flags {-all} + if { [info exists flags(-all)] } { + check_argc_eq0 "delete_clock" $args + set clks [all_clocks] + } else { + check_argc_eq1 "delete_clock" $args + set clks [get_clocks_warn "clocks" [lindex $args 0]] + } + foreach clk $clks { + remove_clock_cmd $clk + } +} + +################################################################ + define_cmd_args "create_generated_clock" \ {[-name clock_name] -source master_pin [-master_clock clock]\ [-divide_by divisor | -multiply_by multiplier]\ @@ -1270,6 +1236,30 @@ proc create_generated_clock { args } { ################################################################ +define_cmd_args "delete_generated_clock" {[-all] clocks} + +proc delete_generated_clock { args } { + remove_gclk_cmd "delete_generated_clock" $args +} + +proc remove_gclk_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args keys {} flags {-all} + if { [info exists flags(-all)] } { + check_argc_eq0 $cmd $cmd_args + set clks [all_clocks] + } else { + check_argc_eq1 $cmd $cmd_args + set clks [get_clocks_warn "clocks" [lindex $cmd_args 0]] + } + foreach clk $clks { + if { [$clk is_generated] } { + remove_clock_cmd $clk + } + } +} + +################################################################ + define_cmd_args "group_path" \ {-name group_name [-weight weight] [-critical_range range]\ [-default] [-comment comment]\ @@ -1459,6 +1449,66 @@ proc set_clock_groups { args } { ################################################################ +define_cmd_args "unset_clock_groups" \ + {[-logically_exclusive] [-physically_exclusive]\ + [-asynchronous] [-name names] [-all]} + +proc unset_clock_groups { args } { + unset_clk_groups_cmd "unset_clock_groups" $args +} + +proc unset_clk_groups_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args \ + keys {-name} \ + flags {-logically_exclusive -physically_exclusive -asynchronous -all} + + set all [info exists flags(-all)] + set names {} + if {[info exists keys(-name)]} { + set names $keys(-name) + } + + if { $all && $names != {} } { + sta_error 454 "the -all and -name options are mutually exclusive." + } + if { !$all && $names == {} } { + sta_error 455 "either -all or -name options must be specified." + } + + set logically_exclusive [info exists flags(-logically_exclusive)] + set physically_exclusive [info exists flags(-physically_exclusive)] + set asynchronous [info exists flags(-asynchronous)] + + if { ($logically_exclusive+$physically_exclusive+$asynchronous) == 0 } { + sta_error 456 "one of -logically_exclusive, -physically_exclusive or -asynchronous is required." + } + if { ($logically_exclusive+$physically_exclusive+$asynchronous) > 1 } { + sta_error 457 "the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive." + } + + if { $all } { + if { $logically_exclusive } { + unset_clock_groups_logically_exclusive "NULL" + } elseif { $physically_exclusive } { + unset_clock_groups_physically_exclusive "NULL" + } elseif { $asynchronous } { + unset_clock_groups_asynchronous "NULL" + } + } else { + foreach name $names { + if { $logically_exclusive } { + unset_clock_groups_logically_exclusive $name + } elseif { $physically_exclusive } { + unset_clock_groups_physically_exclusive $name + } elseif { $asynchronous } { + unset_clock_groups_asynchronous $name + } + } + } +} + +################################################################ + define_cmd_args "set_clock_latency" \ {[-source] [-clock clock] [-rise] [-fall] [-min] [-max]\ [-early] [-late] delay objects} @@ -1518,6 +1568,50 @@ proc set_clock_latency { args } { ################################################################ +define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects} + +proc unset_clock_latency { args } { + unset_clk_latency_cmd "unset_clock_latency" $args +} + +proc unset_clk_latency_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args keys {-clock} flags {-source} + check_argc_eq1 $cmd $cmd_args + set objects [lindex $cmd_args 0] + parse_clk_port_pin_arg $objects clks pins + set pin_clk "NULL" + if { [info exists keys(-clock)] } { + set pin_clk [get_clock_warn "clock" $keys(-clock)] + if { $clks != {} } { + sta_warn 303 "-clock ignored for clock objects." + } + } + + if {[info exists flags(-source)]} { + # Source latency. + foreach clk $clks { + unset_clock_insertion_cmd $clk "NULL" + } + foreach pin $pins { + # Source only allowed on clocks and clock pins. + if { ![is_clock_pin $pin] } { + sta_error 458 "-source '[$pin path_name]' is not a clock pin." + } + unset_clock_insertion_cmd $pin_clk $pin + } + } else { + # Latency. + foreach clk $clks { + unset_clock_latency_cmd $clk "NULL" + } + foreach pin $pins { + unset_clock_latency_cmd $pin_clk $pin + } + } +} + +################################################################ + define_cmd_args "set_sense" \ {[-type clock|data] [-positive] [-negative] [-pulse pulse_type]\ [-stop_propagation] [-clocks clocks] pins} @@ -1611,6 +1705,18 @@ proc set_clock_transition { args } { ################################################################ +define_cmd_args "unset_clock_transition" {clocks} + +proc unset_clock_transition { args } { + check_argc_eq1 "unset_clock_transition" $args + set clks [get_clocks_warn "clocks" [lindex $args 0]] + foreach clk $clks { + unset_clock_slew_cmd $clk + } +} + +################################################################ + # -rise/-fall are obsolete. define_cmd_args "set_clock_uncertainty" \ {[-from|-rise_from|-fall_from from_clock]\ @@ -1707,6 +1813,92 @@ proc set_clock_uncertainty { args } { ################################################################ +define_cmd_args "unset_clock_uncertainty" \ + {[-from|-rise_from|-fall_from from_clock]\ + [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\ + [-setup] [-hold] [objects]} + +proc unset_clock_uncertainty { args } { + unset_clk_uncertainty_cmd "unset_clock_uncertainty" $args +} + +proc unset_clk_uncertainty_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args \ + keys {-from -rise_from -fall_from -to -rise_to -fall_to} \ + flags {-rise -fall -setup -hold} + + set min_max "min_max" + if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { + set min_max "max" + } + if { [info exists flags(-hold)] && ![info exists flags(-setup)] } { + set min_max "min" + } + + if { [info exists keys(-from)] } { + set from_key "-from" + set from_rf "rise_fall" + } elseif { [info exists keys(-rise_from)] } { + set from_key "-rise_from" + set from_rf "rise" + } elseif { [info exists keys(-fall_from)] } { + set from_key "-fall_from" + set from_rf "fall" + } else { + set from_key "none" + } + + if { [info exists keys(-to)] } { + set to_key "-to" + set to_rf "rise_fall" + } elseif { [info exists keys(-rise_to)] } { + set to_key "-rise_to" + set to_rf "rise" + } elseif { [info exists keys(-fall_to)] } { + set to_key "-fall_to" + set to_rf "fall" + } else { + set to_key "none" + } + + if { $from_key != "none" && $to_key == "none" \ + || $from_key == "none" && $to_key != "none" } { + sta_error 459 "-from/-to must be used together." + } elseif { $from_key != "none" && $to_key != "none" } { + # Inter-clock uncertainty. + check_argc_eq0 "unset_clock_uncertainty" $cmd_args + + # -from/-to can be lists. + set from_clks [get_clocks_warn "from_clocks" $keys($from_key)] + set to_clks [get_clocks_warn "to_clocks" $keys($to_key)] + + foreach from_clk $from_clks { + foreach to_clk $to_clks { + unset_inter_clock_uncertainty $from_clk $from_rf \ + $to_clk $to_rf $min_max + } + } + } else { + # Single clock uncertainty. + check_argc_eq1 $cmd $cmd_args + if { [info exists keys(-rise)] \ + || [info exists keys(-fall)] } { + sta_error 460 "-rise, -fall options not allowed for single clock uncertainty." + } + set objects [lindex $cmd_args 0] + parse_clk_port_pin_arg $objects clks pins + + foreach clk $clks { + unset_clock_uncertainty_clk $clk $min_max + } + foreach pin $pins { + unset_clock_uncertainty_pin $pin $min_max + } + } +} + +################################################################ + define_cmd_args "set_data_check" \ {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\ [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\ @@ -1764,6 +1956,66 @@ proc set_data_check { args } { ################################################################ +define_cmd_args "unset_data_check" \ + {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\ + [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\ + [-setup | -hold] [-clock clock]} + +proc unset_data_check { args } { + unset_data_checks_cmd "unset_data_check" $args +} + +proc unset_data_checks_cmd { cmd cmd_args } { + parse_key_args cmd cmd_args \ + keys {-from -rise_from -fall_from -to -rise_to -fall_to -clock} \ + flags {-setup -hold} + check_argc_eq0 $cmd $cmd_args + + set from_rf "rise_fall" + set to_rf "rise_fall" + set clk "NULL" + set setup_hold "max" + if [info exists keys(-from)] { + set from [get_port_pin_error "from_pin" $keys(-from)] + } elseif [info exists keys(-rise_from)] { + set from [get_port_pin_error "from_pin" $keys(-rise_from)] + set from_rf "rise" + } elseif [info exists keys(-fall_from)] { + set from [get_port_pin_error "from_pin" $keys(-fall_from)] + set from_rf "fall" + } else { + sta_error 461 "missing -from, -rise_from or -fall_from argument." + } + + if [info exists keys(-to)] { + set to [get_port_pin_error "to_pin" $keys(-to)] + } elseif [info exists keys(-rise_to)] { + set to [get_port_pin_error "to_pin" $keys(-rise_to)] + set to_rf "rise" + } elseif [info exists keys(-fall_to)] { + set to [get_port_pin_error "to_pin" $keys(-fall_to)] + set to_rf "fall" + } else { + sta_error 462 "missing -to, -rise_to or -fall_to argument." + } + + if [info exists keys(-clock)] { + set clk [get_clock_warn "clock" $keys(-clock)] + } + + if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { + set setup_hold "setup" + } elseif { [info exists flags(-hold)] && ![info exists flags(-setup)] } { + set setup_hold "hold" + } else { + set setup_hold "setup_hold" + } + + unset_data_check_cmd $from $from_rf $to $to_rf $clk $setup_hold +} + +################################################################ + define_cmd_args "set_disable_timing" \ {[-from from_port] [-to to_port] objects} @@ -1899,6 +2151,105 @@ proc parse_disable_cell_ports { cell port_name } { ################################################################ +define_cmd_args "unset_disable_timing" \ + {[-from from_port] [-to to_port] objects} + +proc unset_disable_timing { args } { + unset_disable_cmd "unset_disable_timing" $args +} + +proc unset_disable_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args keys {-from -to} flags {} + check_argc_eq1 $cmd $cmd_args + + set from "" + if { [info exists keys(-from)] } { + set from $keys(-from) + } + set to "" + if { [info exists keys(-to)] } { + set to $keys(-to) + } + parse_libcell_libport_inst_port_pin_edge_timing_arc_set_arg $cmd_args \ + libcells libports insts ports pins edges timing_arc_sets + + if { ([info exists keys(-from)] || [info exists keys(-to)]) \ + && ($libports != {} || $pins != {} || $ports != {}) } { + sta_warn 304 "-from/-to keywords ignored for lib_pin, port and pin arguments." + } + + foreach libcell $libcells { + unset_disable_timing_cell $libcell $from $to + } + foreach libport $libports { + unset_disable_lib_port $libport + } + foreach inst $insts { + unset_disable_timing_instance $inst $from $to + } + foreach pin $pins { + unset_disable_pin $pin + } + foreach port $ports { + unset_disable_port $port + } + foreach edge $edges { + unset_disable_edge $edge + } + foreach timing_arc_set $timing_arc_sets { + unset_disable_timing_arc_set $timing_arc_set + } +} + +proc unset_disable_timing_cell { cell from to } { + set from_ports [parse_disable_cell_ports $cell $from] + set to_ports [parse_disable_cell_ports $cell $to] + if { $from_ports == "NULL" && $to_ports == "NULL" } { + unset_disable_cell $cell "NULL" "NULL" + } elseif { $from_ports == "NULL" } { + foreach to_port $to_ports { + unset_disable_cell $cell "NULL" $to_port + } + } elseif { $to_ports == "NULL" } { + foreach from_port $from_ports { + unset_disable_cell $cell $from_port "NULL" + } + } else { + foreach from_port $from_ports { + foreach to_port $to_ports { + unset_disable_cell $cell $from_port $to_port + } + } + } +} + +proc unset_disable_timing_instance { inst from to } { + set from_ports [parse_disable_inst_ports $inst $from] + set to_ports [parse_disable_inst_ports $inst $to] + if { ![$inst is_leaf] } { + sta_error 463 "-from/-to hierarchical instance not supported." + } + if { $from_ports == "NULL" && $to_ports == "NULL" } { + unset_disable_instance $inst "NULL" "NULL" + } elseif { $from_ports == "NULL" } { + foreach to_port $to_ports { + unset_disable_instance $inst "NULL" $to_port + } + } elseif { $to_ports == "NULL" } { + foreach from_port $from_ports { + unset_disable_instance $inst $from_port "NULL" + } + } else { + foreach from_port $from_ports { + foreach to_port $to_ports { + unset_disable_instance $inst $from_port $to_port + } + } + } +} + +################################################################ + define_cmd_args "set_false_path" \ {[-setup] [-hold] [-rise] [-fall] [-reset_path] [-comment comment]\ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ @@ -2048,6 +2399,17 @@ proc set_port_delay { cmd sta_cmd cmd_args port_dirs } { ################################################################ +define_cmd_args "unset_input_delay" \ + {[-rise] [-fall] [-max] [-min]\ + [-clock clock] [-clock_fall]\ + port_pin_list} + +proc unset_input_delay { args } { + unset_port_delay "unset_input_delay" "unset_input_delay_cmd" $args +} + +################################################################ + define_cmd_args "set_max_delay" \ {[-rise] [-fall] [-ignore_clock_latency] [-reset_path] [-comment comment]\ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ @@ -2237,6 +2599,56 @@ proc set_multicycle_path { args } { ################################################################ +define_cmd_args "unset_path_exceptions" \ + {[-setup] [-hold] [-rise] [-fall] [-from from_list]\ + [-rise_from from_list] [-fall_from from_list]\ + [-through through_list] [-rise_through through_list]\ + [-fall_through through_list] [-to to_list] [-rise_to to_list]\ + [-fall_to to_list]} + +proc unset_path_exceptions { args } { + unset_path_exceptions_cmd "unset_path_exceptions" $args +} + +proc unset_path_exceptions_cmd { cmd cmd_args } { + parse_key_args $cmd cmd_args \ + keys {-from -rise_from -fall_from -to -rise_to -fall_to} \ + flags {-setup -hold -rise -fall} 0 + + set min_max "min_max" + if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { + set min_max "max" + } + if { [info exists flags(-hold)] && ![info exists flags(-setup)] } { + set min_max "min" + } + + set arg_error 0 + set from [parse_from_arg keys arg_error] + set thrus [parse_thrus_arg cmd_args arg_error] + set to [parse_to_arg keys flags arg_error] + if { $arg_error } { + delete_from_thrus_to $from $thrus $to + sta_error 464 "$cmd command failed." + return 0 + } + + check_for_key_args $cmd cmd_args + if { $cmd_args != {} } { + delete_from_thrus_to $from $thrus $to + sta_error 465 "positional arguments not supported." + } + if { ($from == "NULL" && $thrus == "" && $to == "NULL") } { + delete_from_thrus_to $from $thrus $to + sta_error 466 "-from, -through or -to required." + } + + reset_path_cmd $from $thrus $to $min_max + delete_from_thrus_to $from $thrus $to +} + +################################################################ + define_cmd_args "set_output_delay" \ {[-rise] [-fall] [-max] [-min]\ [-clock clock] [-clock_fall]\ @@ -2251,6 +2663,44 @@ proc set_output_delay { args } { ################################################################ +define_cmd_args "unset_output_delay" \ + {[-rise] [-fall] [-max] [-min]\ + [-clock clock] [-clock_fall]\ + port_pin_list} + +proc unset_output_delay { args } { + unset_port_delay "unset_output_delay" "unset_output_delay_cmd" $args +} + +proc unset_port_delay { cmd swig_cmd cmd_args } { + parse_key_args $cmd cmd_args \ + keys {-clock -reference_pin} \ + flags {-rise -fall -max -min -clock_fall } + check_argc_eq1 $cmd $cmd_args + + set pins [get_port_pins_error "pins" [lindex $cmd_args 0]] + + set clk "NULL" + if [info exists keys(-clock)] { + set clk [get_clock_warn "clock" $keys(-clock)] + } + + if [info exists flags(-clock_fall)] { + set clk_rf "fall" + } else { + set clk_rf "rise" + } + + set tr [parse_rise_fall_flags flags] + set min_max [parse_min_max_all_flags flags] + + foreach pin $pins { + $swig_cmd $pin $tr $clk $clk_rf $min_max + } +} + +################################################################ + define_cmd_args "set_propagated_clock" {objects} proc set_propagated_clock { objects } { @@ -2267,6 +2717,20 @@ proc set_propagated_clock { objects } { } } +################################################################ + +define_cmd_args "unset_propagated_clock" {objects} + +proc unset_propagated_clock { objects } { + parse_clk_port_pin_arg $objects clks pins + foreach clk $clks { + unset_propagated_clock_cmd $clk + } + foreach pin $pins { + unset_propagated_clock_pin_cmd $pin + } +} + ################################################################ # # Environment Commands @@ -2295,6 +2759,17 @@ proc set_case_analysis { value pins } { ################################################################ +define_cmd_args "unset_case_analysis" {pins} + +proc unset_case_analysis { pins } { + set pins1 [get_port_pins_error "pins" $pins] + foreach pin $pins1 { + unset_case_analysis_cmd $pin + } +} + +################################################################ + define_cmd_args "set_drive" {[-rise] [-fall] [-min] [-max] \ resistance ports} @@ -2424,6 +2899,12 @@ proc set_driving_cell { args } { } } +proc port_direction_any_output { dir } { + return [expr { $dir == "output" \ + || $dir == "bidirect" \ + || $dir == "tristate" } ] +} + ################################################################ define_cmd_args "set_fanout_load" {fanout ports} @@ -2789,6 +3270,17 @@ proc set_timing_derate { args } { } } +################################################################ + +define_cmd_args "unset_timing_derate" {} + +proc unset_timing_derate { args } { + check_argc_eq0 "unset_timing_derate" $args + unset_timing_derate_cmd +} + +################################################################ + proc parse_from_arg { keys_var arg_error_var } { upvar 1 $keys_var keys diff --git a/tcl/Search.tcl b/tcl/Search.tcl index 59fa0db8..06a06540 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -1109,6 +1109,41 @@ proc report_clock_min_period { args } { } } +################################################################ + +define_cmd_args "set_disable_inferred_clock_gating" { objects } + +proc set_disable_inferred_clock_gating { objects } { + set_disable_inferred_clock_gating_cmd $objects +} + +proc set_disable_inferred_clock_gating_cmd { objects } { + parse_inst_port_pin_arg $objects insts pins + foreach inst $insts { + disable_clock_gating_check_inst $inst + } + foreach pin $pins { + disable_clock_gating_check_pin $pin + } +} + +################################################################ + +define_cmd_args "unset_disable_inferred_clock_gating" { objects } + +proc unset_disable_inferred_clock_gating { objects } { + unset_disable_inferred_clock_gating_cmd $objects +} + +proc unset_disable_inferred_clock_gating_cmd { objects } { + parse_inst_port_pin_arg $objects insts pins + foreach inst $insts { + unset_disable_clock_gating_check_inst $inst + } + foreach pin $pins { + unset_disable_clock_gating_check_pin $pin + } +} ################################################################ diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index 9a72b117..15b3a69d 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -17,932 +17,11 @@ namespace eval sta { ################################################################ -# +# # Non-SDC commands # ################################################################ -define_cmd_args "delete_clock" {[-all] clocks} - -proc delete_clock { args } { - parse_key_args "delete_clock" args keys {} flags {-all} - if { [info exists flags(-all)] } { - check_argc_eq0 "delete_clock" $args - set clks [all_clocks] - } else { - check_argc_eq1 "delete_clock" $args - set clks [get_clocks_warn "clocks" [lindex $args 0]] - } - foreach clk $clks { - remove_clock_cmd $clk - } -} - -################################################################ - -define_cmd_args "delete_generated_clock" {[-all] clocks} - -proc delete_generated_clock { args } { - remove_gclk_cmd "delete_generated_clock" $args -} - -################################################################ - -define_cmd_args "set_disable_inferred_clock_gating" { objects } - -proc set_disable_inferred_clock_gating { objects } { - set_disable_inferred_clock_gating_cmd $objects -} - -proc set_disable_inferred_clock_gating_cmd { objects } { - parse_inst_port_pin_arg $objects insts pins - foreach inst $insts { - disable_clock_gating_check_inst $inst - } - foreach pin $pins { - disable_clock_gating_check_pin $pin - } -} - -################################################################ - -define_cmd_args "unset_case_analysis" {pins} - -proc unset_case_analysis { pins } { - set pins1 [get_port_pins_error "pins" $pins] - foreach pin $pins1 { - unset_case_analysis_cmd $pin - } -} - -################################################################ - -define_cmd_args "unset_clock_groups" \ - {[-logically_exclusive] [-physically_exclusive]\ - [-asynchronous] [-name names] [-all]} - -proc unset_clock_groups { args } { - unset_clk_groups_cmd "unset_clock_groups" $args -} - -proc unset_clk_groups_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args \ - keys {-name} \ - flags {-logically_exclusive -physically_exclusive -asynchronous -all} - - set all [info exists flags(-all)] - set names {} - if {[info exists keys(-name)]} { - set names $keys(-name) - } - - if { $all && $names != {} } { - sta_error 454 "the -all and -name options are mutually exclusive." - } - if { !$all && $names == {} } { - sta_error 455 "either -all or -name options must be specified." - } - - set logically_exclusive [info exists flags(-logically_exclusive)] - set physically_exclusive [info exists flags(-physically_exclusive)] - set asynchronous [info exists flags(-asynchronous)] - - if { ($logically_exclusive+$physically_exclusive+$asynchronous) == 0 } { - sta_error 456 "one of -logically_exclusive, -physically_exclusive or -asynchronous is required." - } - if { ($logically_exclusive+$physically_exclusive+$asynchronous) > 1 } { - sta_error 457 "the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive." - } - - if { $all } { - if { $logically_exclusive } { - unset_clock_groups_logically_exclusive "NULL" - } elseif { $physically_exclusive } { - unset_clock_groups_physically_exclusive "NULL" - } elseif { $asynchronous } { - unset_clock_groups_asynchronous "NULL" - } - } else { - foreach name $names { - if { $logically_exclusive } { - unset_clock_groups_logically_exclusive $name - } elseif { $physically_exclusive } { - unset_clock_groups_physically_exclusive $name - } elseif { $asynchronous } { - unset_clock_groups_asynchronous $name - } - } - } -} - -################################################################ - -define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects} - -proc unset_clock_latency { args } { - unset_clk_latency_cmd "unset_clock_latency" $args -} - -proc unset_clk_latency_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args keys {-clock} flags {-source} - check_argc_eq1 $cmd $cmd_args - set objects [lindex $cmd_args 0] - parse_clk_port_pin_arg $objects clks pins - set pin_clk "NULL" - if { [info exists keys(-clock)] } { - set pin_clk [get_clock_warn "clock" $keys(-clock)] - if { $clks != {} } { - sta_warn 303 "-clock ignored for clock objects." - } - } - - if {[info exists flags(-source)]} { - # Source latency. - foreach clk $clks { - unset_clock_insertion_cmd $clk "NULL" - } - foreach pin $pins { - # Source only allowed on clocks and clock pins. - if { ![is_clock_pin $pin] } { - sta_error 458 "-source '[$pin path_name]' is not a clock pin." - } - unset_clock_insertion_cmd $pin_clk $pin - } - } else { - # Latency. - foreach clk $clks { - unset_clock_latency_cmd $clk "NULL" - } - foreach pin $pins { - unset_clock_latency_cmd $pin_clk $pin - } - } -} - -################################################################ - -define_cmd_args "unset_clock_transition" {clocks} - -proc unset_clock_transition { args } { - check_argc_eq1 "unset_clock_transition" $args - set clks [get_clocks_warn "clocks" [lindex $args 0]] - foreach clk $clks { - unset_clock_slew_cmd $clk - } -} - -################################################################ - -define_cmd_args "unset_clock_uncertainty" \ - {[-from|-rise_from|-fall_from from_clock]\ - [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\ - [-setup] [-hold] [objects]} - -proc unset_clock_uncertainty { args } { - unset_clk_uncertainty_cmd "unset_clock_uncertainty" $args -} - -proc unset_clk_uncertainty_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args \ - keys {-from -rise_from -fall_from -to -rise_to -fall_to} \ - flags {-rise -fall -setup -hold} - - set min_max "min_max" - if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { - set min_max "max" - } - if { [info exists flags(-hold)] && ![info exists flags(-setup)] } { - set min_max "min" - } - - if { [info exists keys(-from)] } { - set from_key "-from" - set from_rf "rise_fall" - } elseif { [info exists keys(-rise_from)] } { - set from_key "-rise_from" - set from_rf "rise" - } elseif { [info exists keys(-fall_from)] } { - set from_key "-fall_from" - set from_rf "fall" - } else { - set from_key "none" - } - - if { [info exists keys(-to)] } { - set to_key "-to" - set to_rf "rise_fall" - } elseif { [info exists keys(-rise_to)] } { - set to_key "-rise_to" - set to_rf "rise" - } elseif { [info exists keys(-fall_to)] } { - set to_key "-fall_to" - set to_rf "fall" - } else { - set to_key "none" - } - - if { $from_key != "none" && $to_key == "none" \ - || $from_key == "none" && $to_key != "none" } { - sta_error 459 "-from/-to must be used together." - } elseif { $from_key != "none" && $to_key != "none" } { - # Inter-clock uncertainty. - check_argc_eq0 "unset_clock_uncertainty" $cmd_args - - # -from/-to can be lists. - set from_clks [get_clocks_warn "from_clocks" $keys($from_key)] - set to_clks [get_clocks_warn "to_clocks" $keys($to_key)] - - foreach from_clk $from_clks { - foreach to_clk $to_clks { - unset_inter_clock_uncertainty $from_clk $from_rf \ - $to_clk $to_rf $min_max - } - } - } else { - # Single clock uncertainty. - check_argc_eq1 $cmd $cmd_args - if { [info exists keys(-rise)] \ - || [info exists keys(-fall)] } { - sta_error 460 "-rise, -fall options not allowed for single clock uncertainty." - } - set objects [lindex $cmd_args 0] - parse_clk_port_pin_arg $objects clks pins - - foreach clk $clks { - unset_clock_uncertainty_clk $clk $min_max - } - foreach pin $pins { - unset_clock_uncertainty_pin $pin $min_max - } - } -} - -################################################################ - -define_cmd_args "unset_data_check" \ - {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\ - [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\ - [-setup | -hold] [-clock clock]} - -proc unset_data_check { args } { - unset_data_checks_cmd "unset_data_check" $args -} - -proc unset_data_checks_cmd { cmd cmd_args } { - parse_key_args cmd cmd_args \ - keys {-from -rise_from -fall_from -to -rise_to -fall_to -clock} \ - flags {-setup -hold} - check_argc_eq0 $cmd $cmd_args - - set from_rf "rise_fall" - set to_rf "rise_fall" - set clk "NULL" - set setup_hold "max" - if [info exists keys(-from)] { - set from [get_port_pin_error "from_pin" $keys(-from)] - } elseif [info exists keys(-rise_from)] { - set from [get_port_pin_error "from_pin" $keys(-rise_from)] - set from_rf "rise" - } elseif [info exists keys(-fall_from)] { - set from [get_port_pin_error "from_pin" $keys(-fall_from)] - set from_rf "fall" - } else { - sta_error 461 "missing -from, -rise_from or -fall_from argument." - } - - if [info exists keys(-to)] { - set to [get_port_pin_error "to_pin" $keys(-to)] - } elseif [info exists keys(-rise_to)] { - set to [get_port_pin_error "to_pin" $keys(-rise_to)] - set to_rf "rise" - } elseif [info exists keys(-fall_to)] { - set to [get_port_pin_error "to_pin" $keys(-fall_to)] - set to_rf "fall" - } else { - sta_error 462 "missing -to, -rise_to or -fall_to argument." - } - - if [info exists keys(-clock)] { - set clk [get_clock_warn "clock" $keys(-clock)] - } - - if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { - set setup_hold "setup" - } elseif { [info exists flags(-hold)] && ![info exists flags(-setup)] } { - set setup_hold "hold" - } else { - set setup_hold "setup_hold" - } - - unset_data_check_cmd $from $from_rf $to $to_rf $clk $setup_hold -} - -################################################################ - -define_cmd_args "unset_disable_inferred_clock_gating" { objects } - -proc unset_disable_inferred_clock_gating { objects } { - unset_disable_inferred_clock_gating_cmd $objects -} - -proc unset_disable_inferred_clock_gating_cmd { objects } { - parse_inst_port_pin_arg $objects insts pins - foreach inst $insts { - unset_disable_clock_gating_check_inst $inst - } - foreach pin $pins { - unset_disable_clock_gating_check_pin $pin - } -} - -################################################################ - -define_cmd_args "unset_disable_timing" \ - {[-from from_port] [-to to_port] objects} - -proc unset_disable_timing { args } { - unset_disable_cmd "unset_disable_timing" $args -} - -proc unset_disable_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args keys {-from -to} flags {} - check_argc_eq1 $cmd $cmd_args - - set from "" - if { [info exists keys(-from)] } { - set from $keys(-from) - } - set to "" - if { [info exists keys(-to)] } { - set to $keys(-to) - } - parse_libcell_libport_inst_port_pin_edge_timing_arc_set_arg $cmd_args \ - libcells libports insts ports pins edges timing_arc_sets - - if { ([info exists keys(-from)] || [info exists keys(-to)]) \ - && ($libports != {} || $pins != {} || $ports != {}) } { - sta_warn 304 "-from/-to keywords ignored for lib_pin, port and pin arguments." - } - - foreach libcell $libcells { - unset_disable_timing_cell $libcell $from $to - } - foreach libport $libports { - unset_disable_lib_port $libport - } - foreach inst $insts { - unset_disable_timing_instance $inst $from $to - } - foreach pin $pins { - unset_disable_pin $pin - } - foreach port $ports { - unset_disable_port $port - } - foreach edge $edges { - unset_disable_edge $edge - } - foreach timing_arc_set $timing_arc_sets { - unset_disable_timing_arc_set $timing_arc_set - } -} - -proc unset_disable_timing_cell { cell from to } { - set from_ports [parse_disable_cell_ports $cell $from] - set to_ports [parse_disable_cell_ports $cell $to] - if { $from_ports == "NULL" && $to_ports == "NULL" } { - unset_disable_cell $cell "NULL" "NULL" - } elseif { $from_ports == "NULL" } { - foreach to_port $to_ports { - unset_disable_cell $cell "NULL" $to_port - } - } elseif { $to_ports == "NULL" } { - foreach from_port $from_ports { - unset_disable_cell $cell $from_port "NULL" - } - } else { - foreach from_port $from_ports { - foreach to_port $to_ports { - unset_disable_cell $cell $from_port $to_port - } - } - } -} - -proc unset_disable_timing_instance { inst from to } { - set from_ports [parse_disable_inst_ports $inst $from] - set to_ports [parse_disable_inst_ports $inst $to] - if { ![$inst is_leaf] } { - sta_error 463 "-from/-to hierarchical instance not supported." - } - if { $from_ports == "NULL" && $to_ports == "NULL" } { - unset_disable_instance $inst "NULL" "NULL" - } elseif { $from_ports == "NULL" } { - foreach to_port $to_ports { - unset_disable_instance $inst "NULL" $to_port - } - } elseif { $to_ports == "NULL" } { - foreach from_port $from_ports { - unset_disable_instance $inst $from_port "NULL" - } - } else { - foreach from_port $from_ports { - foreach to_port $to_ports { - unset_disable_instance $inst $from_port $to_port - } - } - } -} - -################################################################ - -define_cmd_args "unset_generated_clock" {[-all] clocks} - -proc unset_generated_clock { args } { - unset_gclk_cmd "unset_generated_clock" $args -} - -proc remove_gclk_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args keys {} flags {-all} - if { [info exists flags(-all)] } { - check_argc_eq0 $cmd $cmd_args - set clks [all_clocks] - } else { - check_argc_eq1 $cmd $cmd_args - set clks [get_clocks_warn "clocks" [lindex $cmd_args 0]] - } - foreach clk $clks { - if { [$clk is_generated] } { - remove_clock_cmd $clk - } - } -} - -################################################################ - -define_cmd_args "unset_input_delay" \ - {[-rise] [-fall] [-max] [-min]\ - [-clock clock] [-clock_fall]\ - port_pin_list} - -proc unset_input_delay { args } { - unset_port_delay "unset_input_delay" "unset_input_delay_cmd" $args -} - -################################################################ - -define_cmd_args "unset_output_delay" \ - {[-rise] [-fall] [-max] [-min]\ - [-clock clock] [-clock_fall]\ - port_pin_list} - -proc unset_output_delay { args } { - unset_port_delay "unset_output_delay" "unset_output_delay_cmd" $args -} - -proc unset_port_delay { cmd swig_cmd cmd_args } { - parse_key_args $cmd cmd_args \ - keys {-clock -reference_pin} \ - flags {-rise -fall -max -min -clock_fall } - check_argc_eq1 $cmd $cmd_args - - set pins [get_port_pins_error "pins" [lindex $cmd_args 0]] - - set clk "NULL" - if [info exists keys(-clock)] { - set clk [get_clock_warn "clock" $keys(-clock)] - } - - if [info exists flags(-clock_fall)] { - set clk_rf "fall" - } else { - set clk_rf "rise" - } - - set tr [parse_rise_fall_flags flags] - set min_max [parse_min_max_all_flags flags] - - foreach pin $pins { - $swig_cmd $pin $tr $clk $clk_rf $min_max - } -} - -################################################################ - -define_cmd_args "unset_path_exceptions" \ - {[-setup] [-hold] [-rise] [-fall] [-from from_list]\ - [-rise_from from_list] [-fall_from from_list]\ - [-through through_list] [-rise_through through_list]\ - [-fall_through through_list] [-to to_list] [-rise_to to_list]\ - [-fall_to to_list]} - -proc unset_path_exceptions { args } { - unset_path_exceptions_cmd "unset_path_exceptions" $args -} - -proc unset_path_exceptions_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args \ - keys {-from -rise_from -fall_from -to -rise_to -fall_to} \ - flags {-setup -hold -rise -fall} 0 - - set min_max "min_max" - if { [info exists flags(-setup)] && ![info exists flags(-hold)] } { - set min_max "max" - } - if { [info exists flags(-hold)] && ![info exists flags(-setup)] } { - set min_max "min" - } - - set arg_error 0 - set from [parse_from_arg keys arg_error] - set thrus [parse_thrus_arg cmd_args arg_error] - set to [parse_to_arg keys flags arg_error] - if { $arg_error } { - delete_from_thrus_to $from $thrus $to - sta_error 464 "$cmd command failed." - return 0 - } - - check_for_key_args $cmd cmd_args - if { $cmd_args != {} } { - delete_from_thrus_to $from $thrus $to - sta_error 465 "positional arguments not supported." - } - if { ($from == "NULL" && $thrus == "" && $to == "NULL") } { - delete_from_thrus_to $from $thrus $to - sta_error 466 "-from, -through or -to required." - } - - reset_path_cmd $from $thrus $to $min_max - delete_from_thrus_to $from $thrus $to -} - -################################################################ - -define_cmd_args "unset_propagated_clock" {objects} - -proc unset_propagated_clock { objects } { - parse_clk_port_pin_arg $objects clks pins - foreach clk $clks { - unset_propagated_clock_cmd $clk - } - foreach pin $pins { - unset_propagated_clock_pin_cmd $pin - } -} - -################################################################ - -define_cmd_args "unset_timing_derate" {} - -proc unset_timing_derate { args } { - check_argc_eq0 "unset_timing_derate" $args - unset_timing_derate_cmd -} - -################################################################ -# -# Network editing commands -# -################################################################ - -define_cmd_args "connect_pin" {net pin} -# deprecated 2.0.16 05/02/2019 -define_cmd_args "connect_pins" {net pins} - -define_cmd_args "delete_instance" {inst} - -define_cmd_args "delete_net" {net} - -define_cmd_args "disconnect_pin" {net -all|pin} -# deprecated 2.0.16 05/02/2019 -define_cmd_args "disconnect_pins" {net -all|pins} - -define_cmd_args "make_instance" {inst_path lib_cell} - -define_cmd_args "make_net" {} - -define_cmd_args "replace_cell" {instance lib_cell} - -define_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\ - buffer_out_net_name} - -################################################################ -# -# Delay calculation commands -# -################################################################ - -define_cmd_args "set_assigned_delay" \ - {-cell|-net [-rise] [-fall] [-corner corner] [-min] [-max]\ - [-from from_pins] [-to to_pins] delay} - -# Change the delay for timing arcs between from_pins and to_pins matching -# on cell (instance) or net. -proc set_assigned_delay { args } { - set_assigned_delay_cmd "set_assigned_delay" $args -} - -proc set_assigned_delay_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args keys {-corner -from -to} \ - flags {-cell -net -rise -fall -max -min} - check_argc_eq1 $cmd $cmd_args - set corner [parse_corner keys] - set min_max [parse_min_max_all_check_flags flags] - set to_rf [parse_rise_fall_flags flags] - - if [info exists keys(-from)] { - set from_pins [get_port_pins_error "from_pins" $keys(-from)] - } else { - sta_error 442 "$cmd missing -from argument." - } - if [info exists keys(-to)] { - set to_pins [get_port_pins_error "to_pins" $keys(-to)] - } else { - sta_error 443 "$cmd missing -to argument." - } - - set delay [lindex $cmd_args 0] - if {![string is double $delay]} { - sta_error 444 "$cmd delay is not a float." - } - set delay [time_ui_sta $delay] - - if {[info exists flags(-cell)] && [info exists flags(-net)]} { - sta_error 445 "set_annotated_delay -cell and -net options are mutually excluive." - } elseif {[info exists flags(-cell)]} { - if { $from_pins != {} } { - set inst [[lindex $from_pins 0] instance] - foreach pin $from_pins { - if {[$pin instance] != $inst} { - sta_error 446 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]." - } - } - foreach pin $to_pins { - if {[$pin instance] != $inst} { - sta_error 447 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]" - } - } - } - } elseif {![info exists flags(-net)]} { - sta_error 448 "$cmd -cell or -net required." - } - foreach from_pin $from_pins { - set from_vertices [$from_pin vertices] - set_assigned_delay1 [lindex $from_vertices 0] \ - $to_pins $to_rf $corner $min_max $delay - if { [llength $from_vertices] == 2 } { - set_assigned_delay1 [lindex $from_vertices 1] \ - $to_pins $to_rf $corner $min_max $delay - } - } -} - -proc set_assigned_delay1 { from_vertex to_pins to_rf corner min_max delay } { - foreach to_pin $to_pins { - set to_vertices [$to_pin vertices] - set_assigned_delay2 $from_vertex [lindex $to_vertices 0] \ - $to_rf $corner $min_max $delay - if { [llength $to_vertices] == 2 } { - # Bidirect driver. - set_assigned_delay2 $from_vertex [lindex $to_vertices 1] \ - $to_rf $corner $min_max $delay - } - } -} - -proc set_assigned_delay2 {from_vertex to_vertex to_rf corner min_max delay} { - set edge_iter [$from_vertex out_edge_iterator] - while {[$edge_iter has_next]} { - set edge [$edge_iter next] - if { [$edge to] == $to_vertex \ - && ![timing_role_is_check [$edge role]] } { - foreach arc [$edge timing_arcs] { - if { $to_rf == "rise_fall" \ - || $to_rf eq [$arc to_edge_name] } { - set_arc_delay $edge $arc $corner $min_max $delay - } - } - } - } - $edge_iter finish -} - -################################################################ - -define_cmd_args "set_assigned_check" \ - {-setup|-hold|-recovery|-removal [-rise] [-fall]\ - [-corner corner] [-min] [-max]\ - [-from from_pins] [-to to_pins] [-clock rise|fall]\ - [-cond sdf_cond] check_value} - -proc set_assigned_check { args } { - set_assigned_check_cmd "set_assigned_check" $args -} - -proc set_assigned_check_cmd { cmd cmd_args } { - parse_key_args $cmd cmd_args \ - keys {-from -to -corner -clock -cond} \ - flags {-setup -hold -recovery -removal -rise -fall -max -min} - check_argc_eq1 $cmd $cmd_args - - if { [info exists keys(-from)] } { - set from_pins [get_port_pins_error "from_pins" $keys(-from)] - } else { - sta_error 449 "$cmd missing -from argument." - } - set from_rf "rise_fall" - if { [info exists keys(-clock)] } { - set clk_arg $keys(-clock) - if { $clk_arg eq "rise" \ - || $clk_arg eq "fall" } { - set from_rf $clk_arg - } else { - sta_error 450 "$cmd -clock must be rise or fall." - } - } - - if { [info exists keys(-to)] } { - set to_pins [get_port_pins_error "to_pins" $keys(-to)] - } else { - sta_error 451 "$cmd missing -to argument." - } - set to_rf [parse_rise_fall_flags flags] - set corner [parse_corner keys] - set min_max [parse_min_max_all_check_flags flags] - - if { [info exists flags(-setup)] } { - set role "setup" - } elseif { [info exists flags(-hold)] } { - set role "hold" - } elseif { [info exists flags(-recovery)] } { - set role "recovery" - } elseif { [info exists flags(-removal)] } { - set role "removal" - } else { - sta_error 452 "$cmd missing -setup|-hold|-recovery|-removal check type.." - } - set cond "" - if { [info exists key(-cond)] } { - set cond $key(-cond) - } - set check_value [lindex $cmd_args 0] - if { ![string is double $check_value] } { - sta_error 453 "$cmd check_value is not a float." - } - set check_value [time_ui_sta $check_value] - - foreach from_pin $from_pins { - set from_vertices [$from_pin vertices] - set_assigned_check1 [lindex $from_vertices 0] $from_rf \ - $to_pins $to_rf $role $corner $min_max $cond $check_value - if { [llength $from_vertices] == 2 } { - set_assigned_check1 [lindex $from_vertices 1] $from_rf \ - $to_pins $to_rf $role $corner $min_max $cond $check_value - } - } -} - -proc set_assigned_check1 { from_vertex from_rf to_pins to_rf \ - role corner min_max cond check_value } { - foreach to_pin $to_pins { - set to_vertices [$to_pin vertices] - set_assigned_check2 $from_vertex $from_rf [lindex $to_vertices 0] \ - $to_rf $role $corner $min_max $cond $check_value - if { [llength $to_vertices] == 2 } { - # Bidirect driver. - set_assigned_check2 $from_vertex $from_rf \ - [lindex $to_vertices 1] $to_rf $role $corner $min_max \ - $cond $check_value - } - } -} - -proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \ - role corner min_max cond check_value } { - set edge_iter [$from_vertex out_edge_iterator] - while {[$edge_iter has_next]} { - set edge [$edge_iter next] - if { [$edge to] == $to_vertex } { - foreach arc [$edge timing_arcs] { - if { ($from_rf eq "rise_fall" \ - || $from_rf eq [$arc from_edge_name]) \ - && ($to_rf eq "rise_fall" \ - || $to_rf eq [$arc to_edge_name]) \ - && [$arc role] eq $role \ - && ($cond eq "" || [$arc sdf_cond] eq $cond) } { - set_arc_delay $edge $arc $corner $min_max $check_value - } - } - } - } - $edge_iter finish -} - -################################################################a - -define_cmd_args "set_assigned_transition" \ - {[-rise] [-fall] [-corner corner] [-min] [-max] slew pins} - -# Change the slew on a list of ports. -proc set_assigned_transition { args } { - parse_key_args "set_assigned_transition" args keys {-corner} \ - flags {-rise -fall -max -min} - - set corner [parse_corner keys] - set min_max [parse_min_max_all_check_flags flags] - set tr [parse_rise_fall_flags flags] - check_argc_eq2 "set_assigned_transition" $args - - set slew [lindex $args 0] - if {![string is double $slew]} { - sta_error 428 "set_assigned_transition transition is not a float." - } - set slew [time_ui_sta $slew] - set pins [get_port_pins_error "pins" [lindex $args 1]] - foreach pin $pins { - set vertices [$pin vertices] - set vertex [lindex $vertices 0] - set_annotated_slew $vertex $corner $min_max $tr $slew - if { [llength $vertices] == 2 } { - # Bidirect driver. - set vertex [lindex $vertices 1] - set_annotated_slew $vertex $min_max $tr $slew - } - } -} - -################################################################a - -# compatibility -define_cmd_args "read_parasitics" \ - {[-min]\ - [-max]\ - [-elmore]\ - [-path path]\ - [-increment]\ - [-pin_cap_included]\ - [-keep_capacitive_coupling]\ - [-coupling_reduction_factor factor]\ - [-reduce_to pi_elmore|pi_pole_residue2]\ - [-delete_after_reduce]\ - [-quiet]\ - [-save]\ - filename} - -################################################################ -# -# Utility commands -# -################################################################ - -define_cmd_args "delete_from_list" {list objs} - -proc delete_from_list { list objects } { - delete_objects_from_list_cmd $list $objects -} - -proc delete_objects_from_list_cmd { list objects } { - set list0 [lindex $list 0] - set list_is_object [is_object $list0] - set list_type [object_type $list0] - foreach obj $objects { - # If the list is a collection of tcl objects (returned by get_*), - # convert the obj to be removed from a name to an object of the same - # type. - if {$list_is_object && ![is_object $obj]} { - if {$list_type == "Clock"} { - set obj [find_clock $obj] - } elseif {$list_type == "Port"} { - set top_instance [top_instance] - set top_cell [$top_instance cell] - set obj [$top_cell find_port $obj] - } elseif {$list_type == "Pin"} { - set obj [find_pin $obj] - } elseif {$list_type == "Instance"} { - set obj [find_instance $obj] - } elseif {$list_type == "Net"} { - set obj [find_net $obj] - } elseif {$list_type == "LibertyLibrary"} { - set obj [find_liberty $obj] - } elseif {$list_type == "LibertyCell"} { - set obj [find_liberty_cell $obj] - } elseif {$list_type == "LibertyPort"} { - set obj [get_lib_pins $obj] - } else { - sta_error 439 "unsupported object type $list_type." - } - } - set index [lsearch $list $obj] - if { $index != -1 } { - set list [lreplace $list $index $index] - } - } - return $list -} - -################################################################ - define_cmd_args "get_fanin" \ {-to sink_list [-flat] [-only_cells] [-startpoints_only]\ [-levels level_count] [-pin_levels pin_count]\ @@ -1060,162 +139,6 @@ proc get_fanout { args } { ################################################################ -define_cmd_args "get_name" {objects} -define_cmd_args "get_full_name" {objects} - -################################################################ - -define_cmd_args "get_property" \ - {[-object_type cell|pin|net|port|clock|timing_arc] object property} - -proc get_property { args } { - return [get_property_cmd "get_property" "-object_type" $args] -} - -################################################################ - -proc get_property_cmd { cmd type_key cmd_args } { - parse_key_args $cmd cmd_args keys $type_key flags {-quiet} - set quiet [info exists flags(-quiet)] - check_argc_eq2 $cmd $cmd_args - set object [lindex $cmd_args 0] - if { $object == "" } { - sta_error 491 "$cmd object is null." - } elseif { ![is_object $object] } { - if [info exists keys($type_key)] { - set object_type $keys($type_key) - } else { - sta_error 492 "$cmd $type_key must be specified with object name argument." - } - set object [get_property_object_type $object_type $object $quiet] - } - set prop [lindex $cmd_args 1] - return [get_object_property $object $prop] -} - -proc get_object_property { object prop } { - if { [is_object $object] } { - set object_type [object_type $object] - if { $object_type == "Instance" } { - return [instance_property $object $prop] - } elseif { $object_type == "Pin" } { - return [pin_property $object $prop] - } elseif { $object_type == "Net" } { - return [net_property $object $prop] - } elseif { $object_type == "Clock" } { - return [clock_property $object $prop] - } elseif { $object_type == "Port" } { - return [port_property $object $prop] - } elseif { $object_type == "LibertyPort" } { - return [liberty_port_property $object $prop] - } elseif { $object_type == "LibertyCell" } { - return [liberty_cell_property $object $prop] - } elseif { $object_type == "Cell" } { - return [cell_property $object $prop] - } elseif { $object_type == "Library" } { - return [library_property $object $prop] - } elseif { $object_type == "LibertyLibrary" } { - return [liberty_library_property $object $prop] - } elseif { $object_type == "Edge" } { - return [edge_property $object $prop] - } elseif { $object_type == "PathEnd" } { - return [path_end_property $object $prop] - } elseif { $object_type == "PathRef" } { - return [path_ref_property $object $prop] - } elseif { $object_type == "TimingArcSet" } { - return [timing_arc_set_property $object $prop] - } else { - sta_error 606 "get_property unsupported object type $object_type." - } - } else { - sta_error 493 "get_property $object is not an object." - } -} - -proc get_property_object_type { object_type object_name quiet } { - set object "NULL" - if { $object_type == "instance" \ - || $object_type == "cell"} { - set object [get_cells -quiet $object_name] - } elseif { $object_type == "pin" } { - set object [get_pins -quiet $object_name] - } elseif { $object_type == "net" } { - set object [get_nets -quiet $object_name] - } elseif { $object_type == "port" } { - set object [get_ports -quiet $object_name] - } elseif { $object_type == "clock" } { - set object [get_clocks -quiet $object_name] - } elseif { $object_type == "liberty_cell" \ - || $object_type == "lib_cell"} { - set object [get_lib_cells -quiet $object_name] - } elseif { $object_type == "liberty_port" \ - || $object_type == "lib_pin" } { - set object [get_lib_pins -quiet $object_name] - } elseif { $object_type == "library" \ - || $object_type == "lib"} { - set object [get_libs -quiet $object_name] - } else { - sta_error 494 "$object_type not supported." - } - if { $object == "NULL" && !$quiet } { - sta_error 495 "$object_type '$object_name' not found." - } - return [lindex $object 0] -} - -proc get_object_type { obj } { - set object_type [object_type $obj] - if { $object_type == "Clock" } { - return "clock" - } elseif { $object_type == "LibertyCell" } { - return "lib_cell" - } elseif { $object_type == "LibertyPort" } { - return "lib_pin" - } elseif { $object_type == "Cell" } { - return "cell" - } elseif { $object_type == "Instance" } { - return "instance" - } elseif { $object_type == "Port" } { - return "port" - } elseif { $object_type == "Pin" } { - return "pin" - } elseif { $object_type == "Net" } { - return "net" - } elseif { $object_type == "Edge" } { - return "timing_arc" - } elseif { $object_type == "TimingArcSet" } { - return "timing_arc" - } else { - return "?" - } -} - -proc get_name { object } { - return [get_object_property $object "name"] -} - -proc get_full_name { object } { - return [get_object_property $object "full_name"] -} - -proc sort_by_name { objects } { - return [lsort -command name_cmp $objects] -} - -proc name_cmp { obj1 obj2 } { - return [string compare [get_name $obj1] [get_name $obj2]] -} - -proc sort_by_full_name { objects } { - return [lsort -command full_name_cmp $objects] -} - -proc full_name_cmp { obj1 obj2 } { - return [string compare [get_full_name $obj1] [get_full_name $obj2]] -} - -################################################################ - define_cmd_args "get_timing_edges" \ {[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]} @@ -1408,132 +331,5 @@ proc report_clock1 { clk } { } } -################################################################ - -define_cmd_args "report_object_full_names" {objects} - -proc report_object_full_names { objects } { - foreach obj [sort_by_full_name $objects] { - report_line [get_full_name $obj] - } -} - -define_cmd_args "report_object_names" {objects} - -proc report_object_names { objects } { - foreach obj [sort_by_name $objects] { - report_line [get_name $obj] - } -} - -################################################################ - -define_cmd_args "report_units" {} - -proc report_units { args } { - check_argc_eq0 "report_units" $args - foreach unit {"time" "capacitance" "resistance" "voltage" "current" "power" "distance"} { - report_line " $unit 1[unit_scale_abreviation $unit][unit_suffix $unit]" - } -} - -################################################################ - -define_cmd_args "with_output_to_variable" { var { cmds }} - -# with_output_to_variable variable { command args... } -proc with_output_to_variable { var_name args } { - upvar 1 $var_name var - - set body [lindex $args 0] - sta::redirect_string_begin; - catch $body ret - set var [sta::redirect_string_end] - return $ret -} - -define_cmd_args "set_pocv_sigma_factor" { factor } - -################################################################ - -define_cmd_args "write_path_spice" { -path_args path_args\ - -spice_directory spice_directory\ - -lib_subckt_file lib_subckts_file\ - -model_file model_file\ - -power power\ - -ground ground} - -proc write_path_spice { args } { - parse_key_args "write_path_spice" args \ - keys {-spice_directory -lib_subckt_file -model_file \ - -power -ground -path_args} \ - flags {} - - if { [info exists keys(-spice_directory)] } { - set spice_dir [file nativename $keys(-spice_directory)] - if { ![file exists $spice_dir] } { - sta_error 496 "Directory $spice_dir not found." - } - if { ![file isdirectory $spice_dir] } { - sta_error 497 "$spice_dir is not a directory." - } - if { ![file writable $spice_dir] } { - sta_error 498 "Cannot write in $spice_dir." - } - } else { - sta_error 499 "No -spice_directory specified." - } - - if { [info exists keys(-lib_subckt_file)] } { - set lib_subckt_file [file nativename $keys(-lib_subckt_file)] - if { ![file readable $lib_subckt_file] } { - sta_error 500 "-lib_subckt_file $lib_subckt_file is not readable." - } - } else { - sta_error 501 "No -lib_subckt_file specified." - } - - if { [info exists keys(-model_file)] } { - set model_file [file nativename $keys(-model_file)] - if { ![file readable $model_file] } { - sta_error 502 "-model_file $model_file is not readable." - } - } else { - sta_error 503 "No -model_file specified." - } - - if { [info exists keys(-power)] } { - set power $keys(-power) - } else { - sta_error 504 "No -power specified." - } - - if { [info exists keys(-ground)] } { - set ground $keys(-ground) - } else { - sta_error 505 "No -ground specified." - } - - if { ![info exists keys(-path_args)] } { - sta_error 506 "No -path_args specified." - } - set path_args $keys(-path_args) - set path_ends [eval [concat find_timing_paths $path_args]] - if { $path_ends == {} } { - sta_error 507 "No paths found for -path_args $path_args." - } else { - set path_index 1 - foreach path_end $path_ends { - set path [$path_end path] - set path_name "path_$path_index" - set spice_file [file join $spice_dir "$path_name.sp"] - set subckt_file [file join $spice_dir "$path_name.subckt"] - write_path_spice_cmd $path $spice_file $subckt_file \ - $lib_subckt_file $model_file $power $ground - incr path_index - } - } -} - # sta namespace end. } diff --git a/tcl/Util.tcl b/tcl/Util.tcl index 0e0e0887..c4b4c016 100644 --- a/tcl/Util.tcl +++ b/tcl/Util.tcl @@ -177,78 +177,6 @@ proc define_hidden_cmd_args { cmd arglist } { namespace export $cmd } -# This is used in lieu of command completion to make sdc commands -# like get_ports be abbreviated get_port. -proc define_cmd_alias { alias cmd } { - eval "proc $alias { args } { eval [concat $cmd \$args] }" - namespace export $alias -} - -proc cmd_usage_error { cmd } { - variable cmd_args - - if [info exists cmd_args($cmd)] { - sta_error 404 "Usage: $cmd $cmd_args($cmd)" - } else { - sta_error 405 "Usage: $cmd argument error" - } -} - -################################################################ - -define_cmd_args "help" {[pattern]} - -proc_redirect help { - variable cmd_args - - set arg_count [llength $args] - if { $arg_count == 0 } { - set pattern "*" - } elseif { $arg_count == 1 } { - set pattern [lindex $args 0] - } else { - cmd_usage_error "help" - } - set matches [array names cmd_args $pattern] - if { $matches != {} } { - foreach cmd [lsort $matches] { - show_cmd_args $cmd - } - } else { - sta_warn 300 "no commands match '$pattern'." - } -} - -proc show_cmd_args { cmd } { - variable cmd_args - - set max_col 80 - set indent 2 - set indent_str " " - set line $cmd - set col [string length $cmd] - set arglist $cmd_args($cmd) - # Break the arglist up into max_col length lines. - while {1} { - if {[regexp {(^[\n ]*)([a-zA-Z0-9_\\\|\-]+|\[[^\[]+\])(.*)} \ - $arglist ignore space arg rest]} { - set arg_length [string length $arg] - if { $col + $arg_length < $max_col } { - set line "$line $arg" - set col [expr $col + $arg_length + 1] - } else { - report_line $line - set line "$indent_str $arg" - set col [expr $indent + $arg_length + 1] - } - set arglist $rest - } else { - report_line $line - break - } - } -} - ################################################################ proc sta_warn { msg_id msg } { diff --git a/tcl/WritePathSpice.tcl b/tcl/WritePathSpice.tcl new file mode 100644 index 00000000..f8d33cb7 --- /dev/null +++ b/tcl/WritePathSpice.tcl @@ -0,0 +1,99 @@ +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2022, 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 . + +namespace eval sta { + +define_cmd_args "write_path_spice" { -path_args path_args\ + -spice_directory spice_directory\ + -lib_subckt_file lib_subckts_file\ + -model_file model_file\ + -power power\ + -ground ground} + +proc write_path_spice { args } { + parse_key_args "write_path_spice" args \ + keys {-spice_directory -lib_subckt_file -model_file \ + -power -ground -path_args} \ + flags {} + + if { [info exists keys(-spice_directory)] } { + set spice_dir [file nativename $keys(-spice_directory)] + if { ![file exists $spice_dir] } { + sta_error 496 "Directory $spice_dir not found." + } + if { ![file isdirectory $spice_dir] } { + sta_error 497 "$spice_dir is not a directory." + } + if { ![file writable $spice_dir] } { + sta_error 498 "Cannot write in $spice_dir." + } + } else { + sta_error 499 "No -spice_directory specified." + } + + if { [info exists keys(-lib_subckt_file)] } { + set lib_subckt_file [file nativename $keys(-lib_subckt_file)] + if { ![file readable $lib_subckt_file] } { + sta_error 500 "-lib_subckt_file $lib_subckt_file is not readable." + } + } else { + sta_error 501 "No -lib_subckt_file specified." + } + + if { [info exists keys(-model_file)] } { + set model_file [file nativename $keys(-model_file)] + if { ![file readable $model_file] } { + sta_error 502 "-model_file $model_file is not readable." + } + } else { + sta_error 503 "No -model_file specified." + } + + if { [info exists keys(-power)] } { + set power $keys(-power) + } else { + sta_error 504 "No -power specified." + } + + if { [info exists keys(-ground)] } { + set ground $keys(-ground) + } else { + sta_error 505 "No -ground specified." + } + + if { ![info exists keys(-path_args)] } { + sta_error 506 "No -path_args specified." + } + set path_args $keys(-path_args) + set path_ends [eval [concat find_timing_paths $path_args]] + if { $path_ends == {} } { + sta_error 507 "No paths found for -path_args $path_args." + } else { + set path_index 1 + foreach path_end $path_ends { + set path [$path_end path] + set path_name "path_$path_index" + set spice_file [file join $spice_dir "$path_name.sp"] + set subckt_file [file join $spice_dir "$path_name.subckt"] + write_path_spice_cmd $path $spice_file $subckt_file \ + $lib_subckt_file $model_file $power $ground + incr path_index + } + } +} + +# sta namespace end. +}