# The number of scan chains will be determined automatically
taking into account
# the total number of registers in the core.
# In order to configure a core-level scan insertion,
run the following function:
#---------------------------------------------------------------------------
proc config_scan_chain {max_length} {
set
chains_num [expr [sizeof_collection [all_registers]] / $max_length + 1]
set_scan_configuration -chain_count $chains_num -dedicated_scan_ports
true
preview_scan -show all
}
# This
script inserts scannable flops insert of non-scannable ones and
# connects
them the same way the Design Compiler does: scan data pin of each
# flop is
connected to the same flop's output
# Usage:
# Load this
file into synopsys dc_shell-t and then run:
#
replace_regs <standard cells library name>
#
Example: replace_regs
nlc13_slow108V125C
#
Methodological Note
# First, run
your compilation without -scan switch (this will avoid Test Compiler
# License
usage). Then, run this script on your current design. In case of a
#
hierarchical design, run this script:
# foreach
design [c2l [all_designs]] {
# current_design $design
# replace_regs <standard cells library
name>
# }
# After
replacement, run incremental compile with a low effort to fix possible
# timing
problems which could appear as a result of the changes.
# Replaces non-scannable
register with the scannable one assuming that addition pins
# names
scannable register has are SD (scan data input) and SE (scan enable).
# These
name could be changed in a case of problems.
#==================================================================
proc replace_reg
{reg_name new_ref} {
set pins [c2l [get_pins $reg_name/*]]
foreach pin $pins {
set net($pin) [c2l [all_connected $pin]]
disconnect_net $net($pin) [get_pins $pin]
}
remove_cell $reg_name
create_cell $reg_name $new_ref
foreach pin $pins {
connect_net $net($pin) [get_pins $pin]
}
set out_pins [get_gate_outputs $reg_name]
foreach pin $out_pins {
if {[c2l [all_connected $pin]] !=
""} {
connect_net [get_nets $net($pin)]
[get_pins $reg_name/SD]
}
}
}
# Returns
output pins of given gate
#==================================================================
proc get_gate_outputs
{name} {
set ret_list ""
foreach pin [c2l [get_pins $name/* -filter
"@pin_direction == out"]] {
lappend ret_list $pin
}
return $ret_list
}
# Converts
dc collection to tcl list
#===================================================================
proc c2l
{collection} {
set my_list {}
foreach_in_collection coll_element
$collection {
set element [get_object_name
$coll_element]
lappend my_list $element
}
return $my_list
}
# Returns
reference name of a given cell
#==================================================================
proc get_ref_name
{inst_name} {
return [get_attribute $inst_name ref_name]
}
# Replaces
all non-scannable register for the scannable ones in the current design.
# Scannable
register was chosen by replacing "ff" pattern of original register's
ref name for "sff"
# If cell of
this type exist in current technology library, it replaces original register.
# (This is
library-dependent , please change the pattern inside "regsub .." line
in a case of problems)
#==================================================================
proc replace_regs
{ lib_name} {
foreach_in_collection reg_ptr
[all_registers] {
set reg [get_object_name $reg_ptr]
regsub ff [get_ref_name $reg] sff scan_ref
if {[get_lib_cells $lib_name/$scan_ref] !=
""} {
puts "\nReplacing register $reg ..."
replace_reg $reg $lib_name/$scan_ref
}
}
}
# Inserts
internal scan chain into the current design
#==================================================================
proc create_scan
{} {
create_port -direction "in"
{test_si test_se}
create_net {test_si test_se}
connect_net test_si [get_ports test_si]
connect_net test_se [get_ports test_se]
set in_net test_si
foreach_in_collection reg_ptr
[all_registers] {
set reg [get_object_name $reg_ptr]
connect_net [find net test_se] [get_pins
$reg/SE]
set out_pins [get_outputs $reg]
foreach pin $out_pins {
if {[c2l [all_connected $pin]] !=
""} {
set out_net [c2l [all_connected $pin]]
}
}
disconnect_net $out_net [get_pins $reg/SD]
connect_net $in_net [get_pins $reg/SD]
set in_net $out_net
}
if {[c2l [get_ports [all_connected
$in_net]]] == ""} {
create_port -direction "out"
{test_so}
connect_net $in_net [get_ports test_so]
set_attribute [get_ports test_so] scan_out
true -type boolean
} else {
set so_port [c2l [get_ports [all_connected
$in_net]]]
puts "$so_port is scan out
port!"
set_attribute [get_ports $so_port]
scan_out true -type boolean
}
}