mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
Integrate KLayout DRC for sky130 (#2059)
~ Bump open_pdks version to `cd1748bb197f9b7af62a54507de6624e30363943` ~ Rename `PRIMARY_SIGNOFF_TOOL` to `PRIMARY_GDSII_STREAMOUT_TOOL` ~ Update documentation of `RUN_MAGIC_DRC` and `RUN_KLAYOUT_DRC` + Integrate KLayout DRC for sky130 + Add the following variables: ``` KLAYOUT_DRC_THREADS QUIT_ON_KLAYOUT_DRC RUN_KLAYOUT_DRC KLAYOUT_DRC_RUNSET - PDK variable KLAYOUT_DRC_OPTIONS - PDK variable ``` - Remove `KLAYOUT_DRC_KLAYOUT_GDS`
This commit is contained in:
@@ -41,3 +41,4 @@ set ::env(QUIT_ON_LVS_ERROR) 1
|
||||
|
||||
# Klayout
|
||||
set ::env(QUIT_ON_XOR_ERROR) 1
|
||||
set ::env(QUIT_ON_KLAYOUT_DRC) 1
|
||||
|
||||
@@ -41,7 +41,7 @@ set ::env(RUN_IRDROP_REPORT) 1
|
||||
|
||||
## Signoff
|
||||
set ::env(RUN_CVC) 1
|
||||
set ::env(PRIMARY_SIGNOFF_TOOL) magic
|
||||
set ::env(PRIMARY_GDSII_STREAMOUT_TOOL) magic
|
||||
|
||||
### Netgen
|
||||
set ::env(RUN_LVS) 1
|
||||
@@ -70,7 +70,8 @@ set ::env(MAGIC_GDS_POLYGON_SUBCELLS) 0
|
||||
|
||||
### Klayout-Specific
|
||||
set ::env(RUN_KLAYOUT) 1
|
||||
set ::env(RUN_KLAYOUT_DRC) 0
|
||||
set ::env(RUN_KLAYOUT_DRC) 1
|
||||
set ::env(KLAYOUT_DRC_THREADS) 1
|
||||
set ::env(KLAYOUT_XOR_THREADS) 1
|
||||
set ::env(KLAYOUT_XOR_IGNORE_LAYERS) ""
|
||||
set ::env(TAKE_LAYOUT_SCROT) 0
|
||||
|
||||
2
dependencies/tool_metadata.yml
vendored
2
dependencies/tool_metadata.yml
vendored
@@ -64,6 +64,6 @@
|
||||
in_install: false
|
||||
- name: open_pdks
|
||||
repo: https://github.com/RTimothyEdwards/open_pdks
|
||||
commit: e0f692f46654d6c7c99fc70a0c94a080dab53571
|
||||
commit: cd1748bb197f9b7af62a54507de6624e30363943
|
||||
in_install: false
|
||||
pdk: true
|
||||
|
||||
@@ -23,6 +23,7 @@ ENV OPENROAD_BIN openroad
|
||||
|
||||
ENV OPENROAD=/build/
|
||||
ENV PATH=$OPENLANE_ROOT:$OPENLANE_ROOT/scripts:$OPENROAD/bin:$OPENROAD/bin/Linux-x86_64:$OPENROAD/pdn/scripts:$PATH
|
||||
ENV PYTHONPATH=$PYTHONPATH:/build/lib/python3/dist-packages
|
||||
ENV LD_LIBRARY_PATH=$OPENROAD/lib:$OPENROAD/lib/Linux-x86_64:$LD_LIBRARY_PATH
|
||||
ENV MANPATH=$OPENROAD/share/man:$MANPATH
|
||||
ENV PDK_ROOT /build/pdk
|
||||
|
||||
@@ -321,7 +321,7 @@ These variables worked initially, but they were too sky130 specific and will be
|
||||
|
||||
|Variable|Description|
|
||||
|-|-|
|
||||
| `PRIMARY_SIGNOFF_TOOL` <a id="PRIMARY_SIGNOFF_TOOL"></a> | Determines whether `magic` or `klayout` is the primary signoff tool. <br> (Default: `magic`) |
|
||||
| `PRIMARY_GDSII_STREAMOUT_TOOL` <a id="PRIMARY_GDSII_STREAMOUT_TOOL"></a> | Determines whether `magic` or `klayout` is the primary signoff tool. <br> (Default: `magic`) |
|
||||
| `USE_ARC_ANTENNA_CHECK` <a id="USE_ARC_ANTENNA_CHECK"></a> | Specifies whether to use the openroad ARC antenna checker or magic antenna checker. 0=magic antenna checker, 1=ARC OR antenna checker <br> (Default: `1`)
|
||||
| `RUN_CVC` <a id="RUN_CVC"></a> | Runs CVC on the output spice, which is a Circuit Validity Checker. Voltage aware ERC checker for CDL netlists. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `SIGNOFF_SDC_FILE` <a id="SIGNOFF_SDC_FILE"></a> | Specifies SDC file used by multicorner STA during signoff stage, which can be different from the one used for implementation. <br> (Default: `BASE_SDC_FILE`) |
|
||||
@@ -330,7 +330,7 @@ These variables worked initially, but they were too sky130 specific and will be
|
||||
|Variable|Description|
|
||||
|-|-|
|
||||
| `RUN_MAGIC` <a id="RUN_MAGIC"></a> | Enables running magic and GDSII streaming. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `RUN_MAGIC_DRC` <a id="RUN_MAGIC_DRC"></a> | Enables running magic DRC on GDSII produced by magic. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `RUN_MAGIC_DRC` <a id="RUN_MAGIC_DRC"></a> | Enables running magic DRC on either GDSII produced by `PRIMARY_GDSII_STREAMOUT_TOOL` or final produced DEF file depending on `MAGIC_DRC_USE_GDS`. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `MAGIC_PAD` <a id="MAGIC_PAD"></a> | A flag to pad the views generated by magic (.mag, .lef, .gds) with one site. 1 = Enabled, 0 = Disabled <br> (Default: `0`)|
|
||||
| `MAGIC_ZEROIZE_ORIGIN` <a id="MAGIC_ZEROIZE_ORIGIN"></a> | A flag to move the layout such that it's origin in the lef generated by magic is 0,0. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `MAGIC_GENERATE_GDS` <a id="MAGIC_GENERATE_GDS"></a> | A flag to generate gds view via magic. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
@@ -355,9 +355,10 @@ These variables worked initially, but they were too sky130 specific and will be
|
||||
|-|-|
|
||||
| `RUN_KLAYOUT` <a id="RUN_KLAYOUT"></a> | Enables running KLayout and GDSII streaming. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `RUN_KLAYOUT_XOR` <a id="RUN_KLAYOUT_XOR"></a> | Enables running KLayout XOR on 2 GDSIIs, the defaults are the one produced by magic vs the one produced by klayout. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `RUN_KLAYOUT_DRC` <a id="RUN_KLAYOUT_DRC"></a> | Enables running KLayout DRC on GDSII produced by magic. 1 = Enabled, 0 = Disabled <br> (Default: `0`)|
|
||||
| `RUN_KLAYOUT_DRC` <a id="RUN_KLAYOUT_DRC"></a> | Enables running KLayout DRC on GDSII produced by `PRIMARY_GDSII_STREAMOUT_TOOL`. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
| `KLAYOUT_DRC_KLAYOUT_GDS` <a id="KLAYOUT_DRC_KLAYOUT_GDS"></a> | Enables running KLayout DRC on GDSII produced by KLayout. 1 = Enabled, 0 = Disabled <br> (Default: `0`)|
|
||||
| `KLAYOUT_XOR_THREADS` <a id="KLAYOUT_XOR_THREADS"></a> | Specifies number of threads used in klayout xor check <br> (Default: `1`)|
|
||||
| `KLAYOUT_DRC_THREADS` <a id="KLAYOUT_DRC_THREADS"></a> | Specifies number of threads used in klayout drc check <br> (Default: `1`)|
|
||||
| `TAKE_LAYOUT_SCROT` <a id="TAKE_LAYOUT_SCROT"></a> | Enables running KLayout to take a PNG screenshot of the produced layout (currently configured to run on the results of each stage).1 = Enabled, 0 = Disabled <br> (Default: `0`)|
|
||||
|
||||
|
||||
@@ -390,6 +391,7 @@ These variables worked initially, but they were too sky130 specific and will be
|
||||
| `QUIT_ON_LINTER_WARNINGS` <a id="QUIT_ON_LINTER_WARNINGS"></a> | Quit on warnings generated by linter (currently Verilator) <br> (Default: `0`)|
|
||||
| `QUIT_ON_LINTER_ERRORS` <a id="QUIT_ON_LINTER_ERRORS"></a> | Quit on errors generated by linter (currently Verilator) <br> (Default: `1`)|
|
||||
| `QUIT_ON_XOR_ERROR` <a id="QUIT_ON_XOR_ERROR"></a> | Quit on XOR differences between GDSII generated by Magic and KLayout <br> (Default: `1`)|
|
||||
| `QUIT_ON_KLAYOUT_DRC` <a id="QUIT_ON_KLAYOUT_DRC"></a> | Checks for DRC violations after KLayout DRC is executed and exits the flow if any was found. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
|
||||
|
||||
## Misc.
|
||||
|
||||
|
||||
@@ -251,13 +251,11 @@ Most of the following commands' implementation exists in this [file][17]
|
||||
|
||||
| Command | Flags | Description |
|
||||
|---------------|------------------------|-----------------------------------------|
|
||||
| `run_klayout` | | Streams the back-up final GDSII, generates a PNG screenshot, then runs KLayout DRC deck on it. This is controlled by `RUN_KLAYOUT`, `TAKE_LAYOUT_SCROT` ,and `KLAYOUT_DRC_KLAYOUT_GDS`. The resulting file is under `/<run_path>/results/klayout/` . |
|
||||
| `run_klayout` | | Streams the back-up final GDSII, generates a PNG screenshot, then runs KLayout DRC deck on it. This is controlled by `RUN_KLAYOUT` and `TAKE_LAYOUT_SCROT`. The resulting file is under `/<run_path>/results/klayout/` . |
|
||||
| `scrot_klayout` | | Export a PNG view of a given GDSII or DEF file. This is controlled by `TAKE_LAYOUT_SCROT`. |
|
||||
| | `[-log <log_file>]` | Output log file. |
|
||||
| | `[-layout <layout_file>]` | The input GDS or DEF file, the default is `::env(CURRENT_GDS)`. |
|
||||
| `run_klayout_drc` | | Runs KLayout DRC on a given GDSII file. This is controlled by `RUN_KLAYOUT_DRC`. |
|
||||
| | `[-gds <gds_file>]` | The input GDS file, the default is `::env(CURRENT_GDS)`. |
|
||||
| | `[-stage <stage>]` | The output stage using the DRC, the default is `magic`. The `magic` implies that the drc was run on the default GDS which is produced by magic. |
|
||||
| `run_klayout_drc` | | Runs KLayout DRC on a`::env(CURRENT_GDS)`. This is controlled by `RUN_KLAYOUT_DRC`. |
|
||||
| `run_klayout_gds_xor` | | Runs KLayout XOR on 2 GDSIIs. This is controlled by `RUN_KLAYOUT_XOR` and `KLAYOUT_XOR_GDS` and `KLAYOUT_XOR_XML`. |
|
||||
| | `[-layout1 <gds_file>]` | The input GDS file, the default is the magic generated GDSII under `<run_path>/results/magic/<design_name>.gds`. |
|
||||
| | `[-layout2 <gds_file>]` | The input GDS file, the default is the klayout generated GDSII under `<run_path>/results/klayout/<design_name>.gds`. |
|
||||
|
||||
@@ -58,6 +58,8 @@ you're doing.
|
||||
| `KLAYOUT_PROPERTIES` | Points to the klayout properties file (.lyp). |
|
||||
| `KLAYOUT_DEF_LAYER_MAP` | Points to klayout deflef layer map file (.map). |
|
||||
| `KLAYOUT_XOR_IGNORE_LAYERS` | A space separated layers list to ignore during klayout xor check. |
|
||||
| `KLAYOUT_DRC_RUNSET` | A path to KLayout DRC runset. |
|
||||
| `KLAYOUT_DRC_OPTIONS` | Options availble to KLayout DRC runset. They vary from one PDK to another. |
|
||||
| `MAGIC_MAGICRC` | Points to the magicrc file that is sourced while running magic in the flow. |
|
||||
| `GPIO_PADS_LEF` | A list of the pads lef views. For example:`[glob "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lef/sky130_fd_io.lef"]` |
|
||||
| `GPIO_PADS_PREFIX` | A list of pad cells name prefixes. |
|
||||
|
||||
43
scripts/klayout/xml_drc_report_to_json.py
Normal file
43
scripts/klayout/xml_drc_report_to_json.py
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2023 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.
|
||||
import json
|
||||
|
||||
from klayout.rdb import ReportDatabase
|
||||
import click
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--xml-file")
|
||||
@click.option("--json-file")
|
||||
def cli(xml_file, json_file):
|
||||
database = ReportDatabase("Database")
|
||||
json_database = {}
|
||||
database.load(xml_file)
|
||||
total = 0
|
||||
for category in database.each_category():
|
||||
num_items = category.num_items()
|
||||
category_name = category.name()
|
||||
json_database[category_name] = num_items
|
||||
total += num_items
|
||||
|
||||
json_database = dict(sorted(json_database.items(), key=lambda item: item[1]))
|
||||
json_database["total"] = total
|
||||
|
||||
with open(json_file, "w", encoding="utf8") as f:
|
||||
json.dump(json_database, f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
@@ -638,6 +638,7 @@ proc prep {args} {
|
||||
handle_deprecated_config UNBUFFER_NETS RSZ_DONT_TOUCH_RX
|
||||
|
||||
handle_deprecated_config RCX_SDC_FILE SIGNOFF_SDC_FILE
|
||||
handle_deprecated_config PRIMARY_SIGNOFF_TOOL PRIMARY_GDSII_STREAMOUT_TOOL
|
||||
|
||||
### Checkers/Quitting
|
||||
handle_deprecated_config CHECK_ASSIGN_STATEMENTS QUIT_ON_ASSIGN_STATEMENTS
|
||||
|
||||
@@ -307,7 +307,7 @@ proc quit_on_tr_drc {args} {
|
||||
puts_err "Total Number of violations is $checker"
|
||||
throw_error
|
||||
} else {
|
||||
puts_info "No DRC violations after detailed routing."
|
||||
puts_info "No Magic DRC violations after detailed routing."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ proc quit_on_magic_drc {args} {
|
||||
puts_err "Total Number of violations is $checker"
|
||||
throw_error
|
||||
} else {
|
||||
puts_info "No DRC violations after GDS streaming out."
|
||||
puts_info "No Magic DRC violations after GDS streaming out."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,4 +387,19 @@ proc quit_on_unconnected_pdn_nodes {args} {
|
||||
}
|
||||
}
|
||||
|
||||
proc quit_on_klayout_drc {report_file} {
|
||||
set violations_dict [json::json2dict [cat $report_file]]
|
||||
set violations_count [dict get $violations_dict "total"]
|
||||
if { $::env(QUIT_ON_KLAYOUT_DRC) && $violations_count != 0} {
|
||||
puts_err "There are violations in the design after KLayout DRC."
|
||||
puts_err "Total Number of violations is $violations_count"
|
||||
throw_error
|
||||
} elseif { $violations_count != 0 } {
|
||||
puts_warn "There are violations in the design after KLayout DRC."
|
||||
puts_warn "Total Number of violations is $violations_count"
|
||||
} else {
|
||||
puts_info "No KLayout DRC violations after GDS streaming out."
|
||||
}
|
||||
}
|
||||
|
||||
package provide openlane 0.9
|
||||
|
||||
@@ -52,7 +52,7 @@ proc run_klayout {args} {
|
||||
}
|
||||
|
||||
|
||||
if { $::env(PRIMARY_SIGNOFF_TOOL) == "klayout" } {
|
||||
if { $::env(PRIMARY_GDSII_STREAMOUT_TOOL) == "klayout" } {
|
||||
set ::env(CURRENT_GDS) $::env(signoff_results)/$::env(DESIGN_NAME).gds
|
||||
file copy -force $klayout_out $::env(CURRENT_GDS)
|
||||
}
|
||||
@@ -60,7 +60,7 @@ proc run_klayout {args} {
|
||||
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" } {
|
||||
} elseif { $::env(PRIMARY_GDSII_STREAMOUT_TOOL) != "klayout" } {
|
||||
puts_warn "::env(KLAYOUT_TECH) is not defined for the current PDK. So, GDSII 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 {
|
||||
@@ -70,6 +70,72 @@ proc run_klayout {args} {
|
||||
|
||||
}
|
||||
|
||||
proc run_klayout_drc {args} {
|
||||
set supported_pdks [list "sky130A" "sky130B"]
|
||||
|
||||
if {[lsearch -exact $supported_pdks $::env(PDK)] < 0} {
|
||||
puts_warn "$::env(PDK) isn't supported by OpenLane during KLayout DRC. Skipping this step."
|
||||
return
|
||||
}
|
||||
|
||||
if { $::env(PDK) == "sky130A" || $::env(PDK) == "sky130B" } {
|
||||
run_klayout_drc_sky130
|
||||
}
|
||||
}
|
||||
proc run_klayout_drc_sky130 {args} {
|
||||
if { ![info exists ::env(KLAYOUT_DRC_RUNSET)] || ![info exists ::env(KLAYOUT_DRC_OPTIONS)] } {
|
||||
puts_warn "KLAYOUT_DRC_RUNSET and KLAYOUT_DRC_OPTIONS are missing. You may be using an out-of-date PDK version. KLayout DRC will be skipped."
|
||||
return
|
||||
}
|
||||
set drc_script_path "$::env(KLAYOUT_DRC_RUNSET)"
|
||||
set xml_report "$::env(signoff_reports)/violations.xml"
|
||||
set json_report "$::env(signoff_reports)/violations.json"
|
||||
set threads $::env(KLAYOUT_DRC_THREADS)
|
||||
set feol "false"
|
||||
set beol "false"
|
||||
set floating_metal "false"
|
||||
set offgrid "false"
|
||||
set seal "false"
|
||||
if { [dict get $::env(KLAYOUT_DRC_OPTIONS) feol] } {
|
||||
set feol "true"
|
||||
}
|
||||
if { [dict get $::env(KLAYOUT_DRC_OPTIONS) beol] } {
|
||||
set beol "true"
|
||||
}
|
||||
if { [dict get $::env(KLAYOUT_DRC_OPTIONS) offgrid] } {
|
||||
set offgrid "true"
|
||||
}
|
||||
if { [dict get $::env(KLAYOUT_DRC_OPTIONS) seal] } {
|
||||
set seal "true"
|
||||
}
|
||||
if { [dict get $::env(KLAYOUT_DRC_OPTIONS) floating_metal] } {
|
||||
set floating_metal "true"
|
||||
}
|
||||
increment_index
|
||||
set drc_log [index_file $::env(signoff_logs)/drc-klayout.log]
|
||||
puts_info "Running KLayout DRC (log: [relpath . $drc_log])..."
|
||||
TIMER::timer_start
|
||||
try_exec klayout \
|
||||
-b \
|
||||
-zz \
|
||||
-r $drc_script_path \
|
||||
-rd topcell=$::env(DESIGN_NAME) \
|
||||
-rd input=$::env(CURRENT_GDS) \
|
||||
-rd report=$xml_report \
|
||||
-rd feol=$feol \
|
||||
-rd beol=$beol \
|
||||
-rd floating_metal=$floating_metal \
|
||||
-rd seal=$seal \
|
||||
-rd thread=$threads \
|
||||
|& tee $::env(TERMINAL_OUTPUT) $drc_log
|
||||
try_exec python3 \
|
||||
$::env(SCRIPTS_DIR)/klayout/xml_drc_report_to_json.py \
|
||||
--xml-file $xml_report \
|
||||
--json-file $json_report
|
||||
TIMER::timer_stop
|
||||
quit_on_klayout_drc $json_report
|
||||
}
|
||||
|
||||
proc scrot_klayout {args} {
|
||||
if {$::env(TAKE_LAYOUT_SCROT)} {
|
||||
if {[ info exists ::env(KLAYOUT_TECH)] } {
|
||||
@@ -90,7 +156,7 @@ proc scrot_klayout {args} {
|
||||
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" } {
|
||||
} elseif { $::env(PRIMARY_GDSII_STREAMOUT_TOOL) != "klayout" } {
|
||||
puts_warn "::env(KLAYOUT_DRC_TECH_SCRIPT) is not defined for the current PDK. So, GDSII 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 {
|
||||
@@ -100,37 +166,6 @@ proc scrot_klayout {args} {
|
||||
}
|
||||
}
|
||||
|
||||
proc run_klayout_drc {args} {
|
||||
if {[ info exists ::env(KLAYOUT_DRC_TECH_SCRIPT)] && [file exists $::env(KLAYOUT_DRC_TECH_SCRIPT)]} {
|
||||
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
|
||||
|
||||
increment_index
|
||||
TIMER::timer_start
|
||||
set log [index_file $::env(signoff_logs)/$arg_values(-stage).drc.log]
|
||||
puts_info "Running DRC on the layout using KLayout (log: [relpath . $log])..."
|
||||
|
||||
try_exec bash $::env(SCRIPTS_DIR)/klayout/run_drc.sh $::env(KLAYOUT_DRC_TECH_SCRIPT) $arg_values(-gds) $arg_values(-gds).lydrc |& tee $::env(TERMINAL_OUTPUT) $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, GDSII 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."
|
||||
throw_error
|
||||
}
|
||||
}
|
||||
|
||||
proc run_klayout_gds_xor {args} {
|
||||
set options {
|
||||
{-layout1 optional}
|
||||
|
||||
@@ -32,7 +32,7 @@ proc run_magic {args} {
|
||||
-indexed_log $log\
|
||||
$::env(SCRIPTS_DIR)/magic/def/mag_gds.tcl
|
||||
|
||||
if { $::env(PRIMARY_SIGNOFF_TOOL) == "magic" } {
|
||||
if { $::env(PRIMARY_GDSII_STREAMOUT_TOOL) == "magic" } {
|
||||
set ::env(CURRENT_GDS) $::env(signoff_results)/$::env(DESIGN_NAME).gds
|
||||
file copy -force $::env(MAGIC_GDS) $::env(CURRENT_GDS)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@ import sys
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
exit_code = args[1]
|
||||
run_folder = args[0]
|
||||
|
||||
log_path = os.path.join(run_folder, "openlane.log")
|
||||
|
||||
assert exit_code != 0, "OpenLane did not throw non zero exit code"
|
||||
assert (
|
||||
subprocess.call(
|
||||
["grep", "-i", "There are violations in the design after Magic DRC", log_path]
|
||||
@@ -9,7 +9,7 @@ run_folder = args[0]
|
||||
log_path = os.path.join(run_folder, "openlane.log")
|
||||
assert (
|
||||
subprocess.call(
|
||||
["grep", "-i", "No DRC violations after GDS streaming out", log_path]
|
||||
["grep", "-i", "No Magic DRC violations after GDS streaming out", log_path]
|
||||
)
|
||||
== 0
|
||||
), "OpenLane did not report the lack of DRC violations properly"
|
||||
16
tests/2041-klayout-drc_bad/config.json
Normal file
16
tests/2041-klayout-drc_bad/config.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"DESIGN_NAME": "inverter",
|
||||
"VERILOG_FILES": [],
|
||||
"RUN_CTS": false,
|
||||
"CLOCK_PORT": null,
|
||||
"PL_RANDOM_GLB_PLACEMENT": true,
|
||||
"FP_SIZING": "absolute",
|
||||
"DIE_AREA": "0 0 34.5 57.12",
|
||||
"PL_TARGET_DENSITY": 0.75,
|
||||
"FP_PDN_AUTO_ADJUST": false,
|
||||
"FP_PDN_VPITCH": 25,
|
||||
"FP_PDN_HPITCH": 25,
|
||||
"FP_PDN_VOFFSET": 5,
|
||||
"FP_PDN_HOFFSET": 5,
|
||||
"DIODE_INSERTION_STRATEGY": 3
|
||||
}
|
||||
7
tests/2041-klayout-drc_bad/interactive.tcl
Normal file
7
tests/2041-klayout-drc_bad/interactive.tcl
Normal file
@@ -0,0 +1,7 @@
|
||||
package require openlane;
|
||||
|
||||
prep -design $::env(TEST_DIR) {*}$argv
|
||||
|
||||
set ::env(CURRENT_GDS) $::env(TEST_DIR)/inverter.gds
|
||||
|
||||
run_klayout_drc
|
||||
BIN
tests/2041-klayout-drc_bad/inverter.gds
Normal file
BIN
tests/2041-klayout-drc_bad/inverter.gds
Normal file
Binary file not shown.
22
tests/2041-klayout-drc_bad/issue_regression.py
Normal file
22
tests/2041-klayout-drc_bad/issue_regression.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
exit_code = args[1]
|
||||
run_folder = args[0]
|
||||
|
||||
log_path = os.path.join(run_folder, "openlane.log")
|
||||
assert exit_code != 0, "OpenLane did not throw non zero exit code"
|
||||
assert (
|
||||
subprocess.call(
|
||||
["grep", "-i", "There are violations in the design after KLayout DRC", log_path]
|
||||
)
|
||||
== 0
|
||||
), "OpenLane does not accurately report the existence of violations"
|
||||
|
||||
assert (
|
||||
subprocess.call(["grep", "-Pi", "Total Number of violations is \\d+", log_path])
|
||||
== 0
|
||||
), "OpenLane does not accurately print the number of violations"
|
||||
16
tests/2041-klayout-drc_good/config.json
Normal file
16
tests/2041-klayout-drc_good/config.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"DESIGN_NAME": "inverter",
|
||||
"VERILOG_FILES": [],
|
||||
"RUN_CTS": false,
|
||||
"CLOCK_PORT": null,
|
||||
"PL_RANDOM_GLB_PLACEMENT": true,
|
||||
"FP_SIZING": "absolute",
|
||||
"DIE_AREA": "0 0 34.5 57.12",
|
||||
"PL_TARGET_DENSITY": 0.75,
|
||||
"FP_PDN_AUTO_ADJUST": false,
|
||||
"FP_PDN_VPITCH": 25,
|
||||
"FP_PDN_HPITCH": 25,
|
||||
"FP_PDN_VOFFSET": 5,
|
||||
"FP_PDN_HOFFSET": 5,
|
||||
"DIODE_INSERTION_STRATEGY": 3
|
||||
}
|
||||
7
tests/2041-klayout-drc_good/interactive.tcl
Normal file
7
tests/2041-klayout-drc_good/interactive.tcl
Normal file
@@ -0,0 +1,7 @@
|
||||
package require openlane;
|
||||
|
||||
prep -design $::env(TEST_DIR) {*}$argv
|
||||
|
||||
set ::env(CURRENT_GDS) $::env(TEST_DIR)/inverter.gds
|
||||
|
||||
run_klayout_drc
|
||||
BIN
tests/2041-klayout-drc_good/inverter.gds
Normal file
BIN
tests/2041-klayout-drc_good/inverter.gds
Normal file
Binary file not shown.
15
tests/2041-klayout-drc_good/issue_regression.py
Normal file
15
tests/2041-klayout-drc_good/issue_regression.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
run_folder = args[0]
|
||||
|
||||
log_path = os.path.join(run_folder, "openlane.log")
|
||||
assert (
|
||||
subprocess.call(
|
||||
["grep", "-i", "No KLayout DRC violations after GDS streaming out", log_path]
|
||||
)
|
||||
== 0
|
||||
), "OpenLane did not report the lack of DRC violations properly"
|
||||
Reference in New Issue
Block a user