# Design Compiler Enhancement
functions
#====================================================================
# Graphical version of "man" command: opens
# man results in separate TK window
# Note: download view.tk application and set the
correct path to
# this application inside the body of vman procedure
# Example : vman report_timing
#====================================================================
proc vman {args} {
eval man
$args > tmpfile
exec view.tk tmpfile &
after 500
file delete tmpfile
}
#=======================================================================
# Converts collection to TCL list. By default,
# only 200 first collection members are converted.
# In order to make bigger lists, use second parameter
# which defines the number of members
#
# Examples:
# set inputs_lits [c2l [all_inputs]] - list size is
maximum 200.
# set cells_list [c2l [get_cells U18*] 400] -
list size is maximum 400.
#========================================================================
proc c2l {collection {max_num 200}} {
set my_list
{}
set counter 0
foreach_in_collection coll_element $collection {
set element
[get_object_name $coll_element]
lappend
my_list $element
incr
counter
if
{$counter > $max_num} {break}
}
return
$my_list
}
#=======================================================================
# Makes TCL list to be unique. Unfortunately,
# TCL lacks this useful command
#
# Example: set
uniq_list [unique $non_uniq_list]
#=======================================================================
proc unique {bad_list} {
set good_list
{}
foreach
bad_item $bad_list {
if
{[lsearch -exact $good_list $bad_item] < 0} {
lappend
good_list $bad_item
}
}
return
$good_list
}
#============================================================
# Creates INPUT pins ONLY collection from the current
design.
# All command line options are the same as for
dc_shell's
# "get_pins" command (see "man
get_pins" for details)
#
# Example: set inpins [c2l [get_inpins
byte_controller/*]]
# (creating TCL list of input pins of
"byte_controller" cell)
#============================================================
proc get_inpins {args} {
get_pins
$args -filter "@pin_direction == in"
}
#============================================================
# Creates OUTPUT pins ONLY collection from the current
design.
# All command line options are the same as for
dc_shell's
#
"get_pins" command (see "man get_pins" for details)
#
# Example: set outpins [c2l [get_outpins
byte_controller/*]]
# (creating TCL list of input pins of
"byte_controller" cell)
#=============================================================
proc get_outpins {args} {
get_pins
$args -filter "@pin_direction == out"
}
#================================================================
# Creates INPUT ports ONLY collection from the current
design.
# All command line options are the same as for
dc_shell's
# "get_ports" command (see "man
get_ports" for details)
# Can be useful with "set_input_delay" and
other timing constraints
# commands
#
# Example: set_input_delay 5 -clock PCI_CLK [get_inports
PCI*]]
#================================================================
proc get_inports {args} {
get_ports
$args -filter "@port_direction == in"
}
#================================================================
# Creates OUTPUT ports ONLY collection from the
current design.
# All command line options are the same as for
dc_shell's
# "get_ports" command (see "man
get_ports" for details)
# Can be useful with "set_output_delay" and
other timing constraints
# commands
#
# Example: set_output_delay 5 -clock PCI_CLK
[get_outports PCI*]]
#=================================================================
proc get_outports {args} {
get_ports
$args -filter "@port_direction == out"
}
#=================================================================
# Returns direction of port with given name
# Direction has one of the following values:
# in / out / bidi
#
# Example: get_port_dir MY_PORT_NAME
#=================================================================
proc get_port_dir {name} {
get_attribute
[get_ports $name] port_direction
}
#=================================================================
# Returns direction of pin with given name
# Direction has one of the following values:
# in / out / bidi
#
# Example: get_pin_dir MY_PIN_NAME
#=================================================================
proc get_pin_dir {name} {
get_attribute
[get_pins $name] pin_direction
}
#==================================================================
# Creates collection of PORTS, connected to net with
given name.
# Synopsis:
get_cports <net_name> <optional_port_direction>
# Port_direction switch must have one of the following
values:
# -in / -out
/ -inout
# If no port directions is specified, returns all
connected ports.
#
# Example: set port_name [get_cports NET12 -out]
#==================================================================
proc get_cports {net {direction -all}} {
if
{$direction == "-all"} {
get_ports
[all_connected $net]
} elseif
{$direction == "-in"} {
get_ports
[all_connected $net] -filter "@port_direction == in"
} elseif
{$direction == "-out"} {
get_ports
[all_connected $net] -filter "@port_direction == out"
} elseif
{$direction == "-inout"} {
get_ports [all_connected
$net] -filter "@port_direction == inout"
} else {
puts
"Error: use -in/-out/-inout values only to specify port direction!"
return 0
}
}
#==================================================================
# Creates collection of PINS, connected to net with
given name.
# Synopsis:
get_cpins <net_name> <optional_pin_direction>
# Pin_direction switch must have one of the following
values:
# -in / -out
/ -inout
# If no pin directions is specified, returns all
connected pins.
#
# Example: set conn_pins [get_cpins NET12 -in]
#==================================================================
proc get_cpins {net {direction -all}} {
if
{$direction == "-all"} {
get_pins
[all_connected $net]
} elseif
{$direction == "-in"} {
get_pins
[all_connected $net] -filter "@pin_direction == in"
} elseif
{$direction == "-out"} {
get_pins
[all_connected $net] -filter "@pin_direction == out"
} elseif
{$direction == "-inout"} {
get_pins
[all_connected $net] -filter "@pin_direction == inout"
} else {
puts
"Error: use -in/-out/-inout values only to specify pins direction!"
return 0
}
}
#===================================================================
# Returns reference name of cell with givel name
#
# Example: set rname [refname_of U232]
#===================================================================
proc refname_of {cell} {
get_attribute
$cell ref_name
}
#===================================================================
# Returns fanout of net with given name
#
# Example: if {[fanout_of $my_net] > 7} {lappend
hifan_nets $my_net}
#===================================================================
proc fanout_of {net_name} {
return [expr
[sizeof_collection [all_connected $net_name]] -1]
}
#===================================================================
# Creates collection of cells with given reference
name
#
# Example:
# if {[get_refcells TLATX2] != ""} {
# echo
"Found latches TLATX2 with instance names:"
# echo [c2l [get_refcells
TLATX2]]
# }
#
#====================================================================
proc get_refcells {ref_name} {
get_cells *
-filter "@ref_name == $ref_name"
}
#====================================================================
# Disconnects pin with given name
# The only command dc_compiler has for disconnection
is
# "disconnect_net". However, it is not
enough to be handy.
# Command returns collection which contains
disconnected net
#
# Examples:
# disconnect_pin U123/A
# connect_net [disconnect_pin $pin] [get_pins
$new_pin]
#====================================================================
proc disconnect_pin {pin_name} {
set conn_net
[all_connected [get_pins $pin_name]]
disconnect_net $conn_net [get_pins $pin_name]
return
$conn_net
}
#====================================================================
# Disconnects port with given name
# The only command dc_compiler has for disconnection
is
# "disconnect_net". However, it is not
enough to be handy.
# Command returns collection which contains
disconnected net
#
# Examples:
# disconnect_port JTAG_TDI
# connect_net [disconnect_port $WRONG_PORT] [get_ports
$RIGHT_PORT]
#====================================================================
proc disconnect_port {port_name} {
set conn_net
[all_connected [get_ports $port_name]]
disconnect_net $conn_net [get_ports $port_name]
return
$conn_net
}
#====================================================================
# Renames already exisiting net
# Synopsis:
rename_net <net_name> <new_net_name>
#
# Example: rename_net N762 REGBUS_EN
#====================================================================
proc rename_net {name new_name} {
set all_conn
[all_connected $name]
remove_net
$name
create_net
$new_name
connect_net
$new_name $all_conn
}
#====================================================================
# Renames already exisiting cell
# Synopsis:
rename_cell <cell_name> <new_cell_name>
#
# Example: rename_cell U125 MY_AND
#====================================================================
proc rename_cell {name new_name} {
create_cell
$new_name [refname_of $name]
set pins [c2l
[get_pins $name/*]]
foreach pin
$pins {
regsub
$name $pin $new_name new_pin
connect_net
[disconnect_pin $pin] [get_pins $new_pin]
}
remove_cell
[get_cells $name]
}
#====================================================================
# Renames already exisiting port
# Synopsis:
rename_port <port_name> <new_port_name>
#
# Example: rename_port wb_clk_i master_clk
#====================================================================
proc rename_port {name new_name} {
create_port
$new_name -direction [get_port_dir $name]
connect_net [disconnect_port
$name] [get_ports $new_name]
remove_port
[get_ports $name]
}
#======================================================================
# Rebinds given cell, replacing it with another cell
with given
# reference name and original name
# Can be useful for STA fine tuning etc
# Synopsis:
rebind_cell <cell_name> <new_reference_name>
#
# Example: rebind_cell I235 slow/NAND2X8 - assuming that original
# reference cell of I235 was NAND2X4, increases power
level of this cell
#======================================================================
proc rebind_cell {name new_refname} {
create_cell
$name.tmp $new_refname
set pins [c2l
[get_pins $name/*]]
foreach pin
$pins {
regsub
$name $pin $name.tmp new_pin
connect_net
[disconnect_pin $pin] [get_pins $new_pin]
}
remove_cell
[get_cells $name]
rename_cell
$name.tmp $name
}
#======================================================================
# Returns list of disconnected pins in current design.
# Useful for design connectivity checks
# No command line arguments.
#
# Example:
# foreach pin [get_disc_pins] {echo "Disconnected
pin: $pin"}
#======================================================================
proc get_disc_pins {} {
set ret_list
""
foreach_in_collection pin [get_pins */*] {
if {[c2l
[all_connected $pin]] == ""} {
lappend
ret_list [c2l $pin]
}
}
return
$ret_list
}
#======================================================================
# Returns list of disconnected ports in current
design.
# Useful for design connectivity checks
# No command line arguments.
#
# Example:
# foreach port [get_disc_ports] {echo
"Disconnected port: $port"}
#======================================================================
proc get_disc_ports {} {
set ret_list
""
foreach_in_collection port [get_ports *] {
if {[c2l
[all_connected $port]] == ""} {
lappend
ret_list [c2l $port]
}
}
return
$ret_list
}
#======================================================================
# Returns list of disconnected nets in current design.
# Here, the meaning of disconnected net is net without
driver (or with
# fanin equal to zero)
# Useful for design connectivity checks
# No command line arguments.
#
# Example:
# foreach net [get_disc_nets] {echo "Disconnected
net: $net"}
#======================================================================
proc get_disc_nets {} {
set ret_list
""
foreach_in_collection
net [get_nets *] {
if
{[get_pins [all_connected $net] -filter "@pin_direction == out"] ==
""} {
if
{[get_ports [all_connected $net] -filter "@port_direction == in"] ==
""} {
lappend
ret_list [c2l $net]
}
}
}
return
$ret_list
}
#=======================================================================
# Returns TCL list of net names with specified fanout
number
# Useful for connectivity & STA checks
#
#
# Example:
# set fanout 5
# set nets_exist true
# while {$nets_exist} {
# set nets
[get_nets_by_fanout $fanout]
# if {$nets
!= ""} {
# echo
"\n Found nets $nets with fanout $fanout"
# incr
fanout
# } else {
# set
nets_exist false
# }
# }
#=======================================================================
proc get_nets_by_fanout {fanout} {
set ret_list
""
foreach_in_collection net [get_nets *] {
if
{[sizeof_collection [all_connected [get_nets $net]]] == [expr $fanout + 1]} {
lappend
ret_list [c2l $net]
}
}
return
$ret_list
}