Skip to content

KLayout DRC Enhancements and QA #529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: dev
Choose a base branch
from
Open

Conversation

FaragElsayed2
Copy link
Contributor

@FaragElsayed2 FaragElsayed2 commented Jun 3, 2025

KLayout DRC Enhancements and QA

This PR includes major improvements and validations for the KLayout G2 DRC:

✅ DRC Improvements

  • Restructured and cleaned up existing DRC rule files for better readability and performance.
  • Added the full list of minimum rule set checks.
  • Implemented variables based DRC rules using tech json data.
  • All CLI and GUI run scripts updated to align with the new rule structure and options.
  • Added support for launching and running DRC directly via the KLayout GUI.
  • Integrated regression tests for minimum rule set.

@FaragElsayed2 FaragElsayed2 force-pushed the dev branch 2 times, most recently from 8e2aef0 to 67ad578 Compare June 4, 2025 07:57
Copy link
Contributor

@dnltz dnltz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh nice! I will run them on my designs and give you more feedback.

@KrzysztofHerman
Copy link
Contributor

@atorkmabrains @FaragElsayed2
I have these errors running klayout after the modifications in the JSON file

IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py:35: KeyError: 'grid'
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py:35
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/geometry.py:26
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/thermal.py:22
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmos_code.py:22
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py:238
IHP-Open-PDK/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py:251

Run IHP SG13G2 OpenSource DRC.

Usage:
run_drc.py (--help| -h)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also use pylint and/or flake8 and try to fix those reported issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnltz Thanks for your review.

We will take care of linting issues. But may I understand why do we need to use argparse package?

docopt is POSIX standard documentation based parsing library that has been there for a while.

Cc @FaragElsayed2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnltz @atorkmabrains We support flake8 for code style checks, and our GitHub Actions includes a linting step that validates all our python scripts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnltz @atorkmabrains We support flake8 for code style checks, and our GitHub Actions includes a linting step that validates all our python scripts.

Yes, sorry. Missed that change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnltz Thanks for your review.

We will take care of linting issues. But may I understand why do we need to use argparse package?

docopt is POSIX standard documentation based parsing library that has been there for a while.

Cc @FaragElsayed2

argparse is a Python built-in library and doesn't require any additional packages. Additional it has some nice features:

  1. Default values. For example parser.add_argument('--mp', default=os.cpu_count())
  2. Limit possible arguments with choices. For example `parser.add_argument('--run_mode', choices=['flat', 'deep'])''
  3. Define argument types which can simplify arguments like density. For example `parser.add_argument(''--density', action='store_true)' and this argument is False when not defined and True and defined.
  4. Validate arguments when parsing them. For example you can validate a file actually exists: https://stackoverflow.com/questions/11540854/file-as-command-line-argument-for-argparse-error-message-if-argument-is-not-va

there is more but you can basically off-load quite a load of work to argparser and simplify your code by also expecting correct values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnltz

I'm familiar with argparse library and what it can do. docopt is capable of doing everything you have mentioned without writing a line of code with the exception of number 4. For docopt, all you need to do is to format your script docstring to the standard POSIX tool usage documentation schema which has been around for decades now. And docopt package automatically do the rest. Not a single line code is required.

The only drawback is that you have to install the docopt package while argparse is standard package. I kind of don't think installation is a problem anyway.

Posix standard: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02

http://docopt.org/

Happy to use argparse but I just wanted to clarify the reason we used docopt as I believe there was a good reason.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atorkmabrains @dnltz @FaragElsayed2
In general would be preferable to use python built-in libraries, what releases us of installing and dealing with the dependencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

All docopt usage has been migrated to argparse.

@dnltz
Copy link
Contributor

dnltz commented Jun 11, 2025

@FaragElsayed2 tried it on a small design with 1104264.7056 um^2 and hell yeah only 40 seconds! That's great :)

…rt, updating docs and workflow

Signed-off-by: FaragElsayed2 <[email protected]>
@FaragElsayed2
Copy link
Contributor Author

@FaragElsayed2 @atorkmabrains

after trying to run a DRC check on the following design I get immediate crash. I have tested with 2 separate machines and 2 versions of klayout. It is a pretty big design.

Testing other example example works without issues. Could you please take a look.

Signal number: 11
Address: 0x5c6a31267d4e
Program Version: KLayout 0.30.2 (2025-05-29 r5173a2aad)

