| #!/usr/bin/tclsh8.5 |
| |
| # Copyright (c) Efabless Corporation. All rights reserved. |
| # See LICENSE file in the project root for full license information. |
| |
| ## TIMER START |
| set timer_start [clock seconds] |
| |
| # |----------------------------------------------------| |
| # |-------- 0. DESIGN & PDK INIT --------------| |
| # |----------------------------------------------------| |
| |
| # scripts & utilities |
| source ./scripts/utils/utils.tcl |
| set ::env(SCRIPTS_DIR) "[pwd]/scripts/" |
| set ::env(PATH) "$::env(PATH):$::env(SCRIPTS_DIR)/pdn/src/scripts" |
| set ::env(TCLLIBPATH) "$::env(SCRIPTS_DIR)/pdn/src/scripts" |
| foreach tcl_file [glob $::env(SCRIPTS_DIR)/tcl_commands/*.tcl] { |
| source $tcl_file |
| } |
| |
| |
| set options {{-design required} \ |
| {-tag optional} \ |
| {-config optional} \ |
| } |
| |
| set flags {-init_design_config -disable_output} |
| |
| set argv_copy $argv |
| parse_key_args "flow.tcl" argv arg_values $options flags_map $flags |
| |
| |
| if { [info exists arg_values(-config)] } { |
| set config_tag $arg_values(-config) |
| } else { |
| set config_tag "config" |
| } |
| |
| |
| if { [info exist flags_map(-init_design_config)] } { |
| set config_tag "config" |
| if { [info exist arg_values(-tag) ] } { |
| set config_tag $arg_values(-tag) |
| } |
| init_design $arg_values(-design) $config_tag |
| exit |
| } |
| |
| if { ! [info exist flags_map(-disable_output)] } { |
| set ::env(TERMINAL_OUTPUT) "/dev/tty" |
| } else { |
| set ::env(TERMINAL_OUTPUT) "/dev/null" |
| } |
| |
| set datetime [clock format [clock seconds] -format %d-%m_%H-%M] |
| if { [lsearch -exact $argv_copy -tag ] >= 0} { |
| set tag "$arg_values(-tag)" |
| } else { |
| set tag $datetime |
| } |
| |
| #set flow_config "./configuration/flow_default.tcl" |
| set ::env(CONFIGS) [glob ./configuration/*.tcl] |
| set ::env(DESIGN_CONFIG) ./designs/$arg_values(-design)/$config_tag.tcl |
| |
| foreach config $::env(CONFIGS) { |
| source $config |
| } |
| |
| source $::env(DESIGN_CONFIG) |
| source "./pdks/$::env(PDK)/common_config.tcl" |
| source $::env(DESIGN_CONFIG) |
| source "./pdks/$::env(PDK)/$::env(PDK_VARIANT)/config.tcl" |
| source $::env(DESIGN_CONFIG) |
| |
| # |
| ############################ |
| # Prep directories and files |
| ############################ |
| # |
| set ::env(RUN_TAG) "$tag" |
| set ::env(RUN_DIR) "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/" |
| set ::env(RESULTS_DIR) "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/results/" |
| set ::env(TMP_DIR) "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/tmp/" |
| set ::env(LOG_DIR) "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/logs/" |
| set ::env(REPORTS_DIR) "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/reports/" |
| set GLB_CFG_FILE "[pwd]/designs/$::env(DESIGN_NAME)/runs/$tag/config.tcl" |
| |
| if { [file exists $::env(RUN_DIR)] } { |
| exec rm -r $::env(RUN_DIR) |
| } |
| |
| if { [file exists $GLB_CFG_FILE] } { |
| exec rm $GLB_CFG_FILE |
| } |
| set tmp_output { |
| {yosys "synthesis/yosys"} |
| {opensta synthesis/opensta} |
| {verilog2def floorplan/verilog2def} |
| {ioPlacer floorplan/ioPlacer} |
| {tapcell floorplan/tapcell} |
| {pdn floorplan/pdn} |
| {replaceio placement/replace} |
| {psn placement/psn} |
| {opendp placement/opendp} |
| {addspacers routing/addspacers} |
| {fastroute routing/fastroute} |
| {tritonRoute routing/tritonRoute} |
| {magic magic/magic} |
| {cts cts/cts} |
| } |
| |
| set final_output \ |
| [list \ |
| [list yosys synthesis/$::env(DESIGN_NAME).synthesis] \ |
| [list pdn floorplan/$::env(DESIGN_NAME).floorplan] \ |
| [list opendp placement/$::env(DESIGN_NAME).placement] \ |
| [list tritonRoute routing/$::env(DESIGN_NAME).routing] \ |
| [list cts cts/$::env(DESIGN_NAME).cts] \ |
| [list magic magic/$::env(DESIGN_NAME).magic] \ |
| ] |
| |
| array set results_file_name [make_array $final_output $::env(RESULTS_DIR)] |
| array set reports_file_name [make_array $tmp_output $::env(REPORTS_DIR)] |
| array set logs_file_name [make_array $tmp_output $::env(LOG_DIR)] |
| array set tmp_file_name [make_array $tmp_output $::env(TMP_DIR)] |
| |
| foreach {key value} [array get results_file_name] { |
| set ::env(${key}_result_file_tag) $value |
| } |
| foreach {key value} [array get reports_file_name] { |
| set ::env(${key}_report_file_tag) $value |
| } |
| foreach {key value} [array get logs_file_name] { |
| set ::env(${key}_log_file_tag) $value |
| } |
| foreach {key value} [array get tmp_file_name] { |
| set ::env(${key}_tmp_file_tag) $value |
| } |
| |
| |
| try_catch mkdir -p $::env(RESULTS_DIR) $::env(TMP_DIR) $::env(LOG_DIR) $::env(REPORTS_DIR) |
| |
| set stages {synthesis floorplan placement cts routing magic} |
| foreach stage $stages { |
| try_catch mkdir -p $::env(RESULTS_DIR)/$stage \ |
| $::env(TMP_DIR)/$stage \ |
| $::env(LOG_DIR)/$stage \ |
| $::env(REPORTS_DIR)/$stage |
| } |
| |
| # pad lef |
| set ::env(MERGED_LEF_UNPADDED) $::env(MERGED_LEF) |
| try_catch $::env(SCRIPTS_DIR)/padLefMacro.py -p $::env(CELL_PAD) -i $::env(MERGED_LEF) -o $::env(TMP_DIR)/merged.lef -e $::env(CELL_PAD_EXECLUDE) |
| |
| # trim libs |
| set trimmed_lib $::env(TMP_DIR)/trimmed.lib |
| exec $::env(SCRIPTS_DIR)/libtrim.pl $::env(PDK_VARIANT) $::env(LIB_SYNTH) > $trimmed_lib |
| set ::env(LIB_SYNTH) $trimmed_lib |
| |
| # change to system verilog |
| #if {$::env(SYSTEM_VERILOG)} { |
| # foreach verilogfile $::env(VERILOG_FILES) { |
| # system_verilog_2_verilog \ |
| # -include $::env(VERILOG_FILES) \ |
| # -input $verilogfile \ |
| # -output [file rootname $verilogfile].v \ |
| # -define SYNTHESIS |
| # } |
| #} |
| |
| set util $::env(FP_CORE_UTIL) |
| set density $::env(PL_TARGET_DENSITY) |
| |
| # Fill config file |
| #General |
| exec echo "# General config" >> $GLB_CFG_FILE |
| set_log ::env(PDK) $::env(PDK) $GLB_CFG_FILE 1 |
| set_log ::env(PDK_VARIANT) $::env(PDK_VARIANT) $GLB_CFG_FILE 1 |
| set_log ::env(CELL_PAD) $::env(CELL_PAD) $GLB_CFG_FILE 1 |
| set_log ::env(MERGED_LEF) $::env(MERGED_LEF) $GLB_CFG_FILE 1 |
| set_log ::env(TRACKS_INFO_FILE) $::env(TRACKS_INFO_FILE) $GLB_CFG_FILE 1 |
| # Design |
| exec echo "# Design config" >> $GLB_CFG_FILE |
| set_log ::env(CLOCK_PERIOD) $::env(CLOCK_PERIOD) $GLB_CFG_FILE 1 |
| # Synthesis |
| exec echo "# Synthesis config" >> $GLB_CFG_FILE |
| set_log ::env(LIB_SYNTH) $::env(LIB_SYNTH) $GLB_CFG_FILE 1 |
| set_log ::env(SYNTH_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL) $GLB_CFG_FILE 1 |
| set_log ::env(SYNTH_CAP_LOAD) $::env(SYNTH_CAP_LOAD) $GLB_CFG_FILE 1; # femtofarad |
| set_log ::env(SYNTH_MAX_FANOUT) $::env(SYNTH_MAX_FANOUT) $GLB_CFG_FILE 1 |
| if { [info exist ::env(SYNTH_MAX_TRAN)] } { |
| set_log ::env(SYNTH_MAX_TRAN) $::env(SYNTH_MAX_TRAN) $GLB_CFG_FILE 1 |
| } else { |
| set_log ::env(SYNTH_MAX_TRAN) "\[\expr {0.1*$::env(CLOCK_PERIOD)}\]" $GLB_CFG_FILE 1 |
| } |
| set_log ::env(LIB_MIN) $::env(LIB_MIN) $GLB_CFG_FILE 1 |
| set_log ::env(LIB_MAX) $::env(LIB_MAX) $GLB_CFG_FILE 1 |
| set_log ::env(LIB_TYPICAL) $::env(LIB_TYPICAL) $GLB_CFG_FILE 1 |
| set_log SYNTH_SCRIPT "scripts/synth.tcl" $GLB_CFG_FILE 0 |
| set_log ::env(SYNTH_STRATEGY) $::env(SYNTH_STRATEGY) $GLB_CFG_FILE 1 |
| set_log ::env(SYNTH_OPT) 0 $GLB_CFG_FILE 0 |
| |
| # Floorplan |
| exec echo "# Floorplan config" >> $GLB_CFG_FILE |
| set_log ::env(FP_SIZING) "relative" $GLB_CFG_FILE 0; # absolute, relative |
| set_log ::env(FP_CORE_UTIL) $util $GLB_CFG_FILE 1 |
| set_log ::env(FP_ASPECT_RATIO) $::env(FP_ASPECT_RATIO) $GLB_CFG_FILE 1 |
| set_log ::env(FP_CORE_MARGIN) $::env(FP_CORE_MARGIN) $GLB_CFG_FILE 1 |
| set_log ::env(FP_IO_HMETAL) $::env(FP_IO_HMETAL) $GLB_CFG_FILE 1 |
| set_log ::env(FP_IO_VMETAL) $::env(FP_IO_VMETAL) $GLB_CFG_FILE 1 |
| set_log ::env(FP_IO_RANDOM) 2 $GLB_CFG_FILE 0; #0 (default, disabled) 1 fully random, 2 evenly distributed, 3 group on the middle of core edge |
| set_log ::env(FP_WELLTAP_CELL) $::env(FP_WELLTAP_CELL) $GLB_CFG_FILE 1 |
| set_log ::env(FP_ENDCAP_CELL) $::env(FP_ENDCAP_CELL) $GLB_CFG_FILE 1 |
| set_log ::env(FP_PDN_VOFFSET) $::env(FP_PDN_VOFFSET) $GLB_CFG_FILE 1 |
| set_log ::env(FP_PDN_VPITCH) $::env(FP_PDN_VPITCH) $GLB_CFG_FILE 1 |
| set_log ::env(FP_PDN_HOFFSET) $::env(FP_PDN_HOFFSET) $GLB_CFG_FILE 1 |
| set_log ::env(FP_PDN_HPITCH) $::env(FP_PDN_HPITCH) $GLB_CFG_FILE 1 |
| |
| # Placement |
| exec echo "# Placement config" >> $GLB_CFG_FILE |
| set_log ::env(PL_TARGET_DENSITY) $density $GLB_CFG_FILE 1 |
| set_log ::env(PL_INIT_COEFF) 0.00002 $GLB_CFG_FILE 0 |
| set_log ::env(PL_TIME_DRIVEN) $::env(PL_TIME_DRIVEN) $GLB_CFG_FILE 1 |
| set_log ::env(PL_LIB) $::env(PL_LIB) $GLB_CFG_FILE 1 |
| set_log ::env(PL_IO_ITER) 5 $GLB_CFG_FILE 0 |
| |
| # CTS |
| exec echo "# CTS config" >> $GLB_CFG_FILE |
| set_log ::env(CTS_TARGET_SKEW) $::env(CTS_TARGET_SKEW) $GLB_CFG_FILE 1 |
| set_log ::env(CTS_ROOT_BUFFER) $::env(CTS_ROOT_BUFFER) $GLB_CFG_FILE 1 |
| set_log ::env(CTS_TECH_DIR) $::env(CTS_TECH_DIR) $GLB_CFG_FILE 1 |
| set_log ::env(CTS_TOLERANCE) $::env(CTS_TOLERANCE) $GLB_CFG_FILE 1 |
| |
| # ROUTING |
| exec echo "# Routing config" >> $GLB_CFG_FILE |
| set_log ::env(GLB_RT_MAXLAYER) $::env(GLB_RT_MAXLAYER) $GLB_CFG_FILE 1 |
| set_log ::env(GLB_RT_ADJUSTMENT) $::env(GLB_RT_ADJUSTMENT) $GLB_CFG_FILE 1 |
| set_log ::env(GLB_RT_LI1_ADJUSTMENT) $::env(GLB_RT_LI1_ADJUSTMENT) $GLB_CFG_FILE 1 |
| set_log ::env(GLB_RT_MET1_ADJUSTMENT) $::env(GLB_RT_MET1_ADJUSTMENT) $GLB_CFG_FILE 1 |
| set_log ::env(GLB_RT_MINLAYER) $::env(GLB_RT_MINLAYER) $GLB_CFG_FILE 1 |
| set_log ::env(GLB_RT_MAXLAYER) $::env(GLB_RT_MAXLAYER) $GLB_CFG_FILE 1 |
| |
| # Flow control |
| exec echo "# Flow control config" >> $GLB_CFG_FILE |
| set_log ::env(RUN_MAGIC) $::env(RUN_MAGIC) $GLB_CFG_FILE 1 |
| set_log ::env(RUN_ROUTING_DETAILED) $::env(RUN_ROUTING_DETAILED) $GLB_CFG_FILE 1 |
| set_log ::env(CLOCK_TREE_SYNTH) $::env(CLOCK_TREE_SYNTH) $GLB_CFG_FILE 1 |
| set_log ::env(FILL_INSERTION) $::env(FILL_INSERTION) $GLB_CFG_FILE 1 |
| |
| set ::env(MERGED_LEF) $::env(TMP_DIR)/merged.lef |
| |
| # |----------------------------------------------------| |
| # |---------------- 1. SYNTHESIS ------------------| |
| # |----------------------------------------------------| |
| # catch |
| set ::env(CURRENT_STAGE) synthesis |
| TIMER::timer_start |
| try_catch yosys \ |
| -c $SYNTH_SCRIPT \ |
| -l $::env(yosys_log_file_tag).log \ |
| |& tee $::env(TERMINAL_OUTPUT) |
| |
| try_catch sta ./scripts/sta.tcl \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(opensta_log_file_tag).log |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(yosys_log_file_tag)_runtime.txt |
| |
| # |----------------------------------------------------| |
| # |---------------- 2. FLOORPLAN ------------------| |
| # |----------------------------------------------------| |
| set ::env(CURRENT_STAGE) floorplan |
| |
| # intial fp |
| TIMER::timer_start |
| if {$::env(FP_SIZING) == "absolute"} { |
| |
| try_catch verilog2def \ |
| -verilog $::env(RESULTS_DIR)/1_synthesis/1_synthesis.v \ |
| -lef $::env(MERGED_LEF) \ |
| -liberty $::env(LIB_SYNTH) \ |
| -top_module $::env(DESIGN_NAME) \ |
| -site $::env(PLACE_SITE) \ |
| -tracks $::env(TRACKS_INFO_FILE) \ |
| -units $::env(DEF_UNITS_PER_MACRON) \ |
| \ |
| -die_area $::env(DIE_AREA) \ |
| -core_area $::env(CORE_AREA) \ |
| \ |
| -def $::env(RESULTS_DIR)/$::env(CURRENT_STAGE)/3_1_floorplan.def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(LOG_DIR)/$::env(CURRENT_STAGE)/3_1_verilog2def.log |
| } else { |
| try_catch verilog2def \ |
| -verilog $::env(yosys_result_file_tag).v \ |
| -lef $::env(MERGED_LEF) \ |
| -liberty $::env(LIB_SYNTH) \ |
| -top_module $::env(DESIGN_NAME) \ |
| -site $::env(PLACE_SITE) \ |
| -tracks $::env(TRACKS_INFO_FILE) \ |
| -units $::env(DEF_UNITS_PER_MACRON) \ |
| \ |
| -utilization $::env(FP_CORE_UTIL) \ |
| -aspect_ratio $::env(FP_ASPECT_RATIO) \ |
| -core_space $::env(FP_CORE_MARGIN) \ |
| \ |
| -def $::env(verilog2def_tmp_file_tag)_broken.def \ |
| -verbose \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(verilog2def_log_file_tag).log |
| } |
| exec cat $::env(verilog2def_tmp_file_tag)_broken.def | sed -r "s/(ROW.*) by /\\1 BY /g" > $::env(verilog2def_tmp_file_tag).def |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(verilog2def_log_file_tag)_runtime.txt |
| # place io |
| TIMER::timer_start |
| try_catch ioPlacer \ |
| -l $::env(MERGED_LEF) \ |
| -d $::env(verilog2def_tmp_file_tag).def \ |
| -h $::env(FP_IO_HMETAL) \ |
| -v $::env(FP_IO_VMETAL) \ |
| --random $::env(FP_IO_RANDOM) \ |
| -w 1 \ |
| \ |
| -o $::env(ioPlacer_tmp_file_tag).def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(ioPlacer_log_file_tag).log |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(ioPlacer_log_file_tag)_runtime.txt |
| |
| try_catch cp $::env(ioPlacer_tmp_file_tag).def $::env(tapcell_tmp_file_tag).def |
| TIMER::timer_start |
| try_catch tapcell -lef $::env(MERGED_LEF) \ |
| -def $::env(tapcell_tmp_file_tag).def \ |
| -welltap $::env(FP_WELLTAP_CELL) \ |
| -endcap $::env(FP_ENDCAP_CELL) \ |
| -outdef $::env(tapcell_tmp_file_tag).def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(tapcell_log_file_tag).log |
| TIMER::timer_stop |
| |
| exec echo "[TIMER::get_runtime]" >> $::env(tapcell_log_file_tag)_runtime.txt |
| # pdn generation |
| TIMER::timer_start |
| puts "Initializing openDB" |
| catch {exec opendbtcl $::env(SCRIPTS_DIR)/pdn/init_db.tcl} |
| puts "Applying PDN" |
| try_catch opendbtcl $::env(SCRIPTS_DIR)/pdn/apply_pdn.tcl ./pdks/$::env(PDK)/common_pdn.tcl \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(pdn_log_file_tag).log |
| try_catch sed -i "s/+ ROWCOL.*;/;/g" $::env(pdn_result_file_tag).def |
| |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(pdn_log_file_tag)_runtime.txt |
| #try_catch cp $::env(replacemacro_tmp_file_tag).def $::env(pdn_tmp_file_tag).def |
| |
| # tapcell |
| |
| |
| # outputs: 3_floorplan.def, 3_floorplan.v, 3_floorplan.sdc |
| |
| # |----------------------------------------------------| |
| # |---------------- 3. PLACEMENT ------------------| |
| # |----------------------------------------------------| |
| |
| set ::env(CURRENT_STAGE) placement |
| |
| #try_catch replace < $::env(SCRIPTS_DIR)/replace_io.tcl |& tee $::env(TERMINAL_OUTPUT) $::env(replaceio_log_file_tag).log |
| TIMER::timer_start |
| #for {set i 0} {$i < $::env(PL_IO_ITER)} {incr i} { |
| try_catch replace < ./scripts/replace_gp.tcl |& tee $::env(TERMINAL_OUTPUT) $::env(replaceio_log_file_tag).log |
| |
| #try_catch mv $::env(replaceio_tmp_file_tag)_io.def $::env(replaceio_tmp_file_tag)_io_$i.def |
| |
| #try_catch ioPlacer \ |
| -l $::env(MERGED_LEF) \ |
| -d $::env(replaceio_tmp_file_tag)_place.def \ |
| -h $::env(FP_IO_HMETAL) \ |
| -v $::env(FP_IO_VMETAL) \ |
| -r $::env(FP_IO_RANDOM) \ |
| \ |
| -o $::env(replaceio_tmp_file_tag)_io.def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(ioPlacer_log_file_tag).log |
| |
| #try_catch cp $::env(replaceio_tmp_file_tag)_place.def $::env(replaceio_tmp_file_tag)_place_$i.def |
| #} |
| try_catch cp $::env(replaceio_tmp_file_tag)_place.def $::env(replaceio_tmp_file_tag).def |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(replaceio_log_file_tag)_runtime.txt |
| |
| #try_catch Psn --verbose --file $::env(SCRIPTS_DIR)/psn.tcl |& tee /dev/tty $::env(psn_log_file_tag).log |
| |
| # GIFing the result |
| #puts "Generating Placement GIF" |
| #try_catch convert -delay 20 {*}[lsort [glob $::env(RESULTS_DIR)/4_placement/etc/3_floorplanning/output/cell/*.jpg]] \ |
| -delay 100 $::env(RESULTS_DIR)/4_placement/etc/3_floorplanning/output/globalPlaceResult.jpg \ |
| \ |
| $::env(RESULTS_DIR)/4_placement.gif \ |
| |& tee $::env(TERMINAL_OUTPUT) |
| |
| #try_catch cp $::env(RESULTS_DIR)/4_placement/etc/3_floorplanning/output/3_floorplan_final.def $::env(RESULTS_DIR)/4_1_place_gp.def |
| |
| # outputs: 4_1_place_gp.def |
| |
| # detailed 4_placement |
| TIMER::timer_start |
| try_catch opendp \ |
| -lef $::env(MERGED_LEF) \ |
| -def $::env(replaceio_tmp_file_tag).def \ |
| \ |
| -output_def $::env(opendp_result_file_tag).def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(opendp_log_file_tag).log |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(opendp_log_file_tag)_runtime.txt |
| |
| |
| # outputs: 4_place.def, sdc, v ... |
| |
| # |----------------------------------------------------| |
| # |---------------- 4. CTS --------------------------| |
| # |----------------------------------------------------| |
| set ::env(CURRENT_STAGE) cts |
| if {![info exists ::env(OPENROAD)]} { |
| set ::env(OPENROAD) ~/.local/bin |
| } |
| |
| TIMER::timer_start |
| if {$::env(CLOCK_TREE_SYNTH)} { |
| set_core_dims \ |
| -log_path $::env(verilog2def_log_file_tag).log \ |
| |
| gen_cts_config \ |
| -verilog $::env(yosys_result_file_tag).v \ |
| -def $::env(opendp_result_file_tag).def \ |
| -root_buffer $::env(CTS_ROOT_BUFFER) \ |
| -target_skew $::env(CTS_TARGET_SKEW) \ |
| -output $::env(cts_tmp_file_tag).config \ |
| -toler $::env(CTS_TOLERANCE) |
| |
| gen_clock_tree \ |
| -config $::env(cts_tmp_file_tag).config |
| eval exec mv [glob $::env(RESULTS_DIR)/cts/*] $::env(TMP_DIR)/cts/ |
| exec mv $::env(TMP_DIR)/cts/$::env(DESIGN_NAME).cts.v $::env(RESULTS_DIR)/cts/$::env(DESIGN_NAME).cts.v |
| exec mv $::env(TMP_DIR)/cts/$::env(DESIGN_NAME).cts.def $::env(RESULTS_DIR)/cts/$::env(DESIGN_NAME).cts.def |
| } else { |
| exec echo "SKIPPED!" >> $::env(cts_log_file_tag).log |
| try_catch cp $::env(opendp_result_file_tag).def $::env(cts_result_file_tag).def |
| } |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(cts_log_file_tag)_runtime.txt |
| |
| # |----------------------------------------------------| |
| # |---------------- 5. ROUTING ----------------------| |
| # |----------------------------------------------------| |
| set ::env(CURRENT_STAGE) routing |
| |
| # fastroute global 6_routing |
| TIMER::timer_start |
| if {$::env(FILL_INSERTION)} { |
| try_catch addspacers \ |
| -o $::env(addspacers_tmp_file_tag).def \ |
| -l $::env(MERGED_LEF) \ |
| -f $::env(FILL_CELL) $::env(cts_result_file_tag).def \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(addspacers_log_file_tag).log |
| } else { |
| exec echo "SKIPPED!" >> $::env(addspacers_log_file_tag).log |
| try_catch cp $::env(cts_result_file_tag).def $::env(addspacers_tmp_file_tag).def |
| } |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(addspacers_log_file_tag)_runtime.txt |
| |
| TIMER::timer_start |
| if {$::env(GLB_RT_OLD_FR)} { |
| try_catch envsubst < $::env(SCRIPTS_DIR)/fastroute.rsyn > $::env(fastroute_tmp_file_tag).rsyn |
| try_catch FRlefdef_old \ |
| --no-gui \ |
| --script $::env(fastroute_tmp_file_tag).rsyn \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(fastroute_log_file_tag).log |
| } else { |
| try_catch envsubst < $::env(SCRIPTS_DIR)/fastroute.tcl > $::env(fastroute_tmp_file_tag).tcl |
| try_catch FastRoute -c 1 < $::env(fastroute_tmp_file_tag).tcl \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(fastroute_log_file_tag).log |
| } |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(fastroute_log_file_tag)_runtime.txt |
| |
| TIMER::timer_start |
| if {$::env(RUN_ROUTING_DETAILED)} { |
| try_catch envsubst < $::env(SCRIPTS_DIR)/tritonRoute.param > $::env(tritonRoute_tmp_file_tag).param |
| |
| try_catch TritonRoute \ |
| $::env(tritonRoute_tmp_file_tag).param \ |
| |& tee $::env(TERMINAL_OUTPUT) $::env(tritonRoute_log_file_tag).log |
| } else { |
| exec echo "SKIPPED!" >> $::env(tritonRoute_log_file_tag).log |
| } |
| TIMER::timer_stop |
| exec echo "[TIMER::get_runtime]" >> $::env(tritonRoute_log_file_tag)_runtime.txt |
| # exec dr-cu \ |
| # -lef $::env(MERGED_LEF) \ |
| # -def $::env(RESULTS_DIR)/5_cts/5_4_cts.def \ |
| # -guide $::env(RESULTS_DIR)/$::env(CURRENT_STAGE)/route.guide \ |
| # -threads [exec nproc] \ |
| # \ |
| # -output $::env(RESULTS_DIR)/$::env(CURRENT_STAGE)/6_2_route.def \ |
| # -tat 9999999 \ |
| # |& tee $::env(TERMINAL_OUTPUT) $::env(LOG_DIR)/$::env(CURRENT_STAGE)/6_2_dr-cu.log |
| |
| |
| |
| |
| ## TIMER END |
| set timer_end [clock seconds] |
| |
| set runtime_s [expr {($timer_end - $timer_start)}] |
| set runtime_h [expr {$runtime_s/3600}] |
| |
| set runtime_s [expr {$runtime_s-$runtime_h*3600}] |
| set runtime_m [expr {$runtime_s/60}] |
| |
| set runtime_s [expr {$runtime_s-$runtime_m*60}] |
| puts "Completed $::env(DESIGN_NAME)/$datetime in ${runtime_h}h${runtime_m}m${runtime_s}s" |
| set runtime_log [open $::env(REPORTS_DIR)/runtime.txt w] |
| puts $runtime_log "Completed $::env(DESIGN_NAME)/$datetime in ${runtime_h}h${runtime_m}m${runtime_s}s" |
| close $runtime_log |
| |
| # |----------------------------------------------------| |
| # |---------------- 6. TAPE-OUT ---------------------| |
| # |----------------------------------------------------| |
| |
| if {$::env(RUN_MAGIC)} { |
| puts "Streaming out GDS II..." |
| set ::env(CURRENT_STAGE) finishing |
| if {[catch {exec tclsh $::env(SCRIPTS_DIR)/run_magic.tcl} issue]} { } |
| } |