############################################################ ## 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 }