Skip to content

flow: KLayout Python module for GDS, DRC and LVS; deprecate Ruby decks; no KLayout application install - #4757

Open
oharboe wants to merge 10 commits into
The-OpenROAD-Project:masterfrom
oharboe:gds-pypi-klayout
Open

oharboe wants to merge 10 commits into
The-OpenROAD-Project:masterfrom
oharboe:gds-pypi-klayout

Conversation

@oharboe

@oharboe oharboe commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Before: the flow wrote GDS with the KLayout application, and make drc/make lvs ran Ruby rule decks that need the application.
Now: KLayout's Python module, pip install klayout, writes the GDS and runs every DRC and LVS deck ORFS uses (DRC: asap7, nangate45, sky130hd, ihp-sg13g2; LVS: sky130hd, ihp-sg13g2), rewritten in Python; Ruby decks are deprecated, and the installer installs the module only, not the KLayout application.

This continues and reframes the earlier version of this pull request, which dropped the KLayout application from the installer and wrote that DRC/LVS needed the application down as a permanent state. That gap is closed here instead: DRC and LVS run on the Python module, so the application is needed only for a deprecated Ruby deck, and whoever uses one installs it. (#4797, which removed the application install on its own, is folded in as the last commit.)

DRC and LVS decks in Python

KLayout ships no Ruby in the Python module (KLayout/klayout#1772); its DRC language is a thin layer over klayout.db's Region, Edges and EdgePairs (KLayout/klayout#1980). flow/util/klayout_drc.py is that layer for the operations ORFS's decks use, with the DRC language's arguments and defaults (_drc_layer.rb), and flow/util/klayout_lvs.py adds what the LVS language adds (_lvs_netter.rb). Each deck is the Ruby deck translated line by line, one platform per commit, and the Ruby deck is deleted in the same commit. make drc/make lvs run a deck ending in .py with PYTHON_EXE. Outputs keep their names: 6_drc.lyrdb, 6_drc_count.rpt, 6_lvs.lvsdb.

Each Python deck is checked, on the klayout module at 0.30.12 (the version the lock pins) and at 0.30.13 with identical results, against the Ruby deck run by the KLayout 0.30.0 application on the same GDS from ORFS's gcd on that platform, clean, and with shapes added outside the design that break a sample of rules. DRC: violations per category and the markers themselves; LVS: the match verdict and the cross-reference counts in the .lvsdb.

platform deck clean GDS, Ruby / Python seeded GDS, Ruby / Python seeded rules runtime, Ruby / Python
asap7 DRC 42 / 42 in 9 categories, same markers 64 / 64 in 17 categories, same markers width, spacing, via enclosure, gate width (universal drc), select 73 s / 55 s
nangate45 DRC, with antenna 0 / 0 8 / 8 in 8 categories, same markers width, spacing, via enclosure, poly, metal1 antenna 27 s / 2.6 s
sky130hd DRC 0 / 0 6 / 6 in 6 categories, same markers; FEOL rules on in both: 6 / 6 width, spacing, via without metal 4.2 s / 2.7 s
sky130hd LVS match / match; 496 devices, 1119 nets, 451 subcircuits matched in both short (a met1 bar across the core): no match / no match; 10 nets and 28 subcircuits mismatched in both connectivity 2.6 s / 0.8 s
ihp-sg13g2 DRC (sg13g2_minimal), with density 8 / 8 in 8 categories (global and 800 x 800 um density), same markers 24 / 24 in 20 categories, same markers width, spacing with a corner touch, via and contact size, pin outside metal, density 4.3 s / 2.6 s
ihp-sg13g2 LVS match / match; 36 circuits, 232 devices, 837 nets, 239 pins, 1764 subcircuits matched in both short (a Metal3 bar between req_msg[12] and req_msg[9]): no match / no match; the same 2 nets and 1 subcircuit mismatched, the merged net named req_msg[12],req_msg[9] connectivity, devices 7.3 s / 3.9 s

Also in these commits:

  • nangate45 no longer sets KLAYOUT_LVS_FILE: it named lvs/FreePDK45.lylvs, which does not exist, so make lvs now says LVS is not supported instead of failing on a missing file.
  • RBA::CellView::active, which only the application has, is gone with the Ruby decks: the asap7 and sky130hd DRC decks used it when no report file was given, the sky130hd LVS deck to place its extracted netlist (the .lvsdb holds that netlist), the ihp deck for its file dialog.
  • In the sky130hd DRC deck, if backend_flow = CU assigns rather than compares, so its copper-only rules never ran; the Python deck keeps that (CU = False).
  • The sky130hd LVS .lvsdb from Python lists the same device abstracts as the Ruby one, in a different order.
  • ihp-sg13g2's Ruby LVS deck never ran in ORFS: KLAYOUT_LVS_FILE was commented out and named a file that does not exist, the deck read -rd input=/schematic=/topcell=/report= where make lvs passes in_gds=/cdl_file=/top_cell=/report_file=, and run by hand it said "no match" on gcd because the CDL from cdl.tcl leaves out the decap cells, which have transistors (1231 instances). The Python deck takes make lvs's arguments, cdl.tcl now writes the CDL with write_cdl -include_fillers, and ihp-sg13g2 sets KLAYOUT_LVS_FILE. With that CDL both decks match; sky130hd LVS still matches. The -include_fillers change reaches every platform's CDL.
  • The ihp-sg13g2 Ruby LVS runset is deleted with its replacement: sg13g2.lvs, the 39 rule_decks/*.lvs files and run_lvs.py, which only drove it. IHP's vendoring script (sg13g2_update.py) never fetched them.
  • flow/test/test_klayout_drc.py checks width, space, enclosure, a universal drc check, area filters and deep against flat reporting on a generated layout; it is skipped without the klayout module.

Ruby decks: deprecated

A .lydrc/.lylvs deck, on a platform outside this repository for one, still runs through the KLayout application, and make drc/make lvs warn:

WARNING: <deck> is a Ruby KLayout deck; Ruby decks are deprecated and need a KLayout application you install yourself, see docs/user/KLayoutPythonDecks.md

There is no schedule for removing Ruby support; that is up to the maintainers. docs/user/KLayoutPythonDecks.md says how to convert a deck, with ORFS's decks as worked examples. flow/util/klayout_compare_decks.py runs a Ruby deck and its translation on one GDS file and compares the violations per category, count and markers, as ORFS's decks were checked; on asap7 gcd it reports the Ruby and Python decks the same.

GDS via the Python module

def2stream.py merges the GDS file with the module, run by PYTHON_EXE; it already used only klayout.db calls, and gets a command line. The module is a prebuilt wheel, with no Qt and nothing to compile, for Python 3.10 and up on Linux (x86_64 and aarch64, glibc 2.27 and up) and macOS, added to etc/requirements-common.in and pinned at 0.30.12 in the lock, the version the installer installs. Without the module the merge stops, exit status 1, no file written:

ERROR: the klayout Python module is not installed, pip install klayout (etc/requirements-common_lock.txt)
sky130hd lb_32x128, make do-gds KLayout Python module 0.30.12 KLayout application 0.30.0
layout identical (LayoutDiff, 12 cells) identical
bytes that differ 26, the GDS timestamps
wall time, peak memory (one run) 0.34 s, 101 MB 1.36 s, 403 MB

Installer: no KLayout application

etc/DependencyInstaller.sh loses its KLayout install for every OS; the module comes in with the other Python packages. Deleted:

  • klayoutVersion and the version-check-and-reinstall logic, written three times (CentOS 7, CentOS 8, Rocky Linux 9) around klayout.org RPMs.
  • On Ubuntu x86_64: the klayout.org .deb download, its md5 table per release, and the "Unsupported Ubuntu version" exit, so KLayout's packaging no longer limits which Ubuntu releases the installer supports.
  • On Ubuntu aarch64: the build of KLayout from source, with its Qt, Ruby and libgit2 build dependencies, the slowest step of a fresh aarch64 install.
  • klayout from apt on rodete, and the Homebrew cask on macOS.
  • env.sh: the KLayout.app PATH entry on macOS.
  • flow/scripts/variables.mk: the lookup of a KLayout in tools/install/klayout, which nothing installs. KLAYOUT_CMD is the klayout on PATH unless set, looked up once (command -v klayout runs 21 times for make -n clean_all on asap7/gcd, as on master).
  • docs/user/BuildWithPrebuilt.md: the KLayout version note and the LD_LIBRARY_PATH line for a KLayout built from source.

A deprecated Ruby deck, the gallery and the viewers still need the KLayout application, installed by whoever uses them; without it they stop at check-klayout, as on master.

Dogs left lying

  • flow/scripts/klayout/src and test (14 Ruby files): a bring-up tool that generates KLayout tech and layer files from a Cadence Virtuoso tech file. Nothing in the repository runs or references it; it is left as it is.
  • ihp-sg13g2's full DRC deck, sg13g2_maximal.lydrc, which no flow uses, is deleted rather than converted: ORFS runs sg13g2_minimal, and converting IHP's full deck is IHP's to do in its own repository.

Commits

  1. flow: write the GDS file with the klayout Python module
  2. to 7. One deck per platform: asap7 DRC, nangate45 DRC, sky130hd DRC, sky130hd LVS, ihp-sg13g2 DRC, ihp-sg13g2 LVS.
  3. ihp-sg13g2: delete the unused Ruby DRC deck sg13g2_maximal.lydrc
  4. flow: deprecate Ruby KLayout decks
  5. installer: no KLayout application

Tests

  • flow/test/test_def2stream.py checks that the module gets the arguments, and that without it the merge exits with status 1, prints the error and writes no file. flow/test/test_klayout_sh.py checks that klayout.sh stops without the KLayout application and passes a call through unchanged with it. Both pass (25 tests).
  • The deck equivalence table above; klayout_compare_decks.py on asap7 gcd: same.
  • make -n shows the deprecation warning for a .lydrc deck and none for a .py deck.
  • black 26.10.1 (the CI version) clean on every commit.
  • Not run: the wrapped-macro merge (WRAP_LEFS), which only gf12 designs use. It calls the same script with the same arguments as before.

🤖 Generated with Claude Code

https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the flow to make KLayout an optional dependency by utilizing the klayout Python module for GDS/OAS stream generation, falling back to mocking (writing an empty file with a warning) when KLayout is entirely missing. It updates dependency installers, Makefiles, and documentation to reflect this change, and adds corresponding unit tests. The review feedback correctly identifies a critical issue in flow/util/def2stream.py where a subprocess version check could cause an unnecessary hard failure, and points out that the custom environment dictionary is not being forwarded to the spawned subprocesses.

Comment thread flow/util/def2stream.py Resolved
@oharboe

oharboe commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator Author

@maliberty @eder-matheus @vvbandeira TL;DR klayout has been a thorny dependency and it confuses users

This is intended to prune as much as possible from ORFS install scripts, etc. while giving each use-case the least chafing experience.

We try PyPi klayout first, then local and finally we write an empty .gds file and a warning.

The full klayout install is still needed for make lvs/drc and gallery, but I think those are out of the way for most users and PyPi klayout doesn't have ruby, so there's nothing for it, full klayout install is needed. This would be solved by documentation, this is an out of the way use-case you have to install klayout yourself.

@openroad-ci

openroad-ci commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 161cd23 · Jenkins build #17 · Baseline: build · View build on dashboard

62 design(s) checked — 0 with regression(s), 0 without a comparable baseline.

@oharboe oharboe changed the title Write the GDS file with KLayout's Python module; the installer drops the KLayout application Delete the KLayout application install and the aarch64 KLayout source build; KLayout's Python module writes the GDS file Oct 29, 2026
@oharboe
oharboe requested a review from maliberty November 2, 2026 17:16
@oharboe
oharboe marked this pull request as ready for review November 2, 2026 17:17
@oharboe
oharboe requested a review from a team as a code owner November 2, 2026 17:17
@oharboe
oharboe marked this pull request as draft November 4, 2026 10:03
@oharboe
oharboe marked this pull request as ready for review November 4, 2026 14:31
@oharboe
oharboe requested review from vvbandeira and removed request for maliberty November 4, 2026 18:08
Comment thread flow/docs/KLayoutOptionalDependency.md Outdated
Comment on lines +15 to +19
DRC, LVS, the gallery and the viewers need the KLayout application,
which you install yourself: [KLayout](https://www.klayout.de/build.html).
The DRC and LVS rule decks are scripts in KLayout's Ruby-based DSL,
which the Python module does not include. None of them runs in the
default `make`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is arguably a gap that should be fixed rather than a status we should enshrine. I like the simplification but not at the expense of having the possibility of DRC/LVS in the future.

@maliberty maliberty closed this Nov 6, 2026
@oharboe oharboe reopened this Nov 6, 2026
@oharboe
oharboe marked this pull request as draft November 6, 2026 06:43
@oharboe

oharboe commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator Author

Reopened to close the gap rather than document it: the Ruby DRC/LVS decks get rewritten in Python on the PyPI klayout module (klayout.db Region checks, TilingProcessor for density, LayoutVsSchematic for LVS), one platform per commit. Each Python deck is checked against the Ruby deck's violations on the same GDS. Upstream KLayout ships no Ruby in the PyPI module (KLayout/klayout#1772) and points to plain Python over Region for this (KLayout/klayout#1980). Draft until the decks are in.

oharboe and others added 6 commits November 6, 2026 10:01
def2stream.py merges the GDS file with the klayout Python module from
pip (etc/requirements-common), run by PYTHON_EXE, instead of under the
KLayout application (klayout -zz -r def2stream.py). The script already
used only klayout.db calls; it gets a command line. Without the module
it stops with an error and writes no file.

The GDS merge no longer depends on check-klayout. DRC and LVS still run
the KLayout application, so they depend on check-klayout directly.

The wrapped-macro merge passed `-rd config_file=$(FILL_CONFIG)`, which
def2stream.py never read; it is not passed any more.

test_def2stream.py checks the module path and the error without it;
test_klayout_sh.py checks that klayout.sh still stops without KLayout
and passes a call through unchanged with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, make drc on asap7 needed the KLayout application to run the
Ruby deck asap7.lydrc. Now it runs asap7_drc.py with the klayout
Python module that already writes the GDS.

flow/util/klayout_drc.py is the thin layer KLayout's DRC language is
over klayout.db (KLayout/klayout#1980), for the operations ORFS's decks
use: each method calls Region, Edges or EdgePairs with the arguments
and defaults of _drc_layer.rb, values in microns as floats and in
database units as ints, deep mode on a DeepShapeStore, and the report
written with rdb's scan_collection into the .lyrdb that make drc
counts. The deck is the Ruby deck translated line by line.

make drc runs a deck ending in .py with PYTHON_EXE; a .lydrc deck still
goes to the KLayout application. RBA::CellView::active, which only the
application has, is gone with the Ruby deck: the report file is always
given.

Checked against the Ruby deck run by the KLayout 0.30.0 application on
the same asap7/gcd GDS, Python on klayout 0.30.13:

  clean GDS:  42 violations in 9 categories, both, same markers
  seeded GDS: 64 violations in 17 categories, both, same markers
              (narrow M1/M2, V1 spacing and enclosure, GATE width,
              ACTIVE without select)
  runtime:    73 s Ruby, 55 s Python

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, make drc on nangate45 needed the KLayout application to run
FreePDK45.lydrc, and KLAYOUT_LVS_FILE named lvs/FreePDK45.lylvs, which
does not exist. Now make drc runs FreePDK45_drc.py on the klayout
Python module, and nangate45 sets no LVS deck: make lvs says LVS is not
supported on this platform instead of failing on a missing file.

The antenna checks go through LayoutToNetlist as the DRC language's
connect and antenna_check do: the layers registered on the deep shape
store, connected, the netlist extracted once and antenna_check called
with the diode layer.

Checked against the Ruby deck run by the KLayout 0.30.0 application on
the same nangate45/gcd GDS, Python on klayout 0.30.13:

  clean GDS:  0 violations, both
  seeded GDS: 8 violations in 8 categories, both, same markers
              (narrow and close metal1, narrow metal2 and poly, via1
              without enclosure, ACTIVE.4, a metal1 antenna)
  runtime:    27 s Ruby, 2.6 s Python

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, make drc on sky130hd needed the KLayout application to run
sky130hd.lydrc. Now it runs sky130hd_drc.py on the klayout Python
module.

The Ruby deck's "if backend_flow = CU" blocks are assignments, not
comparisons: with CU false they never run and the AL blocks always do.
The Python deck says that with one CU = False. Its FEOL rules stay off
as before; the cell selections (source.select) are a Source in
klayout_drc.py with the same select/unselect order on the shape
iterator. The deck's area(layer) is the layer's area in square
microns, as the DRC language's.

Checked against the Ruby deck run by the KLayout 0.30.0 application on
the same sky130hd/gcd GDS, Python on klayout 0.30.13:

  clean GDS:  0 violations, both
  seeded GDS: 6 violations in 6 categories, both, same markers
              (narrow and close m1, narrow li and m2, via without
              metal)
  FEOL on in both decks, seeded GDS: 6 and 6, same markers
  runtime:    4.2 s Ruby, 2.7 s Python (FEOL on: 177 s, 162 s)

sky130hd has no density rules in its deck; the tiled density checks
are in ihp-sg13g2's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, make lvs on sky130hd needed the KLayout application to run
sky130hd.lylvs. Now it runs sky130hd_lvs.py on the klayout Python
module.

flow/util/klayout_lvs.py is what the LVS language adds to the DRC
language (_lvs_netter.rb), for what this deck uses: mos4 device
extraction with the layers registered in sorted terminal order, the
CDL schematic, connect_global, device scaling, split_gates and
tolerance applied once the netlist is extracted, same_circuits and
equivalent_pins applied to each NetlistComparer when it is made, align,
compare, and the short-format .lvsdb. The deck's schematic and netlist
edits (0-ohm ties in CONB_1, the stack merges, the VNB/VSS tie) are the
Ruby functions in Python; nets are keyed by name, as the Ruby deck
does, since the binding hands back a new wrapper on each lookup.

The Ruby deck wrote the extracted netlist next to
RBA::CellView::active, which only the application has; the Python deck
writes the .lvsdb only, which holds the extracted netlist.

Checked against the Ruby deck run by the KLayout 0.30.0 application on
the same sky130hd/gcd GDS and CDL, Python on klayout 0.30.13, comparing
the cross references in the two .lvsdb files:

  clean GDS:   match, both: 59 circuits, 496 devices, 1119 nets,
               931 pins, 451 subcircuits matched, both
  shorted GDS: no match, both (a met1 bar across the core): 1 circuit,
               10 nets and 28 subcircuits mismatched, the rest matched,
               the same counts in both
  runtime:     2.6 s Ruby, 0.8 s Python

The device abstracts are the same set in both .lvsdb files, in a
different order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, make drc on ihp-sg13g2 needed the KLayout application to run
sg13g2_minimal.lydrc. Now it runs sg13g2_minimal_drc.py on the klayout
Python module.

The Ruby deck adds ext_* methods to the DRC language's layer; the
Python deck adds the same functions to klayout_drc.Layer, line by line:
the space, width and separation checks with their touch-point and
intersecting-edge handling (EdgePairOperator subclasses as in Ruby),
the rectangle and square filters as universal DRC expressions
(CompoundRegionOperationNode), and the global and 800 x 800 um density
windows. klayout_drc.py gets what these need from the DRC language:
with_density/without_density on a TilingProcessor with the same
expression script, tile options, padding_ignore, labels and texts,
raw, merge, dup, select_inside, with_distance, sizing modes and the
ortho edge filter.

What only the application had is gone: the file dialog and
RBA::CellView::active when no GDS is given (make drc always gives
one), and the -rd variables log_file, cell, threads and densityRules,
which the Makefile never set; density rules stay on and the deck runs
single-threaded, as before.

Checked against the Ruby deck run by the KLayout 0.30.0 application on
the same ihp-sg13g2/gcd GDS, Python on klayout 0.30.13:

  clean GDS:  8 violations in 8 categories (global and windowed
              density), both, same markers
  seeded GDS: 24 violations in 20 categories, both, same markers
              (narrow and close Metal1, narrow Metal2, GatPoly,
              Activ and TopMetal1, Via1 of the wrong size, Cont
              spacing with a corner touch, GatPoly spacing, a Metal1
              pin outside Metal1, and density)
  runtime:    4.3 s Ruby, 2.6 s Python

sg13g2_maximal.lydrc, which no flow uses, and the commented-out LVS
deck stay as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe oharboe changed the title Delete the KLayout application install and the aarch64 KLayout source build; KLayout's Python module writes the GDS file flow: KLayout Python module for GDS, DRC and LVS; deprecate Ruby decks Nov 6, 2026
@oharboe
oharboe force-pushed the gds-pypi-klayout branch 2 times, most recently from 309fe85 to 63c807e Compare November 6, 2026 10:08
@oharboe oharboe changed the title flow: KLayout Python module for GDS, DRC and LVS; deprecate Ruby decks flow: KLayout Python module for GDS, DRC and LVS; deprecate Ruby decks; no KLayout application install Nov 6, 2026
oharboe and others added 4 commits November 6, 2026 11:43
Before, ihp-sg13g2 had IHP's Ruby LVS runset (sg13g2.lvs, 39 rule_decks/
files and its driver run_lvs.py), and make lvs did not run it. Now make
lvs runs sg13g2_lvs.py on the klayout Python module, and gcd matches.

What was broken: the runset never ran in ORFS.

- config.mk had KLAYOUT_LVS_FILE commented out, naming
  $(PLATFORM).lylvs, a file that does not exist.
- The runset reads -rd input=, schematic=, topcell= and report=; make
  lvs passes in_gds=, cdl_file=, top_cell= and report_file=, so run as
  make would, it stops at once: "'source': No layout loaded".
- Given its own variables, it runs, and reports no match on gcd: the
  CDL from cdl.tcl leaves out the physical-only cells, and
  sg13g2_decap_4/8 have transistors, so 1231 decap instances in the
  layout have no schematic counterpart. cdl.tcl now writes the CDL with
  write_cdl -include_fillers. sky130hd's LVS still matches with it.

sg13g2_lvs.py is the runset translated line by line, in include order:
the layer definitions and derivations on klayout_drc.Layer, the
connections, and the device extraction; the runset's Ruby classes as the
klayout.db classes of the same names: the SPICE reader delegate (its
error fallbacks through super()), the device classes, the device
combiners, and the GenericDeviceExtractor subclasses for resistors,
varactors, inductors and MIM capacitors. The switches are run_lvs.py's
defaults (deep mode, simplify, series and parallel resistors combined).
Kept as the Ruby does it: a Metrics::Projection passed as the second
positional argument of space_check and notch_check is whole_edges, and
the reader deletes [, ], $ and / from element lines. The extracted
netlist (target_netlist and its SPICE writer) is not written; the
.lvsdb holds it, as for sky130hd.

klayout_drc.py gets extent(cell_filter), middle, with_bbox_max and
connect for text layers; klayout_lvs.py gets bjt3, bjt4, diode and
resistor extractors with a device class, a schematic reader, max_res and
min_caps.

Checked against the Ruby runset run by the KLayout 0.30.0 application on
the same ihp-sg13g2/gcd GDS and CDL (with the decaps), Python on klayout
0.30.12 and 0.30.13, comparing the cross references in the .lvsdb files:

  clean GDS:   match, all: 36 circuits, 232 devices, 837 nets, 239 pins
               and 1764 subcircuits matched
  shorted GDS: no match, all (a Metal3 bar between the pins req_msg[12]
               and req_msg[9]): gcd, 2 nets and 1 subcircuit mismatched,
               the layout net named "req_msg[12],req_msg[9]"; the rest
               matched, the same counts in all
  CDL without the decaps: no match, all, 1231 subcircuits and VDD and
               VSS mismatched
  runtime:     7.3 s Ruby, 3.9 s Python

The extracted netlists are the same in the Python deck run in the 0.30.0
application and the Ruby runset, but for the pin order of two circuits
and the numbers of unnamed nets. Between 0.30.0, 0.30.12 and 0.30.13 the
split of the source/drain areas (AS, AD) of combined multi-finger
transistors differs; LVS does not compare them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Before, ihp-sg13g2 carried sg13g2_maximal.lydrc, a Ruby deck no flow
runs. Now it is gone.

No flow sets KLAYOUT_DRC_FILE to it; sg13g2_minimal_drc.py is the deck
ORFS runs. IHP's own repository keeps the full deck. sg13g2_update.py
does not fetch it: its download line is commented out, since IHP
replaced the minimal and maximal decks with a parameterizable
sg13g2.drc. test_klayout_sh.py named it only as an argument to
klayout.sh, which stops before reading it; the test now names a
generic deck.lydrc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Every deck ORFS runs is now Python on the klayout module. A deck in
KLayout's Ruby DRC language, a platform outside ORFS for one, still runs
through the KLayout application, and make drc / make lvs say it is
deprecated:

  WARNING: <deck> is a Ruby KLayout deck; Ruby decks are deprecated and
  need a KLayout application you install yourself, see
  docs/user/KLayoutPythonDecks.md

There is no schedule for removing Ruby support; that is up to the ORFS
maintainers.

docs/user/KLayoutPythonDecks.md says how to convert a deck, with ORFS's
decks as worked examples. flow/util/klayout_compare_decks.py runs a Ruby
deck and its translation on one GDS file and compares the violations,
count and markers per category, as the conversion of ORFS's decks was
checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
The flow writes its GDS file and runs its DRC and LVS decks with
KLayout's Python module, from the installer's Python packages, so the
installer no longer installs the KLayout application.

Deleted:

- etc/DependencyInstaller.sh: klayoutVersion, and the KLayout install
  for each OS: the CentOS 7, CentOS 8 and Rocky Linux 9 RPMs with their
  version check and reinstall, the Ubuntu .deb with its md5 table per
  release and the "Unsupported Ubuntu version" exit, the build from
  source on Ubuntu aarch64 with its Qt, Ruby and libgit2 build
  dependencies, `klayout` from apt on rodete and the Homebrew cask on
  macOS.
- env.sh: the KLayout.app PATH entry on macOS.
- flow/scripts/variables.mk: the lookup of a KLayout built into
  tools/install/klayout, which nothing installs. KLAYOUT_CMD is the
  klayout on PATH unless set, and is exported bare.
- docs/user/BuildWithPrebuilt.md: the KLayout version note and the
  LD_LIBRARY_PATH line for a KLayout built from source.

A deprecated Ruby DRC/LVS deck, the gallery and the viewers still need
the KLayout application, installed by those who use them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PFLaCzFtFbnWE4nPTDwpC
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from maliberty November 6, 2026 10:49
@oharboe

oharboe commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator Author

@maliberty Rewrote ruby to python, klayout only needed for those designs(confidential/users) that still use Ruby. My thinking is they can install klayout themselves and ORFS can drop klayout install. I don't have any opinion on the deprecation period.

@oharboe
oharboe marked this pull request as ready for review November 6, 2026 10:50
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.

3 participants