blob: 3444fec46ff7d7636ecc568249cc6785e34bc807 [file] [log] [blame] [edit]
#!/usr/bin/tclsh8.5
## 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}
{replacemacro floorplan/replacemacro}
{mplace floorplan/mplace}
{pdn floorplan/pdn}
{tapcell floorplan/tapcell}
{replaceio placement/replace}
{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 tapcell 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
try_catch $::env(SCRIPTS_DIR)/padLefMacro.py -p $::env(CELL_PAD) -i $::env(MERGED_LEF) -o $::env(TMP_DIR)/merged.lef
# 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_UNPADDED) $::env(MERGED_LEF)
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) \
-liberty ./demo_sram/sram_16_256_8_scn4m_subm_TT_5p0V_25C.lib \
-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).def \
-verbose \
|& tee $::env(TERMINAL_OUTPUT) $::env(verilog2def_log_file_tag).log
}
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) \
-r $::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
# MACRO PLACEMENT
try_catch replace < ./scripts/replace_mstd.tcl |& tee $::env(TERMINAL_OUTPUT) $::env(replacemacro_log_file_tag).log
# try_catch mplace < $::env(SCRIPTS_DIR)/mplace.tcl |& tee $::env(TERMINAL_OUTPUT) $::env(mplace_log_file_tag).log
try_catch cp $::env(replacemacro_tmp_file_tag).def $::env(mplace_tmp_file_tag).def
###
# pdn generation
TIMER::timer_start
#try_catch apply_pdn ./pdks/$::env(PDK)/common_pdn.tcl \
|& tee $::env(TERMINAL_OUTPUT) $::env(pdn_log_file_tag).log
#try_catch mv $::env(TMP_DIR)/$::env(CURRENT_STAGE)/$::env(DESIGN_NAME)_post_T8.def $::env(pdn_tmp_file_tag).def
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" >> $::env(pdn_log_file_tag)_runtime.txt
# try_catch mv $::env(DESIGN_NAME)_pdn.def $::env(pdn_tmp_file_tag)_empty.def
try_catch cp $::env(replacemacro_tmp_file_tag).def $::env(pdn_tmp_file_tag).def
# tapcell
try_catch cp $::env(pdn_tmp_file_tag).def $::env(tapcell_result_file_tag).def
TIMER::timer_start
#try_catch tapcell -lef $::env(MERGED_LEF) \
-def $::env(tapcell_result_file_tag).def \
-welltap $::env(FP_WELLTAP_CELL) \
-endcap $::env(FP_ENDCAP_CELL) \
-outdef $::env(tapcell_result_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
# 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
# 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_UNPADDED) \
-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 FRlefdef -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]} { }
}