diff --git a/.github/workflows/test-docker-image-run-drc-for-cell-gds-using-magic.yml b/.github/workflows/test-docker-image-run-drc-for-cell-gds-using-magic.yml new file mode 100644 index 0000000..6f72005 --- /dev/null +++ b/.github/workflows/test-docker-image-run-drc-for-cell-gds-using-magic.yml @@ -0,0 +1,73 @@ +# Copyright 2021 Google LLC +# +# 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 +# +# https://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. +# +# SPDX-License-Identifier: Apache-2.0 +name: Test Docker Image for Run DRC for cell GDS (using Magic) Action + +on: + workflow_dispatch: + push: + pull_request: + + +permissions: + contents: read + + +jobs: + + test: + name: Basic Test + + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v2 + + - name: Check tests/action-local/action.yml is up to date + run: | + cd run-drc-for-cell-gds-using-magic + make ./tests/action-local/action.yml + git diff --exit-code --color=always ./tests/action-local/action.yml + + - uses: ./run-drc-for-cell-gds-using-magic/tests/action-local + name: Clean cells should pass. + with: + top: ./run-drc-for-cell-gds-using-magic/tests/clean + + - uses: ./run-drc-for-cell-gds-using-magic/tests/action-local + name: Broken cells is filtered (--known-bad). + with: + top: ./run-drc-for-cell-gds-using-magic/tests/broken + known-bad: sky130_fd_sc_hd__clkdlybuf4s15_1 + + - uses: ./run-drc-for-cell-gds-using-magic/tests/action-local + name: Broken cells is filtered (--match-cells). + with: + top: ./run-drc-for-cell-gds-using-magic/tests/broken + match-cell-directories: clean_cell + + - uses: ./run-drc-for-cell-gds-using-magic/tests/action-local + name: Broken cells should fail. + id: broken-should-fail + continue-on-error: true + with: + top: ./run-drc-for-cell-gds-using-magic/tests/broken + + - name: Error on success + if: steps.broken-should-fail.outcome != 'failure' + run: + echo "The action should have failed!" + exit 1 diff --git a/run-drc-for-cell-gds-using-magic/.update-test-action-local.py b/run-drc-for-cell-gds-using-magic/.update-test-action-local.py new file mode 100755 index 0000000..0a2455e --- /dev/null +++ b/run-drc-for-cell-gds-using-magic/.update-test-action-local.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright 2020 SkyWater PDK Authors +# +# 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 +# +# https://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. +# +# SPDX-License-Identifier: Apache-2.0 + +import pathlib + +__dir__ = pathlib.Path(__file__).parent.resolve() + +src_action_yml = __dir__ / 'action.yml' +dst_action_yml = (__dir__ / 'tests' / 'action-local' / 'action.yml').resolve() + +print('Base action.yml file at:', src_action_yml) +print('Test action.yml file at:', dst_action_yml) + +with open(src_action_yml) as f: + action_data = f.read() + +name = 'run-drc-for-cell-gds-using-magic' +action_data = action_data.replace( + f'image: docker://gcr.io/skywater-pdk/actions/{name}:main', + 'image: ../../Dockerfile', +) + +action_data = action_data.replace( + '\nname:', + """ +# WARNING! Don't modify this file, modify the base `action.yml` file and then +# run `make tests/action-local/action.yml`. + +name:""") + +with open(dst_action_yml, 'w') as f: + f.write(action_data) diff --git a/run-drc-for-cell-gds-using-magic/Makefile b/run-drc-for-cell-gds-using-magic/Makefile index fb408e8..ef26bc8 100644 --- a/run-drc-for-cell-gds-using-magic/Makefile +++ b/run-drc-for-cell-gds-using-magic/Makefile @@ -16,8 +16,15 @@ TOP_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))/..) +NAME := run-drc-for-cell-gds-using-magic + +tests/action-local/action.yml: action.yml .update-test-action-local.py + $(TOP_DIR)/$(NAME)/.update-test-action-local.py + +.PHONY: tests/action-local/action.yml + README.rst: README.src.rst $(TOP_DIR)/docs/*.rst $(TOP_DIR)/Makefile - make -C $(TOP_DIR) run-drc-for-cell-gds-using-magic/README.rst + make -C $(TOP_DIR) $(NAME)/README.rst # Redirect everything to the top directory by default. %: diff --git a/run-drc-for-cell-gds-using-magic/README.rst b/run-drc-for-cell-gds-using-magic/README.rst index e0ad9d5..7c20f65 100644 --- a/run-drc-for-cell-gds-using-magic/README.rst +++ b/run-drc-for-cell-gds-using-magic/README.rst @@ -19,9 +19,7 @@ Add this to any push, PR or manual dispatch workflow: - uses: actions/checkout@v2 - name: Run DRC for cell GDS (using Magic) - uses: docker://gcr.io/skywater-pdk/actions/run-drc-for-cell-gds-using-magic:latest - with: - args: --acceptable-errors-file /dev/null --match-directories . --known-bad '' + uses: google/skywater-pdk-actions/run-drc-for-cell-gds-using-magic@main Check the Python file for more documentation on arguments. diff --git a/run-drc-for-cell-gds-using-magic/README.src.rst b/run-drc-for-cell-gds-using-magic/README.src.rst index 75734ef..52ee987 100644 --- a/run-drc-for-cell-gds-using-magic/README.src.rst +++ b/run-drc-for-cell-gds-using-magic/README.src.rst @@ -19,9 +19,7 @@ Add this to any push, PR or manual dispatch workflow: - uses: actions/checkout@v2 - name: Run DRC for cell GDS (using Magic) - uses: docker://gcr.io/skywater-pdk/actions/run-drc-for-cell-gds-using-magic:latest - with: - args: --acceptable-errors-file /dev/null --match-directories . --known-bad '' + uses: google/skywater-pdk-actions/run-drc-for-cell-gds-using-magic@main Check the Python file for more documentation on arguments. diff --git a/run-drc-for-cell-gds-using-magic/action.yml b/run-drc-for-cell-gds-using-magic/action.yml new file mode 100644 index 0000000..46465bd --- /dev/null +++ b/run-drc-for-cell-gds-using-magic/action.yml @@ -0,0 +1,52 @@ +# Copyright 2020 SkyWater PDK Authors +# +# 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 +# +# https://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. +# +# SPDX-License-Identifier: Apache-2.0 + +name: run-drc-for-cell-gds-using-magic +description: >- + This GitHub action runs Design Rule Checks on all GDS files inside the /cells + directory. + +inputs: + top: + description: >- + What directory to run the check inside. + default: . + acceptable-errors-file: + description: >- + A file containing a list of newline-delimited acceptable DRC errors. + default: /dev/null + match-cell-directories: + description: >- + A regex that will match cell names to be checked. + default: ^.*$ + known-bad: + description: >- + Common separated list of known bad cells that should be ignored. + default: + + +runs: + using: 'docker' + image: docker://gcr.io/skywater-pdk/actions/run-drc-for-cell-gds-using-magic:main + args: + - --top + - ${{ inputs.top }} + - --acceptable-errors-file + - ${{ inputs.acceptable-errors-file }} + - --match-cell-directories + - ${{ inputs.match-cell-directories }} + - --known-bad + - ${{ inputs.known-bad }} diff --git a/run-drc-for-cell-gds-using-magic/run_all_drc.py b/run-drc-for-cell-gds-using-magic/run_all_drc.py index 5adcbcd..6811e66 100644 --- a/run-drc-for-cell-gds-using-magic/run_all_drc.py +++ b/run-drc-for-cell-gds-using-magic/run_all_drc.py @@ -134,6 +134,13 @@ def drc_gds(path: str) -> Tuple[str, List[DRCError]]: @click.command() +@click.option( + "-t", + "--top", + default=".", + help="Directory to run the process inside." + " Default: Current working directory" +) @click.option( "-a", "--acceptable-errors-file", @@ -143,10 +150,11 @@ def drc_gds(path: str) -> Tuple[str, List[DRCError]]: ) @click.option( "-m", - "--match-directories", - default=".", - help="A regex that will match subdirectories under cells/." - " Default: . (matches everything.)" + "--match-cell-directories", + default="^.*$", + help="A regex that that will match cell names to be checked (which will" + " match subdirectories under cells/)." + " Default: ^.*$ (matches everything)" ) @click.option( "-b", @@ -156,12 +164,27 @@ def drc_gds(path: str) -> Tuple[str, List[DRCError]]: " thus do not cause a non-zero exit upon failure." " Default: empty string (None of them.)" ) -def run_all_drc(acceptable_errors_file, match_directories, known_bad): - print("Testing cells in directories matching /%s/…" % match_directories) +def run_all_drc( + top, + acceptable_errors_file, + match_cell_directories, + known_bad, + ): + + os.chdir(top) + print("Testing cells in %s directories matching /%s/…" % ( + os.getcwd(), match_cell_directories)) global acceptable_errors - acceptable_errors_str = open(acceptable_errors_file).read() - acceptable_errors = acceptable_errors_str.split("\n") + acceptable_errors = [] + with open(acceptable_errors_file) as f: + acceptable_errors += f.read().split("\n") + + cells_dir = "./cells" + lib_acceptable_errors_file = os.path.join(cells_dir, 'allowed_drc_errors') + if os.path.exists(lib_acceptable_errors_file): + with open(lib_acceptable_errors_file) as f: + acceptable_errors += f.read().split("\n") known_bad_list = known_bad.split(",") @@ -169,15 +192,16 @@ def run_all_drc(acceptable_errors_file, match_directories, known_bad): with futures.ThreadPoolExecutor(max_workers=nproc) as executor: future_list = [] - cells_dir = "./cells" cells = os.listdir(cells_dir) for cell in cells: - if not re.match(match_directories, cell): + if not re.fullmatch(match_cell_directories, cell): print("Skipping directory %s…" % cell) continue cell_dir = os.path.join(cells_dir, cell) + if not os.path.isdir(cell_dir): + continue gds_list = list( filter(lambda x: x.endswith(".gds"), os.listdir(cell_dir)) @@ -195,19 +219,23 @@ def run_all_drc(acceptable_errors_file, match_directories, known_bad): total += 1 cell_name, errors = future.result() - symbol = "❌" - message = "ERROR" if len(errors) == 0: successes += 1 # This tick is rendered black on all major platforms except for # Microsoft. symbol = "✔\ufe0f" message = "CLEAN" + elif cell_name in known_bad_list: + symbol = "✘\ufe0f" + message = "ERROR (ignored as known bad)" + else: + symbol = "❌" + message = "ERROR" + exit_code = 65 + print("%-64s %s %s" % (cell_name, symbol, message)) if len(errors) != 0: - if cell_name not in known_bad_list: - exit_code = 65 for error in errors: print("* %s" % error[0]) for line in error[1]: diff --git a/run-drc-for-cell-gds-using-magic/tests/action-local/action.yml b/run-drc-for-cell-gds-using-magic/tests/action-local/action.yml new file mode 100644 index 0000000..17f369f --- /dev/null +++ b/run-drc-for-cell-gds-using-magic/tests/action-local/action.yml @@ -0,0 +1,55 @@ +# Copyright 2020 SkyWater PDK Authors +# +# 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 +# +# https://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. +# +# SPDX-License-Identifier: Apache-2.0 + +# WARNING! Don't modify this file, modify the base `action.yml` file and then +# run `make tests/action-local/action.yml`. + +name: run-drc-for-cell-gds-using-magic +description: >- + This GitHub action runs Design Rule Checks on all GDS files inside the /cells + directory. + +inputs: + top: + description: >- + What directory to run the check inside. + default: . + acceptable-errors-file: + description: >- + A file containing a list of newline-delimited acceptable DRC errors. + default: /dev/null + match-cell-directories: + description: >- + A regex that will match cell names to be checked. + default: ^.*$ + known-bad: + description: >- + Common separated list of known bad cells that should be ignored. + default: + + +runs: + using: 'docker' + image: ../../Dockerfile + args: + - --top + - ${{ inputs.top }} + - --acceptable-errors-file + - ${{ inputs.acceptable-errors-file }} + - --match-cell-directories + - ${{ inputs.match-cell-directories }} + - --known-bad + - ${{ inputs.known-bad }} diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/allowed_drc_errors b/run-drc-for-cell-gds-using-magic/tests/broken/cells/allowed_drc_errors new file mode 120000 index 0000000..2cfcf43 --- /dev/null +++ b/run-drc-for-cell-gds-using-magic/tests/broken/cells/allowed_drc_errors @@ -0,0 +1 @@ +../../clean/cells/allowed_drc_errors \ No newline at end of file diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_1.gds b/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_1.gds new file mode 100644 index 0000000..b7e4c16 Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_1.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_2.gds b/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_2.gds new file mode 100644 index 0000000..bb1a0d8 Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/broken/cells/broken_cell/sky130_fd_sc_hd__clkdlybuf4s15_2.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_1.gds b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_1.gds new file mode 100644 index 0000000..d4a081a Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_1.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_2.gds b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_2.gds new file mode 100644 index 0000000..2e70fa7 Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_2.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_4.gds b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_4.gds new file mode 100644 index 0000000..879002f Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/broken/cells/clean_cell/sky130_fd_sc_hd__a211o_4.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_1.gds b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_1.gds new file mode 100644 index 0000000..b4d1193 Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_1.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_2.gds b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_2.gds new file mode 100644 index 0000000..7e32913 Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_2.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_4.gds b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_4.gds new file mode 100644 index 0000000..062a5cb Binary files /dev/null and b/run-drc-for-cell-gds-using-magic/tests/clean/cells/a2111o/sky130_fd_sc_hd__a2111o_4.gds differ diff --git a/run-drc-for-cell-gds-using-magic/tests/clean/cells/allowed_drc_errors b/run-drc-for-cell-gds-using-magic/tests/clean/cells/allowed_drc_errors new file mode 100644 index 0000000..e1e13a9 --- /dev/null +++ b/run-drc-for-cell-gds-using-magic/tests/clean/cells/allowed_drc_errors @@ -0,0 +1,3 @@ +All nwells must contain metal-connected N+ taps (nwell.4) +P-diff distance to N-tap must be < 15.0um (LU.3) +N-diff distance to P-tap must be < 15.0um (LU.2) \ No newline at end of file