Nuts and Bolts

The klayout Python Module

The klayout Python module is a side branch of the KLayout system. KLayout is a 2d viewer and editor for mask layouts used in chip manufacturing. It reads and writes GDS, OASIS, CIF, DXF and other formats including Gerber PCB files. It is capable of handling large files on the multi-GB scale with literally billions of polygons.

KLayout embeds a Ruby and Python interpreter and development environment. Scripting in KLayout acts as a high-level access layer to the analysis and processing functionality. This layer provides most of the relevant classes KLayout implements in C++.

The klayout Python package available on PyPI offers a subset of this API packaged as a lean, dependency-free binary distribution. This subset includes:

  • Geometry database (klayout.db submodule)
  • Utility classes (klayout.tl submodule)
  • Report database classes (klayout.rdb submodule)

Note: we’ll focus on klayout.db here as this is by far the most important module.

Compared to KLayout’s full functionality, the Python package lacks all user-interface related classes. This avoids a dependency to the heavy Qt library and related license issues. Still the Python package allows generating, manipulating and analyzing layout files. If you need KLayout’s full Python features as an external Python package, consider using the Python package which comes with KLayout itself - e.g. distributed with the Linux RPM or DEB packages. This package adds additional submodules like klayout.lay for the user interface components.

Sample

This simple example generates a small layout containing a single cell and some rectangles:

Result

Download GDS file

Code:

import klayout.db as db

ly = db.Layout()

# sets the database unit to 1 nm
ly.dbu = 0.001

# adds a single top cell
top_cell = ly.create_cell("SAMPLE")

# creates a new layer (layer number 1, datatype 0)
layer1 = ly.layer(1, 0)

pattern = """
.#...#.#......###..#...#..###..#...#.#####
.#..#..#.....#...#.#...#.#...#.#...#...#..
.#.#...#.....#...#.#...#.#...#.#...#...#..
.##....#.....#####..#.# .#...#.#...#...#..
.#.#...#.....#...#...#. .#...#.#...#...#..
.#..#..#.....#...#...#. .#...#.#...#...#..
.#...#.#####.#...#...#. ..###...###....#..
"""

# produces pixels from the bitmap as 0.5x0.5 µm
# boxes on a 1x1 µm grid:
y = 8.0
for line in pattern.split("\n"):

  x = 0.0
  for bit in line:

    if bit == "#":
      # creates a rectangle for the "on" pixel
      rect = db.DBox(0, 0, 0.5, 0.5).moved(x, y)
      top_cell.shapes(layer1).insert(rect)

    x += 1.0

  y -= 1.0

# adds an envelope box on layer 2/0
layer2 = ly.layer(2, 0)
envelope = top_cell.dbbox().enlarged(1.0, 1.0)
top_cell.shapes(layer2).insert(envelope)
  
# writes the layout to GDS
ly.write("basic.gds")