OpenSTA/tcl/Sta.tcl

1540 lines
45 KiB
Tcl
Raw Normal View History

2018-09-28 17:54:21 +02:00
# OpenSTA, Static Timing Analyzer
# Copyright (c) 2022, Parallax Software, Inc.
2018-09-28 17:54:21 +02:00
#
# 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
2018-09-28 17:54:21 +02:00
# 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 <https://www.gnu.org/licenses/>.
2018-09-28 17:54:21 +02:00
namespace eval sta {
################################################################
#
2021-04-26 04:16:34 +02:00
# Non-SDC commands
#
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "delete_clock" {[-all] clocks}
2018-09-28 17:54:21 +02:00
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
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "delete_generated_clock" {[-all] clocks}
2018-09-28 17:54:21 +02:00
proc delete_generated_clock { args } {
remove_gclk_cmd "delete_generated_clock" $args
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "set_disable_inferred_clock_gating" { objects }
2018-09-28 17:54:21 +02:00
proc set_disable_inferred_clock_gating { objects } {
set_disable_inferred_clock_gating_cmd $objects
}
2021-04-26 03:46:46 +02:00
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
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_case_analysis" {pins}
2018-09-28 17:54:21 +02:00
proc unset_case_analysis { pins } {
set pins1 [get_port_pins_error "pins" $pins]
foreach pin $pins1 {
unset_case_analysis_cmd $pin
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_clock_groups" \
2018-09-28 17:54:21 +02:00
{[-logically_exclusive] [-physically_exclusive]\
[-asynchronous] [-name names] [-all]}
proc unset_clock_groups { args } {
unset_clk_groups_cmd "unset_clock_groups" $args
}
2021-04-26 03:46:46 +02:00
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
}
}
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects}
2018-09-28 17:54:21 +02:00
proc unset_clock_latency { args } {
unset_clk_latency_cmd "unset_clock_latency" $args
}
2021-04-26 03:46:46 +02:00
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
}
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_clock_transition" {clocks}
2018-09-28 17:54:21 +02:00
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
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_clock_uncertainty" \
2018-09-28 17:54:21 +02:00
{[-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
}
2021-04-26 03:46:46 +02:00
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
}
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_data_check" \
2018-09-28 17:54:21 +02:00
{[-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
}
2021-04-26 03:46:46 +02:00
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
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_disable_inferred_clock_gating" { objects }
2018-09-28 17:54:21 +02:00
proc unset_disable_inferred_clock_gating { objects } {
unset_disable_inferred_clock_gating_cmd $objects
}
2021-04-26 03:46:46 +02:00
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
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_disable_timing" \
2018-09-28 17:54:21 +02:00
{[-from from_port] [-to to_port] objects}
proc unset_disable_timing { args } {
unset_disable_cmd "unset_disable_timing" $args
}
2021-04-26 03:46:46 +02:00
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
}
}
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_generated_clock" {[-all] clocks}
2018-09-28 17:54:21 +02:00
proc unset_generated_clock { args } {
unset_gclk_cmd "unset_generated_clock" $args
}
2021-04-26 03:46:46 +02:00
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
}
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_input_delay" \
2018-09-28 17:54:21 +02:00
{[-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
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_output_delay" \
2018-09-28 17:54:21 +02:00
{[-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
}
2021-04-26 03:46:46 +02:00
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
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_path_exceptions" \
2018-09-28 17:54:21 +02:00
{[-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
}
2021-04-26 03:46:46 +02:00
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
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_propagated_clock" {objects}
2018-09-28 17:54:21 +02:00
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
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "unset_timing_derate" {}
2018-09-28 17:54:21 +02:00
proc unset_timing_derate { args } {
check_argc_eq0 "unset_timing_derate" $args
unset_timing_derate_cmd
2018-09-28 17:54:21 +02:00
}
################################################################
#
# Network editing commands
#
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "connect_pin" {net pin}
2019-05-03 17:07:00 +02:00
# deprecated 2.0.16 05/02/2019
2021-04-26 04:16:34 +02:00
define_cmd_args "connect_pins" {net pins}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "delete_instance" {inst}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "delete_net" {net}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "disconnect_pin" {net -all|pin}
2019-05-03 17:07:00 +02:00
# deprecated 2.0.16 05/02/2019
2021-04-26 04:16:34 +02:00
define_cmd_args "disconnect_pins" {net -all|pins}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "make_instance" {inst_path lib_cell}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "make_net" {}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "replace_cell" {instance lib_cell}
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\
2019-05-03 17:07:00 +02:00
buffer_out_net_name}
2018-09-28 17:54:21 +02:00
################################################################
#
# Delay calculation commands
#
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "set_assigned_delay" \
{-cell|-net [-rise] [-fall] [-corner corner] [-min] [-max]\
2018-09-28 17:54:21 +02:00
[-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
}
2021-04-26 03:46:46 +02:00
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]
2019-01-17 00:37:31 +01:00
2021-04-26 03:46:46 +02:00
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] {
2021-04-26 03:46:46 +02:00
if { $to_rf == "rise_fall" \
|| $to_rf eq [$arc to_edge_name] } {
2021-04-26 03:46:46 +02:00
set_arc_delay $edge $arc $corner $min_max $delay
}
}
}
}
$edge_iter finish
}
################################################################
2018-09-28 17:54:21 +02:00
2021-04-26 04:16:34 +02:00
define_cmd_args "set_assigned_check" \
2018-09-28 17:54:21 +02:00
{-setup|-hold|-recovery|-removal [-rise] [-fall]\
[-corner corner] [-min] [-max]\
2018-09-28 17:54:21 +02:00
[-from from_pins] [-to to_pins] [-clock rise|fall]\
[-cond sdf_cond] check_value}
2018-09-28 17:54:21 +02:00
proc set_assigned_check { args } {
set_assigned_check_cmd "set_assigned_check" $args
}
2021-04-26 03:46:46 +02:00
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}
2021-04-26 03:46:46 +02:00
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] {
2021-04-26 03:46:46 +02:00
if { ($from_rf eq "rise_fall" \
|| $from_rf eq [$arc from_edge_name]) \
2021-04-26 03:46:46 +02:00
&& ($to_rf eq "rise_fall" \
|| $to_rf eq [$arc to_edge_name]) \
2021-04-26 03:46:46 +02:00
&& [$arc role] eq $role \
&& ($cond eq "" || [$arc sdf_cond] eq $cond) } {
set_arc_delay $edge $arc $corner $min_max $check_value
}
}
}
}
$edge_iter finish
}
2018-09-28 17:54:21 +02:00
################################################################a
2021-04-26 04:16:34 +02:00
define_cmd_args "set_assigned_transition" \
{[-rise] [-fall] [-corner corner] [-min] [-max] slew pins}
2018-09-28 17:54:21 +02:00
# 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]} {
2020-12-16 06:31:08 +01:00
sta_error 428 "set_assigned_transition transition is not a float."
2018-09-28 17:54:21 +02:00
}
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
}
}
}
2021-04-26 03:46:46 +02:00
################################################################a
# compatibility
2021-04-26 04:16:34 +02:00
define_cmd_args "read_parasitics" \
2021-04-26 03:46:46 +02:00
{[-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}
2018-09-28 17:54:21 +02:00
################################################################
#
# Utility commands
#
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "delete_from_list" {list objs}
2018-09-28 17:54:21 +02:00
2019-02-16 21:07:59 +01:00
proc delete_from_list { list objects } {
2018-09-28 17:54:21 +02:00
delete_objects_from_list_cmd $list $objects
}
2021-04-26 03:46:46 +02:00
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
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "get_fanin" \
2018-09-28 17:54:21 +02:00
{-to sink_list [-flat] [-only_cells] [-startpoints_only]\
[-levels level_count] [-pin_levels pin_count]\
[-trace_arcs timing|enabled|all]}
proc get_fanin { args } {
parse_key_args "get_fanin" args \
keys {-to -levels -pin_levels -trace_arcs} \
flags {-flat -only_cells -startpoints_only}
if { [llength $args] != 0 } {
cmd_usage_error "get_fanin"
}
if { ![info exists keys(-to)] } {
cmd_usage_error "get_fanin"
}
parse_port_pin_net_arg $keys(-to) pins nets
foreach net $nets {
lappend pins [net_driver_pins $net]
}
set flat [info exists flags(-flat)]
set only_insts [info exists flags(-only_cells)]
set startpoints_only [info exists flags(-startpoints_only)]
set inst_levels 0
if { [info exists keys(-levels)] } {
set inst_levels $keys(-levels)
}
set pin_levels 0
if { [info exists keys(-pin_levels)] } {
set pin_levels $keys(-pin_levels)
}
set thru_disabled 0
set thru_constants 0
if { [info exists keys(-trace_arcs)] } {
set trace_arcs $keys(-trace_arcs)
if { $trace_arcs == "timing" } {
set thru_disabled 0
set thru_constants 0
} elseif { $trace_arcs == "enabled" } {
set thru_disabled 0
set thru_constants 0
} elseif { $trace_arcs == "all" } {
set thru_disabled 1
set thru_constants 1
} else {
2021-02-12 16:53:12 +01:00
cmd_usage_error "get_fanin"
2018-09-28 17:54:21 +02:00
}
}
if { $only_insts } {
return [find_fanin_insts $pins $flat $startpoints_only \
$inst_levels $pin_levels $thru_disabled $thru_constants]
} else {
return [find_fanin_pins $pins $flat $startpoints_only \
$inst_levels $pin_levels $thru_disabled $thru_constants]
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "get_fanout" \
2018-09-28 17:54:21 +02:00
{-from source_list [-flat] [-only_cells] [-endpoints_only]\
[-levels level_count] [-pin_levels pin_count]\
[-trace_arcs timing|enabled|all]}
proc get_fanout { args } {
parse_key_args "get_fanout" args \
keys {-from -levels -pin_levels -trace_arcs} \
flags {-flat -only_cells -endpoints_only}
if { [llength $args] != 0 } {
cmd_usage_error "get_fanout"
}
parse_port_pin_net_arg $keys(-from) pins nets
foreach net $nets {
lappend pins [net_load_pins $net]
}
set flat [info exists flags(-flat)]
set only_insts [info exists flags(-only_cells)]
set endpoints_only [info exists flags(-endpoints_only)]
set inst_levels 0
if { [info exists keys(-levels)] } {
set inst_levels $keys(-levels)
}
set pin_levels 0
if { [info exists keys(-pin_levels)] } {
set pin_levels $keys(-pin_levels)
}
set thru_disabled 0
set thru_constants 0
if { [info exists keys(-trace_arcs)] } {
set trace_arcs $keys(-trace_arcs)
if { $trace_arcs == "timing" } {
set thru_disabled 0
set thru_constants 0
} elseif { $trace_arcs == "enabled" } {
set thru_disabled 0
set thru_constants 0
} elseif { $trace_arcs == "all" } {
set thru_disabled 1
set thru_constants 1
} else {
cmd_usage_error "get_fanout"
}
}
if { $only_insts } {
return [find_fanout_insts $pins $flat $endpoints_only \
$inst_levels $pin_levels $thru_disabled $thru_constants]
} else {
return [find_fanout_pins $pins $flat $endpoints_only \
$inst_levels $pin_levels $thru_disabled $thru_constants]
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "get_name" {objects}
define_cmd_args "get_full_name" {objects}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "get_property" \
2018-09-28 17:54:21 +02:00
{[-object_type cell|pin|net|port|clock|timing_arc] object property}
proc get_property { args } {
return [get_property_cmd "get_property" "-object_type" $args]
}
################################################################
2021-04-26 03:46:46 +02:00
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"} {
2021-04-26 03:46:46 +02:00
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"} {
2021-04-26 03:46:46 +02:00
set object [get_lib_cells -quiet $object_name]
} elseif { $object_type == "liberty_port" \
|| $object_type == "lib_pin" } {
2021-04-26 03:46:46 +02:00
set object [get_lib_pins -quiet $object_name]
} elseif { $object_type == "library" \
|| $object_type == "lib"} {
2021-04-26 03:46:46 +02:00
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"
2021-04-26 03:46:46 +02:00
} elseif { $object_type == "LibertyPort" } {
return "lib_pin"
2021-04-26 03:46:46 +02:00
} elseif { $object_type == "Cell" } {
return "cell"
} elseif { $object_type == "Instance" } {
return "instance"
2021-04-26 03:46:46 +02:00
} 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]]
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "get_timing_edges" \
2018-09-28 17:54:21 +02:00
{[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]}
proc get_timing_edges { args } {
return [get_timing_edges_cmd "get_timing_edges" $args]
}
2021-04-26 03:46:46 +02:00
proc get_timing_edges_cmd { cmd cmd_args } {
parse_key_args $cmd cmd_args \
keys {-from -to -of_objects -filter} flags {}
check_argc_eq0 $cmd $cmd_args
set arcs {}
if { [info exists keys(-of_objects)] } {
if { [info exists keys(-from)] \
|| [info exists keys(-from)] } {
sta_error 440 "-from/-to arguments not supported with -of_objects."
}
set arcs [get_timing_arcs_objects $keys(-of_objects)]
} elseif { [info exists keys(-from)] \
&& [info exists keys(-to)] } {
set arcs [get_timing_arcs_from_to \
[get_port_pin_error "from" $keys(-from)] \
[get_port_pin_error "to" $keys(-to)]]
} elseif { [info exists keys(-from)] } {
set arcs [get_timing_arcs_from $keys(-from)]
} elseif { [info exists keys(-to)] } {
set arcs [get_timing_arcs_to $keys(-to)]
} else {
cmd_usage_error $cmd
}
if [info exists keys(-filter)] {
set arcs [filter_timing_arcs1 $keys(-filter) $arcs]
}
return $arcs
}
proc get_timing_arcs_objects { object_arg } {
parse_libcell_inst_arg $object_arg libcells insts
if { $insts != {} } {
set edges {}
foreach inst $insts {
lappend edges [instance_edges $inst]
}
return $edges
} elseif { $libcells != {} } {
set arc_sets {}
foreach libcell $libcells {
lappend arc_sets [$libcell timing_arc_sets]
2021-04-26 03:46:46 +02:00
}
return $arc_sets
}
}
proc instance_edges { inst } {
set edges {}
set pin_iter [$inst pin_iterator]
while {[$pin_iter has_next]} {
set pin [$pin_iter next]
foreach vertex [$pin vertices] {
set edge_iter [$vertex out_edge_iterator]
while {[$edge_iter has_next]} {
set edge [$edge_iter next]
if { [$edge role] != "wire" } {
lappend edges $edge
}
}
$edge_iter finish
}
}
$pin_iter finish
return $edges
}
proc get_timing_arcs_from_to { from_pin_arg to_pin_arg } {
set edges {}
set from_pin [get_port_pin_error "from" $from_pin_arg]
set to_pin [get_port_pin_error "to" $to_pin_arg]
foreach from_vertex [$from_pin vertices] {
foreach to_vertex [$to_pin vertices] {
set edge_iter [$from_vertex out_edge_iterator]
while {[$edge_iter has_next]} {
set edge [$edge_iter next]
if { [$edge to] == $to_vertex } {
lappend edges $edge
}
}
$edge_iter finish
}
}
return $edges
}
proc get_timing_arcs_from { from_pin_arg } {
set from_pin [get_port_pin_error "from" $from_pin_arg]
set edges {}
foreach from_vertex [$from_pin vertices] {
set edge_iter [$from_vertex out_edge_iterator]
while {[$edge_iter has_next]} {
set edge [$edge_iter next]
lappend edges $edge
}
$edge_iter finish
}
return $edges
}
proc get_timing_arcs_to { to_pin_arg } {
set to_pin [get_port_pin_error "to" $to_pin_arg]
set edges {}
foreach to_vertex [$to_pin vertices] {
set edge_iter [$to_vertex in_edge_iterator]
while {[$edge_iter has_next]} {
set edge [$edge_iter next]
lappend edges $edge
}
$edge_iter finish
}
return $edges
}
proc filter_timing_arcs1 { filter objects } {
variable filter_regexp1
variable filter_or_regexp
variable filter_and_regexp
set filtered_objects {}
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
if { [regexp $filter_or_regexp $filter ignore expr1 \
ignore ignore ignore expr2] } {
regexp $filter_regexp1 $expr1 ignore attr_name op arg
set filtered_objects1 [filter_timing_arcs $attr_name $op $arg $objects]
regexp $filter_regexp1 $expr2 ignore attr_name op arg
set filtered_objects2 [filter_timing_arcs $attr_name $op $arg $objects]
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
ignore ignore ignore expr2] } {
regexp $filter_regexp1 $expr1 ignore attr_name op arg
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
regexp $filter_regexp1 $expr2 ignore attr_name op arg
set filtered_objects [filter_timing_arcs $attr_name $op \
$arg $filtered_objects]
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
} else {
sta_error 441 "unsupported -filter expression."
}
return $filtered_objects
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "report_clock_properties" {[clocks]}
2018-09-28 17:54:21 +02:00
proc_redirect report_clock_properties {
check_argc_eq0or1 "report_clock_properties" $args
update_generated_clks
2020-12-26 01:55:46 +01:00
report_line "Clock Period Waveform"
report_line "----------------------------------------------------"
2018-09-28 17:54:21 +02:00
if { [llength $args] == 0 } {
Network::id for maps/sets commit be70d30ae05665021254b0d7e69fb8d2f0a82890 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 17:04:49 2023 -0700 cmp Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4d4ef96948afe3d6a00c4521aeb5bc74274f5737 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 16:08:50 2023 -0700 rvo, const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit bb584e4264af2bea867b17d07e8d38c0e9eb0025 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 15:05:00 2023 -0700 const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a08fe558bca6b769b2728882258bd85aed990a27 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 14:57:33 2023 -0700 LibertyPortPair no ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4d3bd60c109d1ce9d0589d746f4968fa7bebd90d Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 14:13:07 2023 -0700 cleanup Signed-off-by: James Cherry <cherry@parallaxsw.com> commit dc25ff77771cfbe26f9318bad2b3c45879614783 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 14:06:13 2023 -0700 const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 06e81586ce11a0cc06948ed78fef99353077d69e Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 14:01:10 2023 -0700 sortByName Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9d8592aff5b246f83e47e1b94490e3cef8d8e119 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 11:57:17 2023 -0700 sort pred Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 462a8e14df8b561ddfc842addc62c4b8435b6347 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 11:09:57 2023 -0700 const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69f71505b684e88b22d395510429497e87bf1015 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 10:45:14 2023 -0700 flush ConstPortSeq Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6429d578b78eac3fe7e99fcd67a120789932b2eb Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 09:19:15 2023 -0700 rm ConstNetSet Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f247930b16e40560b957a36af68947249ed1ef04 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 17 08:50:50 2023 -0700 sortPathNames Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4ca2b0e0af7252c7bcbc65cf141d0ce40634d329 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 10:14:05 2023 -0700 const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 3d18640d2ebc4aae3098c7e7242a554fcb64fd42 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 09:41:27 2023 -0700 set_input/ouput_delay -reference_pin Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d4a0854dd2102f46f96a94fb9eb8749f1593a85f Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 09:13:46 2023 -0700 PinPairSet no malloc Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a6f1583fc6a856c5ecc0dcb15a1d8b1f61e30718 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 08:53:33 2023 -0700 no malloc for EdgePins Signed-off-by: James Cherry <cherry@parallaxsw.com> commit c8e4b92e8b619109d6aa3c141c720646067ccb4b Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 06:31:08 2023 +0000 leak commit abab99e0fc3e466d914f6c1705aa08cdc204df51 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 16 06:07:36 2023 +0000 leaks commit d1913b554bb6e98b89673d80d2295f552eb4ffca Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 19:48:39 2023 -0700 LibertyCell::checkCornerCell Signed-off-by: James Cherry <cherry@parallaxsw.com> commit bcc172237d48deed647374f9592bac70bd2d5425 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 18:19:47 2023 -0700 rvo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 8ef9800b87f5e5548055a13afc21397f28a6bcf7 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 18:07:46 2023 -0700 sdc net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d7235abed04ced4e2d84e91bf9968e621268567d Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 16:00:27 2023 -0700 range iter Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a22f91a3c54c644574339d1126821d9bc8045bd6 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 15:52:50 2023 -0700 range iter Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 762615ce3de91d950eeaaa4680549a45b13e0e0a Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 15:42:19 2023 -0700 range iter Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 7e0c531613d343d23f064c24873bf5a498f6f4ce Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 12:26:49 2023 -0700 rm removeLoadCaps, removeNetLoadCaps Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f2e88c6082e2d4605e9849348008bf4065401fc8 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 12:21:03 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b5939666188c0b94dfe957e22bbd8a92f4786125 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 11:36:16 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a435081bafe10260743319f53a59cbe2ed0388b7 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 08:43:37 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit acfb247559db7b726d47f203613488df0f7add53 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 08:38:07 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 7541b71da92ea15085615988a1e6ea1d4d53d8d6 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 08:00:55 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d033210132656ea68fa834228575b9def1d02d90 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 07:52:03 2023 -0700 sdc rm map ptrs Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ca6e9ecb7821b83ab024c4fee6df8f7fc8fc2ce2 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 07:38:12 2023 -0700 instance_pvt_maps_ Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 631e4209b596386f5818045d521784db5239f58d Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 07:26:42 2023 -0700 rm GroupPathIterator Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 059c32afa87617fff530c9afa1ef8005a136739d Author: James Cherry <cherry@parallaxsw.com> Date: Sat Jan 14 20:07:44 2023 -0700 rm ClockIterator Signed-off-by: James Cherry <cherry@parallaxsw.com> commit c65fe873a6a6696220bbb44c4ecac87d5ca978ac Author: James Cherry <cherry@parallaxsw.com> Date: Sat Jan 14 19:45:58 2023 -0700 rvo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ce15c9a0cc78915acddc2f03749573d989ae96d6 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 15 01:04:03 2023 +0000 leaks commit f97955a0c7e70b65ceb3f697ff47c0524a9b3cd4 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Jan 14 01:17:58 2023 +0000 leaks commit 7cdd65684adeb14e02827f5d93e7fab3b19af5dd Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 16:07:47 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ee97c7e50394a3927458e7ef09c5dbeb27719d15 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 11:52:48 2023 -0700 swig rm Tmp collections Signed-off-by: James Cherry <cherry@parallaxsw.com> commit c49935da8704e41459280971b7645fccd97e3d13 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 11:18:36 2023 -0700 swig rm Tmp types Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4320b00ce700914843006f592126cd8cc1c4657a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 10:55:10 2023 -0700 swig rm TmpPinSet, TmpPinSeq Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ff6004910980c9b09b41f63a553a4481404cc539 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 10:45:06 2023 -0700 swig rm Tmp collections Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9a5bf5c1a3e5a6d2996b3ab327fa2f3015f2ff20 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 10:15:29 2023 -0700 swig rm one TmpPinSet Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f441116b56e23849485b2393b30e7086c33165a8 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 09:16:56 2023 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 050b08df8618340b568d9cd41fd3d5f052e2c680 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 09:10:53 2023 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit be8c17f3a715ab53140748dc1d94698209965cf9 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Jan 13 08:59:06 2023 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit e43b82f8fb52eaeda90e3c7e76cf350ae6735ebd Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 18:57:49 2023 -0700 range iter Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 8db56209de7805ac2574fd2f76170bf68afd156d Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 18:08:54 2023 -0700 GroupPathSet net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cb7917f9827c2ea3afebd735cd4508405a0d77d4 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 12:00:15 2023 -0700 DataCheckLess net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d9da3c62d7a76699c6ad62cebb1f5c39f89722fa Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 11:42:27 2023 -0700 rm hashPtr uses Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5bbea162bb1e023aba813598c7992c740ddf9d0b Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 11:30:12 2023 -0700 EdgePins has use net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit df38405e2ebaabdd7bbf99f3b19d78b25bd95720 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 09:51:38 2023 -0700 ExceptionPath hash use net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9a6dcfa54c54c9f50b14248a2449c70c20a0d977 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 08:56:49 2023 -0700 ClockInsertion, ClockLatency net id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit dbb6dc0b8c93812458df31e93f08e0dbd74e8105 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 08:34:03 2023 -0700 ExceptionStateSet obj id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 70b8721c48ec0816289ee09b664c332ee095875f Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 08:14:37 2023 -0700 ClockGroups cmp Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4c6c4ca191a99cd8541e106fec3202ee14968f39 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Jan 12 07:38:17 2023 -0700 ClockGroup typedef to ClockSet Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 66f425315e16deee5f00b05c0a505766e7afbf01 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 20:32:38 2023 -0700 set cmps Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a94866c7828af5b6714e3e4fffc13bdaf5155c0e Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 19:08:09 2023 -0700 net use id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6348320908f42ebb5262117182e13d0024f65537 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 11:52:13 2023 -0700 exception id cmp Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 0edfca41b6d6408ac17f8dfe10e697c55146c1ef Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 10:47:02 2023 -0700 range iter Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 44ad77985da9f0b9e7f4780e3f233c8d94fa7db7 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 08:27:58 2023 -0700 non-ptr set cmp Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 36de7d88c3fa683465604a9e16b2fc1f6bc5fdd0 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Jan 11 08:00:54 2023 -0700 range iteration Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4a31a2c8d9bdae58b09af8c05a64702ea3ac6c15 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 10 16:43:54 2023 -0700 tcl types Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 056a7447b494a4c8ecc9764650d78a5bed3d87e8 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 10 16:10:36 2023 -0700 tcl types Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 97239554c7625ba50ee729260f08eda7dec02365 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Jan 10 13:10:42 2023 -0700 use RVO Signed-off-by: James Cherry <cherry@parallaxsw.com> commit c3247d8937d483102e3e1f2b69d7ac1d331ba9d4 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 22:41:20 2023 -0700 swig template seq's Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5431c06feb256adb46858819fcf5d513cfa6b5ec Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 20:50:24 2023 -0700 swig set in template Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 592ad641bf01d3beb862314a0d8986f66e258642 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 17:27:25 2023 -0700 network return containers Signed-off-by: James Cherry <cherry@parallaxsw.com> commit c95f8b77e0d6bd5ffa5ba8102413c70883c756e1 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 12:15:37 2023 -0700 PinSeq const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 702e7f9ba2f901066a38f32e67b35602b6c7bbdf Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 12:02:29 2023 -0700 InstanceSeq const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 44fc25ba4a15e4ae570d74af27c9435872a126e0 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 12:01:45 2023 -0700 NetSeq const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 03b2725c81f5d52c33c875b55056c11d482144f1 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 11:33:18 2023 -0700 rm PortPair Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 3fb82a7344dc053171c9883a113764ba691ab827 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Jan 9 11:20:53 2023 -0700 PinSet id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 3dd31f027e15d40d62a11d0a88ef2a115f01fb73 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 8 15:03:33 2023 -0700 InstanceSet id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a91dea5cc0af3bede36b3faed13adb05239ff907 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 8 11:40:15 2023 -0700 NetSet id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b91e4b6410134eccae7969ddcfb0b27933b2e746 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 8 10:44:47 2023 -0700 CellSet, PortSet id Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6f891f77fae5a6b19c1454a1a4b4e3dfae0b5c50 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 8 10:29:25 2023 -0700 network object sets Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eb8c627a57ecc6e7c5846a01d62b090ff91c08bf Author: James Cherry <cherry@parallaxsw.com> Date: Sun Jan 8 10:09:00 2023 -0700 PinSet1 Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 8e864ecbdf87000fbb3c3097c39f06173c941e35 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Jan 7 17:13:03 2023 -0700 concrete network object id Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-01-19 19:23:45 +01:00
foreach clk [all_clocks] {
2018-09-28 17:54:21 +02:00
report_clock1 $clk
}
} else {
foreach clk [get_clocks_warn "clock_name" [lindex $args 0]] {
report_clock1 $clk
}
}
}
2021-04-26 03:46:46 +02:00
proc report_clock1 { clk } {
global sta_report_default_digits
if { [$clk waveform_valid] } {
set digits $sta_report_default_digits
set waveform [$clk waveform]
if { $waveform == {} } {
set wave " "
} else {
set wave ""
foreach edge $waveform {
set wave "$wave[format "%10s" [format_time $edge $digits]]"
}
}
if {[$clk is_generated]} {
set generated " (generated)"
} else {
set generated ""
}
report_line "[format %-20s [get_name $clk]][format %10s [format_time [$clk period] $digits]] $wave$generated"
}
}
2018-09-28 17:54:21 +02:00
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "report_object_full_names" {objects}
2019-01-17 00:37:31 +01:00
2020-12-26 01:55:46 +01:00
proc report_object_full_names { objects } {
foreach obj [sort_by_full_name $objects] {
report_line [get_full_name $obj]
2019-01-17 00:37:31 +01:00
}
}
2021-04-26 04:16:34 +02:00
define_cmd_args "report_object_names" {objects}
2018-09-28 17:54:21 +02:00
2020-12-26 01:55:46 +01:00
proc report_object_names { objects } {
foreach obj [sort_by_name $objects] {
report_line [get_name $obj]
2018-09-28 17:54:21 +02:00
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "report_units" {}
2020-06-24 02:11:48 +02:00
proc report_units { args } {
check_argc_eq0 "report_units" $args
foreach unit {"time" "capacitance" "resistance" "voltage" "current" "power" "distance"} {
2020-12-26 01:55:46 +01:00
report_line " $unit 1[unit_scale_abreviation $unit][unit_suffix $unit]"
2020-06-24 02:11:48 +02:00
}
}
################################################################
2021-04-26 04:16:34 +02:00
define_cmd_args "with_output_to_variable" { var { cmds }}
2018-09-28 17:54:21 +02:00
# 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
}
2021-04-26 04:16:34 +02:00
define_cmd_args "set_pocv_sigma_factor" { factor }
2019-03-13 01:25:53 +01:00
2021-04-26 03:46:46 +02:00
################################################################
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
}
}
}
2018-09-28 17:54:21 +02:00
# sta namespace end.
}