Backtrace:
/usr/lib/klayout/libklayout_lay.so.0 +0x2f043f lay::enable_signal_handler_gui(bool) [??:?]
/lib/x86_64-linux-gnu/libc.so.6 +0x45330
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1d4486 _ZN11QFormLayoutD1Ev
/usr/lib/klayout/libklayout_QtWidgets.so.0 +0xf2411d
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1ac2c3 _ZN7QWidgetD2Ev
/usr/lib/klayout/libklayout_QtWidgets.so.0 +0x1df5f48
/usr/lib/klayout/libklayout_rba.so.0 +0x54d4c
/usr/lib/klayout/libklayout_rba.so.0 +0x54ebd
/usr/lib/klayout/libklayout_rba.so.0 +0x54f4d
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xcb14f
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xcb226
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x26f0b8 rb_postponed_job_flush
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x212fb9 rb_threadptr_execute_interrupts
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x24dbdb
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25013f
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x253212
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x257b4a rb_vm_exec
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25c297 rb_yield
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xb71d7 rb_protect
/usr/lib/klayout/libklayout_rba.so.0 +0x519ef
/usr/lib/klayout/libklayout_rba.so.0 +0x2dd70
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x24d930
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25013f
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25462c
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x257b4a rb_vm_exec
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x258762
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25c953
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25fd7e rb_funcallv
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xb71d7 rb_protect
/usr/lib/klayout/libklayout_rba.so.0 +0x517ec
/usr/lib/klayout/libklayout_rba.so.0 +0x51901
/usr/lib/klayout/libklayout_lym.so.0 +0x5a892 _ZNK3lym5Macro3runEv
/usr/lib/klayout/libklayout_laybasic.so.0 +0x1cee24 _ZN3lay6Action17qaction_triggeredEv
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x312dbf
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x164f94 _ZN7QAction9triggeredEb
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x167eab _ZN7QAction8activateENS_11ActionEventE
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x2fc512
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x304702
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1b0df8 _ZN7QWidget5eventEP6QEvent
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x16bd45 _ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1746b0 _ZN12QApplication6notifyEP7QObjectP6QEvent
/usr/lib/klayout/libklayout_lay.so.0 +0x14b380 _ZN3lay14GuiApplication9do_notifyEP7QObjectP6QEvent
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x2d8118 _ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x172874 _ZN19QApplicationPrivate14sendMouseEventEP7QWidgetP11QMouseEventS1_S1_PS1_R8QPointerIS0_Ebb
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1cb5d2
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x1cdfbf
/lib/x86_64-linux-gnu/libQt5Widgets.so.5 +0x16bd45 _ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
/usr/lib/klayout/libklayout_lay.so.0 +0x14b395 _ZN3lay14GuiApplication9do_notifyEP7QObjectP6QEvent
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x2d8118 _ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent
/lib/x86_64-linux-gnu/libQt5Gui.so.5 +0x145a3b _ZN22QGuiApplicationPrivate17processMouseEventEPN29QWindowSystemInterfacePrivate10MouseEventE
/lib/x86_64-linux-gnu/libQt5Gui.so.5 +0x117bfc _ZN22QWindowSystemInterface22sendWindowSystemEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE
/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 +0x75d06
/lib/x86_64-linux-gnu/libglib-2.0.so.0 +0x5d5c5
/lib/x86_64-linux-gnu/libglib-2.0.so.0 +0xbc737
/lib/x86_64-linux-gnu/libglib-2.0.so.0 +0x5ca63 g_main_context_iteration
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x335279 _ZN20QEventDispatcherGlib13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x2d6a7b _ZN10QEventLoop4execE6QFlagsINS_17ProcessEventsFlagEE
/lib/x86_64-linux-gnu/libQt5Core.so.5 +0x2df3e8 _ZN16QCoreApplication4execEv
/usr/lib/klayout/libklayout_lay.so.0 +0x150b0c _ZN3lay15ApplicationBase3runEv
klayout +0x4a30
/usr/lib/klayout/libklayout_rba.so.0 +0x29274
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x24d930
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x25013f
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x253212
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0x257b4a rb_vm_exec
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xb4e2c
/lib/x86_64-linux-gnu/libruby-3.2.so.3.2 +0xb9153 ruby_run_node
/usr/lib/klayout/libklayout_rba.so.0 +0x2a882 _ZN3rba15RubyInterpreter10initializeERiPPcPFiS1_S3_E
klayout +0x538c
klayout +0x4220
/lib/x86_64-linux-gnu/libc.so.6 +0x2a1ca
/lib/x86_64-linux-gnu/libc.so.6 +0x2a28b __libc_start_main
klayout +0x42e5

