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

Generated on Tue Nov 22 15:16:34 CET 2011
Home