blob: 8fe17ce7dd93d15df75a6a39463d662e3d814c72 [file] [log] [blame]
# Copyright 2020-2022 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
proc run_klayout {args} {
TIMER::timer_start
set ::env(CURRENT_STAGE) signoff
if {[ info exists ::env(KLAYOUT_TECH)] } {
increment_index
puts_info "Streaming out GDS-II with Klayout..."
set gds_files_in ""
if { [info exist ::env(EXTRA_GDS_FILES)] } {
set gds_files_in $::env(EXTRA_GDS_FILES)
}
if { $::env(STD_CELL_LIBRARY_OPT) != $::env(STD_CELL_LIBRARY) } {
set cells_gds "$::env(GDS_FILES) $::env(GDS_FILES_OPT)"
} else {
set cells_gds $::env(GDS_FILES)
}
set klayout_out $::env(signoff_results)/$::env(DESIGN_NAME).klayout.gds
try_catch klayout -b\
-rm $::env(SCRIPTS_DIR)/klayout/def2gds.py\
-rd out_gds=$klayout_out\
-rd tech_file=$::env(KLAYOUT_TECH)\
-rd design_name=$::env(DESIGN_NAME)\
-rd in_def=$::env(CURRENT_DEF)\
-rd "in_gds=$cells_gds $gds_files_in"\
-rd "config_file="\
-rd "seal_gds="\
-rd lef_file=$::env(MERGED_LEF)\
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(signoff_logs)/gdsii-klayout.log]
if {[info exists ::env(KLAYOUT_PROPERTIES)]} {
file copy -force $::env(KLAYOUT_PROPERTIES) $::env(signoff_results)/$::env(DESIGN_NAME).lyp
} else {
puts_warn "::env(KLAYOUT_PROPERTIES) is not defined. So, it won't be copied to the run directory."
}
if { $::env(PRIMARY_SIGNOFF_TOOL) == "klayout" } {
set ::env(CURRENT_GDS) $::env(signoff_results)/$::env(DESIGN_NAME).gds
file copy -force $klayout_out $::env(CURRENT_GDS)
}
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "gdsii - klayout"
scrot_klayout -layout $::env(signoff_results)/$::env(DESIGN_NAME).gds -log $::env(signoff_logs)/screenshot.klayout.log
} elseif { $::env(PRIMARY_SIGNOFF_TOOL) != "klayout" } {
puts_warn "::env(KLAYOUT_TECH) is not defined for the current PDK. So, GDS-II streaming out using Klayout will be skipped."
puts_warn "This warning can be turned off by setting ::env(RUN_KLAYOUT) to 0, or defining a tech file."
} else {
puts_err "::env(KLAYOUT_TECH) is not defined for the current PDK, however Klayout is set as the primary signoff tool. This is a critical error."
flow_fail
}
}
proc scrot_klayout {args} {
if {$::env(TAKE_LAYOUT_SCROT)} {
increment_index
TIMER::timer_start
puts_info "Taking a Screenshot of the Layout Using Klayout..."
if {[ info exists ::env(KLAYOUT_TECH)] } {
set options {
{-log required}
{-layout optional}
}
parse_key_args "scrot_klayout" args arg_values $options
if {[info exists ::env(CURRENT_GDS)]} {
set_if_unset arg_values(-layout) $::env(CURRENT_GDS)
}
set log [index_file $arg_values(-log)]
try_catch bash $::env(SCRIPTS_DIR)/klayout/scrotLayout.sh $::env(KLAYOUT_TECH) $arg_values(-layout) |& tee $::env(TERMINAL_OUTPUT) $log
puts_info "Screenshot taken."
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "screenshot - klayout"
} elseif { $::env(PRIMARY_SIGNOFF_TOOL) != "klayout" } {
puts_warn "::env(KLAYOUT_DRC_TECH_SCRIPT) is not defined for the current PDK. So, GDS-II streaming out using Klayout will be skipped."
puts_warn "This warning can be turned off by setting ::env(RUN_KLAYOUT_DRC) to 0, or designating a tech file."
} else {
puts_err "::env(KLAYOUT_DRC_TECH_SCRIPT) is not defined for the current PDK, however Klayout is set as the primary signoff tool. This is a critical error."
flow_fail
}
}
}
proc run_klayout_drc {args} {
TIMER::timer_start
if {[ info exists ::env(KLAYOUT_DRC_TECH_SCRIPT)] && [file exists $::env(KLAYOUT_DRC_TECH_SCRIPT)]} {
increment_index
puts_info "Running DRC on the layout using Klayout..."
set options {
{-gds optional}
{-stage optional}
}
parse_key_args "run_klayout_drc" args arg_values $options
if {[info exists ::env(CURRENT_GDS)]} {
set_if_unset arg_values(-gds) $::env(CURRENT_GDS)
}
set_if_unset arg_values(-stage) magic
try_catch bash $::env(SCRIPTS_DIR)/klayout/run_drc.sh $::env(KLAYOUT_DRC_TECH_SCRIPT) $arg_values(-gds) $arg_values(-gds).lydrc |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(signoff_logs)/$arg_values(-stage).drc.log]
file copy -force $arg_values(-gds).lydrc [index_file $::env(signoff_reports)/$arg_values(-stage).lydrc]
puts_info "Klayout DRC Complete"
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "drc - klayout"
} elseif { $::env(PRIMARY_SIGNOFF_TOOL) != "klayout" } {
puts_warn "::env(KLAYOUT_DRC_TECH_SCRIPT) is not defined or doesn't exist for the current PDK. So, GDS-II streaming out using Klayout will be skipped."
puts_warn "This warning can be turned off by setting ::env(RUN_KLAYOUT_DRC) to 0, or designating a tech file."
} else {
puts_err "::env(KLAYOUT_DRC_TECH_SCRIPT) is not defined or doesn't exist for the current PDK, however Klayout is set as the primary signoff tool. This is a critical error."
flow_fail
}
}
proc run_klayout_gds_xor {args} {
increment_index
index_file $::env(signoff_logs)/xor.log
TIMER::timer_start
puts_info "Running XOR on the layouts using Klayout..."
set options {
{-layout1 optional}
{-layout2 optional}
{-output_xml optional}
{-output_gds optional}
}
parse_key_args "run_klayout_gds_xor" args arg_values $options
set_if_unset arg_values(-layout1) $::env(signoff_results)/$::env(DESIGN_NAME).gds
set_if_unset arg_values(-layout2) $::env(signoff_results)/$::env(DESIGN_NAME).klayout.gds
set_if_unset arg_values(-output_xml) $::env(signoff_reports)/$::env(DESIGN_NAME).xor.xml
set_if_unset arg_values(-output_gds) $::env(signoff_reports)/$::env(DESIGN_NAME).xor.gds
if { [file exists $arg_values(-layout1)]} {
if { [file exists $arg_values(-layout2)] } {
if { $::env(KLAYOUT_XOR_GDS) } {
try_catch bash $::env(SCRIPTS_DIR)/klayout/xor.sh \
$arg_values(-layout1) $arg_values(-layout2) $::env(DESIGN_NAME) \
$arg_values(-output_gds) \
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(signoff_logs)/xor.log]
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
-l [index_file $::env(signoff_logs)/xor.log] \
-o [index_file $::env(signoff_reports)/xor.rpt]
scrot_klayout -layout $arg_values(-output_gds) -log $::env(signoff_logs)/screenshot.klayout.xor.log
}
if { $::env(KLAYOUT_XOR_XML) } {
try_catch bash $::env(SCRIPTS_DIR)/klayout/xor.sh \
$arg_values(-layout1) $arg_values(-layout2) $::env(DESIGN_NAME) \
$arg_values(-output_xml) \
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(signoff_logs)/xor.log]
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
-l [index_file $::env(signoff_logs)/xor.log] \
-o [index_file $::env(signoff_reports)/xor.rpt]
}
} else {
puts_warn "$arg_values(-layout2) wasn't found. Skipping GDS XOR."
}
} else {
puts_warn "$arg_values(-layout1) wasn't found. Skipping GDS XOR."
}
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "xor - klayout"
}
proc open_in_klayout {args} {
set options {
{-layout optional}
}
parse_key_args "open_in_klayout" args arg_values $options
set_if_unset arg_values(-layout) $::env(CURRENT_DEF)
try_catch python3 $::env(SCRIPTS_DIR)/klayout/open_design_cmd.py\
$arg_values(-layout)
}
package provide openlane 0.9