Hi @KrzysztofHerman

Did the crash occur while setting the options, or during the actual run?

I've made some updates that might help prevent this issue, could you please try again and let me know if it still happens?

@sergeiandreyev
Copy link
Contributor

Hi @FaragElsayed2, is it possible to put LVS regression update into a separate PR?..

@FaragElsayed2
Copy link
Contributor Author

Hi @FaragElsayed2, is it possible to put LVS regression update into a separate PR?..

Hi @sergeiandreyev

Done in #567

@sergeiandreyev
Copy link
Contributor

sergeiandreyev commented Jul 7, 2025

Hi @FaragElsayed2, should we expect more updates in this PR or we can merge it if there are no outstanding issues that you know of?..

@FaragElsayed2
Copy link
Contributor Author

Hi @sergeiandreyev, yes, I believe we can go ahead and merge this PR. I'm planning to open a separate PR soon with the missing rules and some additional enhancements.

Signed-off-by: FaragElsayed2 <[email protected]>
@EngGhaith
Copy link

Hi everyone

PR 529 is still checking Density outside sealring:
image
And V1.a is not corrected here
Why I am seeing such behavior?

Thank you in Advance.
Ghaith.

@FaragElsayed2
Copy link
Contributor Author

Hi @EngGhaith

The current DRC implementation does not perform density checks outside the chip boundary, as you pointed out. For the window-based density check, we use a window size of 800 µm × 800 µm, with a step size of 400 µm. This step size was recommended by the commercial PDK team.

In practice, this means your layout is divided into overlapping windows of 800 µm × 800 µm, each shifted by 400 µm relative to the adjacent window.

Known that our formula is:

density_window = area_metal_in_window / (800 µm * 800 µm)

For example:
If your layout dimensions are 1200 µm × 800 µm, the DRC will generate 6 windows (3 along the X‑direction × 2 along the Y‑direction).

If the layout size is not an exact multiple of the step size, additional partial windows will be created at the edges to cover the remaining areas. These edge windows are treated as individual windows for density calculation.

For such edge cases, the density is computed using only the portion of the window that lies within the chip boundary. In other words, the formula becomes:

density_window = area_metal_in_window_portion / area_of_window_within_chip

The area outside the chip extent is ignored when calculating density, the density is based solely on the valid portion of the window inside the chip.

Regarding V1.a, I’m not sure what you mean by “is not corrected here”. Could you please provide a screenshot or share the specific testcase where you’re encountering an issue with?

@sergeiandreyev
Copy link
Contributor

Regarding V1.a, I’m not sure what you mean by “is not corrected here”.

I think @EngGhaith is referring to this issue w/ npn13G2[L|V]: #569
This was fixed in Pcell code 2 weeks ago..

@FaragElsayed2
Copy link
Contributor Author

@sergeiandreyev I got it now.

It seems that some DRC violations for certain PCells are being ignored. We have applied this exclusion for the ones explicitly mentioned in the DRM as “The following rules do not apply”.

However, I noticed in the older implementation for V1.a was excluding transG2L from this check, and I also see a cntb.h1 violation in npn13G2, but those exclusions not mentioned in DRM.

I believe we could exclude all PCell violations from DRC, but that would be risky for actual designs. The safer approach would be to use waivers for these cells, but as far as I know, KLayout doesn’t provide built‑in waiver support (not sure).

@atorkmabrains, what would be the best approach here?

@sergeiandreyev
Copy link
Contributor

However, I noticed in the older implementation for V1.a was excluding transG2L from this check, and I also see a cntb.h1 violation in npn13G2, but those exclusions not mentioned in DRM.

Hi @stefansimon42, shall we review the DRM for any missing device-specific waivers? also that one #628

@sergeiandreyev
Copy link
Contributor

Hi @FaragElsayed2, could you please resolve the conflicts, then we will merge this PR

@atorkmabrains
Copy link
Contributor

@KrzysztofHerman @FaragElsayed2 is off today, will get it done soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants