############################################################
## Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
## http://www.iis.ee.ethz.ch/~sha3
############################################################
# v0.7 - - Sat Sep 17 15:21:25 CEST 2011
# - added a way to enable multi core. It will check a file called
# run_multi_core in the synopsys directory
# v0.6 - - Tue Sep 13 09:51:20 CEST 2011
# - wireload.tcl will be executed only when one clock is in the clocklist
# v0.5 - - Mon Sep 12 17:21:44 CEST 2011
# - more reports on the end.
# v0.4 - - Mon Sep 12 17:21:44 CEST 2011
# - added the (optional) wireload, increased the max_fanout number to 1200
# v0.3 - - Tue Sep 6 09:23:21 CEST 2011
# - write per clock _scan.ddc
# check if for elaborate or compile script exists and source if it does
# v0.2 - - Mon Sep 5 14:01:00 CEST 2011
# - changed the library seting, new the cornner have to be set (set corner XX)
# v0.1 - - Thu Sep 1 09:32:11 CEST 2011
# - pretty the first version
# -- clean start
remove_design -design
sh rm -rf WORK/*
# ---------------------------------------------------------------------------------------
set NumberThreads [exec cat /proc/cpuinfo | grep -c processor]
# there is not much improvement with this at the moment
if {[file exists ./run_multi_core]} {
puts "*INFO: run_multi_core detected!"
set_host_options -max_cores $NumberThreads
}
# ---------------------------------------------------------------------------------------
# Default Setings
# ---------------------------------------------------------------------------------------
set CLOCKLIST { 1 }
set IN 0
set OUT 0
set PAD_IN 0
set PAD_OUT 0
set CLK_TREE 0
set LIB u065gioll25mvir_25_wc
set DRIV_CELL IUMB
set DRIV_PIN DI
set LOAD_CELL IUMB
set LOAD_PIN DO
# high fanout threshold, we have 1088 bit wide things
set high_fanout_net_threshold 1200
# -- sets for every case a list
set libraryset("wc") [list uk65lscllmvbbr_108c125_wc.db uk65lscllmvbbl_108c125_wc.db uk65lscllmvbbh_108c125_wc.db u065gioll25mvir_25_wc.db]
set libraryset("tc") [list uk65lscllmvbbr_120c25_tc.db uk65lscllmvbbl_120c25_tc.db uk65lscllmvbbh_120c25_tc.db u065gioll25mvir_25_tc.db]
set libraryset("bc") [list uk65lscllmvbbr_132c0_bc.db uk65lscllmvbbl_132c0_bc.db uk65lscllmvbbh_132c0_bc.db u065gioll25mvir_25_bc.db]
# -- driver library the same way
set driverlibrary("wc") uk65lscllmvbbr_108c125_wc
set driverlibrary("tc") uk65lscllmvbbr_120c25_tc
set driverlibrary("bc") uk65lscllmvbbr_132c0_bc
# -- Overwrites the target_library set by .synopsys_dc.setup withe the Worst Case lib
set corner wc
if {[file exists ./scripts/design_settings.tcl]} {
source ./scripts/design_settings.tcl
} else {
puts "*WARNING: Default setings are taken, no design_settings.tcl file exists!"
}
set target_library $libraryset("$corner")
set link_library [concat [list "*"] $libraryset("$corner")]
# ---------------------------------------------------------------------------------------
set path [pwd]
regexp {(ethz_)([^/]+)/[^/]+$} $path matched namep1 namep2
regexp {(gmu_)([^/]+)/[^/]+$} $path matched namep1 namep2
if { $namep1 == "ethz_" } {
set top_block ${namep1}${namep2}
} else {
set top_block ${namep1}${namep2}_top
}
set savename ${namep1}${namep2}
# ---------------------------------------------------------------------------------------
# Analyze Design
# ---------------------------------------------------------------------------------------
set list_file [open "../sourcecode/source.list" r]
set vhdl_file_list ""
while {[gets $list_file line] != -1} {
# if {[regexp -all -inline {\W} $line] }
if { "" != $line } {
# puts "$line"
lappend vhdl_file_list ../sourcecode/$line
}
}
close $list_file
analyze -library WORK -format vhdl $vhdl_file_list
#read_file -library WORK -format vhdl $vhdl_file_list-all_feature
# ---------------------------------------------------------------------------------------
# Elaborate design
# ---------------------------------------------------------------------------------------
# -- elaborate the design
if {[file exists ./scripts/elaborate.tcl]} {
puts "*INFO: elaborate.tcl exists and will be sourced instead"
source ./scripts/elaborate.tcl
} else {
elaborate ${top_block}
}
# if there is a script to add the wireload, do it here
# disabled this feature.. always wireload -kgf
#if {[file exists ./scripts/wireload.tcl] && [llength $CLOCKLIST] == 1 } {
if {[file exists ./scripts/wireload.tcl] } {
puts "*INFO: wireload.tcl exists and will be executed"
source ./scripts/wireload.tcl
}
write -f ddc -h -o DDC/${savename}_elaborate.ddc
# ---------------------------------------------------------------------------------------
# loops all clock periods
# ---------------------------------------------------------------------------------------
foreach CLOCK $CLOCKLIST {
# set CLOCK [lindex $CLOCKLIST 0]
puts "*INFO: clock period is: $CLOCK"
set reportname ${namep1}${namep2}_${CLOCK}_${corner}
remove_design -design
read_ddc DDC/${savename}_elaborate.ddc
# ---------------------------------------------------------------------------------------
# set up timing constraints
# ---------------------------------------------------------------------------------------
# -- pessimistic wire load model
#set_wire_load_mode top
current_design ${top_block}
# create the main Clock
create_clock ClkxCI -period $CLOCK
# clocked inputs have the input delay minus the clock tree
set_input_delay [expr $IN + $CLK_TREE] -clock ClkxCI [all_inputs]
# These are the outputs that go to next stage
set_output_delay [expr $OUT + $PAD_OUT - $CLK_TREE] -clock ClkxCI [all_outputs]
# All inputs are the pads
set_driving_cell -no_design_rule -library ${LIB} -lib_cell ${DRIV_CELL} -pin ${DRIV_PIN} \
[remove_from_collection [all_inputs] ClkxCI]
# all Outputs have the equivalent load of an output pad
set_load [load_of ${LIB}/${LOAD_CELL}/${LOAD_PIN}] [all_outputs]
# set the false path here
set_false_path -from [get_ports {ScanEnxTI}]
# ---------------------------------------------------------------------------------------
# set up DFT constraints
# ---------------------------------------------------------------------------------------
reset_dft_configuration
set_dft_insertion_configuration -synthesis_optimization none
set test_disable_enhanced_dft_drc_report FALSE
#set_scan_configuration -replace false
set_scan_configuration -style multiplexed_flip_flop
# set_scan_configuration -clock_mixing mix_clocks
# -- define scan relatet signals
# set_dft_signal -view spec -type ScanClock -port ClkxCI
set_dft_signal -view existing_dft -type ScanClock -port ClkxCI -timing {45 55}
# set_dft_signal -view spec -type Reset -port RstxRBI
set_dft_signal -view existing_dft -type Reset -port RstxRBI -active_state 0
set_dft_signal -view spec -type ScanEnable -port ScanEnxTI -active_state 1
# -- create 1 chains
set_scan_configuration -chain_count 1
# -- define scan chains
set_dft_signal -view spec -type ScanDataIn -port ScanInxTI
set_dft_signal -view spec -type ScanDataOut -port ScanOutxTO
create_test_protocol
# create_test_protocol -infer_async -infer_clock
#write_test_protocol -o ./${savename}.spf
# display report
# dft_drc
# report_dft_signal
# preview_dft
# write out report
dft_drc -verbose > reports/${reportname}_scanchain.rep
report_dft_signal >> reports/${reportname}_scanchain.rep
# preview_dft -show cells >> reports/${reportname}_scanchain.rep
# ---------------------------------------------------------------------------------------
# compilation
# ---------------------------------------------------------------------------------------
#uniquify
# -- check design for errors
# display check
# check_design -multiple_designs -summary
# report_design
# write out check
check_design -multiple_designs > reports/${reportname}_check_before_compile.rep
report_design > reports/${reportname}_report_before_compile.rep
if {[file exists ./scripts/compile.tcl]} {
puts "*INFO: compile.tcl file exists and will be sourced instead run compile_ultra"
source ./scripts/compile.tcl
} else {
compile_ultra -scan
#compile_ultra -scan -no_autoungroup
}
#write -f ddc -h -o DDC/${savename}_compile.ddc
# ---------------------------------------------------------------------------------------
# Insert DFT
# ---------------------------------------------------------------------------------------
# -- insert scan chains
insert_dft
# display report
# dft_drc -coverage_estimate
# write out report
report_scan_path >> reports/${reportname}_scanchain.rep
dft_drc -coverage_estimate >> reports/${reportname}_scanchain.rep
# need if "set_dft_insertion_configuration -synthesis_optimization none" is set,
# so "insert_dft" is not doing a additional compile. Should be faster.
compile_ultra -incremental
# ---------------------------------------------------------------------------------------
# ScanEnxTI and RstxRBI
# ---------------------------------------------------------------------------------------
report_net_fanout -hi > reports/${reportname}_fanout.rep
foreach SIG {RstxRBI ScanEnxTI} {
clean_buffer_tree -from ${SIG}
balance_buffer -from ${SIG} -prefer BUFM16R -library $driverlibrary("$corner")
report_buffer_tree -from ${SIG} >> reports/${reportname}_fanout.rep
}
write -f ddc -h -o DDC/${reportname}_scan.ddc
# ---------------------------------------------------------------------------------------
# generate reports
# ---------------------------------------------------------------------------------------
# display some useful report
# report_timing
# report_area -hierarchy
# write out report
report_area -hierarchy -nosplit > reports/${reportname}_area.rpt
echo "IN2REG TIMING" > ./reports/${reportname}_timing.rep
report_timing -from [all_inputs] -to [all_registers -data_pins] >> ./reports/${reportname}_timing.rep
echo "REG2REG TIMING" >> ./reports/${reportname}_timing.rep
report_timing -from [all_registers -clock_pins] -to [all_registers -data_pins] >> ./reports/${reportname}_timing.rep
echo "REG2OUT TIMING" >> ./reports/${reportname}_timing.rep
report_timing -from [all_registers -clock_pins] -to [all_outputs] >> ./reports/${reportname}_timing.rep
echo "IN2OUT TIMING" >> ./reports/${reportname}_timing.rep
report_timing -from [all_inputs] -to [all_outputs] >> ./reports/${reportname}_timing.rep
}
# ---------------------------------------------------------------------------------------
# Write out data (verilog netlist and DDC file)
# ---------------------------------------------------------------------------------------
# save the version including scan
#write -f ddc -h -o DDC/${savename}_final.ddc
define_name_rules verilog -add_dummy_nets
change_names -h -rules verilog
write -h -f verilog -o netlists/${savename}.v
# ---------------------------------------------------------------------------------------
# generate report
# ---------------------------------------------------------------------------------------
report_area -hierarchy -nosplit > ./reports/${savename}_area.rpt
report_net_fanout -threshold $high_fanout_net_threshold -nosplit > ./reports/${savename}_high_fanout_net.rep
report_buffer_tree -from ${SIG} >> ./reports/${savename}_high_fanout_net.rep
echo "Clock period is: $CLOCK" > ./reports/${savename}_timing.rep
echo "IN2REG TIMING" >> ./reports/${savename}_timing.rep
report_timing -from [all_inputs] -to [all_registers -data_pins] >> ./reports/${savename}_timing.rep
echo "REG2REG TIMING" >> ./reports/${savename}_timing.rep
report_timing -from [all_registers -clock_pins] -to [all_registers -data_pins] >> ./reports/${savename}_timing.rep
echo "REG2OUT TIMING" >> ./reports/${savename}_timing.rep
report_timing -from [all_registers -clock_pins] -to [all_outputs] >> ./reports/${savename}_timing.rep
echo "IN2OUT TIMING" >> ./reports/${savename}_timing.rep
report_timing -from [all_inputs] -to [all_outputs] >> ./reports/${savename}_timing.rep
ungroup -all -flatten
report_reference -nosplit > ./reports/${savename}_reference.rep
# ---------------------------------------------------------------------------------------
# leave shel
# ---------------------------------------------------------------------------------------
if { [string length [exec ps -fe | grep "dc_shell-xg-t -f"]] != 0 } {
quit
}