KLayout-PEX Documentation

Author
Affiliation

Martin Köhler

Published

March 23, 2025

1 Introduction

1.1 Motivation

In Electronic Design and Automation (EDA) for Integrated Circuits (ICs), a schematic presents an abstraction in comparison to the layout that will eventually be taped-out and fabricated by the semiconductor foundry.

While in the schematic, a connection between device terminals is seen as an equipotential, the stacked geometries in a specific layout introduce parasitic effects, which can be thought of additional resistors, capacitors (and inductors), not modeled by and missing in the original schematic.

To be able to simulate these effects, a parasitic extraction tool (PEX) is used, to extract a netlist from the layout, which represents the original schematic (created from the layout active and passive elements) augmented with the additional parasitic devices.

1.2 Acknowledgements

Special thanks to the public funded German project FMD-QNC (16ME0831) https://www.elektronikforschung.de/projekte/fmd-qnc for financial support to this work.

1.3 About KLayout-PEX

KLayout is an open source VLSI layout viewer and editor.

KLayout-PEX (short KPEX) is a PEX tool, well integrated with KLayout by using its API.

There are multiple PEX engines supported, currently:

  • FasterCap integration (field solver engine)
  • MAGIC integration (wrapper calling magic)
  • Analytical 2.5D engine (parasitic concepts and formulas of MAGIC, implemented using KLayout methods)
Tip

KPEX tool source code itself is made publicly available on GitHub (follow this link) and shared under the GPL-3.0 license.

KPEX documentation source code is made publicly available on GitHub (follow this link) and shared under the Apache-2.0 license.

Please feel free to create issues and/or submit pull requests on GitHub to fix errors and omissions!

The production of the tool and this document would be impossible without these (and many more) great open-source software products: KLayout, FasterCap, MAGIC, protobuf, Quarto, Python, ngspice, Numpy, Scipy, Matplotlib, Git, Docker, Ubuntu, Linux

Caution

Currently, KPEX is developed as a Python prototype, using the KLayout Python API. This allows for a faster development cycle during the current prototyping phase.

Eventually, critical parts will be re-implemented (in C++, and parallelized), to improve performance. As we’re already using the KLayout API (which is pretty similar between Python, Ruby and C++), this will be relatively straight-forward.

1.4 Status

Warning

Please keep in mind that this software is early stage, and not yet intended for production use.

Engine PEX Type Status Description
KPEX/MAGIC CC, RC Usable Wrapper engine, using installed magic tool
KPEX/FasterCap CC Usable, pending QA Field solver engine using FasterCap
KPEX/FastHenry2 R, L Planned Field solver engine using FastHenry2
KPEX/2.5D CC Under construction Prototype engine implementing MAGIC concepts/formulas with KLayout means
KPEX/2.5D R, RC Planned Prototype engine implementing MAGIC concepts/formulas with KLayout means

1.5 Installation

Generally, KPEX is deployed using PyPi (Python Package Index), install via:

pip3 install --upgrade klayout-pex

kpex --version   # check the installed version 
kpex --help      # this will help with command line arguments

As for the dependencies, there are multiple options available.

1.5.1 Option 1: Using IIC-OSIC-TOOLS Docker Image

We provide a comprehensive, low entry barrier Docker image that comes pre-installed with most relevant open source ASIC tools, as well as the open PDKs. This is a pre-compiled Docker image which allows to do circuit design on a virtual machine on virtually any type of computing equipment (personal PC, Raspberry Pi, cloud server) on various operating systems (Windows, macOS, Linux).

For further information please look at the Docker Hub page and for detailed instructions at the IIC-OSIC-TOOLS GitHub page.

Linux

In this document, we assume that users have a basic knowledge of Linux and how to operate it using the terminal (shell). If you are not yet familiar with Linux (which is basically a must when doing integrated circuit design as many tools are only available on Linux), then please check out a Linux introductory course or tutorial online, there are many resources available.

A summary of important Linux shell commands is provided in IIC-JKU Linux Cheatsheet.

1.5.2 Option 2: Standalone Installation

1.5.3 Useful tools: meshlab

For previewing generated 3D geometries, representing the input to FasterCap, we recommend installing MeshLab. The generated STL-files are located at output/<design>/Geometries/*.stl.

2 First Steps

  • The command line tool kpex is used to trigger the parasitic extraction flow from the terminal.
  • Get help calling kpex --help.

2.1 Example Layouts

Example layouts are included in the testdata/designs subdirectory of the KLayout-PEX source code:

git clone https://github.com/martinjankoehler/klayout-pex.git 

# for sky130A
find testdata/designs/sky130A -name "*.gds.gz"

# for IHP SG13G2
find testdata/designs/ihp_sg13g2 -name "*.gds.gz"

2.2 Running the KPEX/FasterCap engine

Preconditions:

Note

Normally, devices with SPICE (Nagel 1975) simulation models (e.g. like MOM-capacitors1 in the sky130A PDK) are ignored (“blackboxed”) during parasitic extraction.

kpex has an option --blacklist n to allow extraction of those devices (whiteboxing), which can be useful during development (during the prototype phase, whiteboxing is actually the default setting, so please use --blacklist y to explicitly configure blackboxing).

Let’s try the following:

kpex --pdk sky130A --blackbox n --gds \
  testdata/designs/sky130A/*/cap_vpp_04p4x04p6_l1m1m2_noshield.gds.gz
Note

This will report an error that we have not activated one or more engines, and list the available engines:

Argument Description
--fastercap Run kpex/FasterCap engine
--2.5D Run kpex/2.5D engine
--magic Run MAGIC engine

Now, to run the FasterCap engine (might take a couple of minutes):

kpex --pdk sky130A --blackbox n --fastercap --gds \
  testdata/designs/sky130A/*/cap_vpp_04p4x04p6_l1m1m2_noshield.gds.gz

Within the output directory (defaults to output), KPEX creates a subdirectory Geometries, containing STL-files that provide a preview of the FasterCap input geometries. Use MeshLab (see Section 1.5.3) to open and preview those files:

ls -d output/cap_vpp_04*/Geometries/*.stl
Tip
  • Open the *.stl files in MeshLab
  • Use the eye buttons to hide and show each file/mesh
  • Use the align tool (“A” in the toolbar) to assign different colors
  • Start by showing only on the conductors (files named cond_*.stl)
  • Then try showing different dielectrics (files named diel_*.stl), to see how they surround the conductors.

MOM Capacitor 3D Model

In the log file, we see the output of FasterCap including the Maxwell capacitance matrix:

Capacitance matrix is:
Dimension 3 x 3
g1_VSUBS  5.2959e-09 -4.46971e-10 -1.67304e-09
g2_C1  -5.56106e-10 1.5383e-08 -1.47213e-08
g3_C0  -1.69838e-09 -1.48846e-08 1.64502e-08

KPEX interprets this matrix and prints a CSV netlist, which can be pasted into a spreadsheet application:

Device;Net1;Net2;Capacitance [fF]
Cext_0_1;VSUBS;C1;0.5
Cext_0_2;VSUBS;C0;1.69
Cext_1_2;C1;C0;14.8
Cext_1_1;C1;VSUBS;0.08

In addition, a SPICE netlist is generated.

2.3 Running the KPEX/MAGIC engine

Preconditions:

The magic section of kpex --help describes the arguments and their defaults. Important arguments:

  • --magicrc: specify location of the magicrc file
  • --gds: path to the GDS input layout
  • --magic: enable magic engine
kpex --pdk sky130A --magic --gds \
  testdata/designs/sky130A/*/cap_vpp_04p4x04p6_l1m1m2_noshield.gds.gz

3 Supporting new PDKs

For every supported PDK, a KPEX technology definition is required, as well as customized PEX-“LVS” scripts.

3.1 Technology Definition Files

The KPEX technology definition format uses Google Protocol Buffers, so there is:

  • formal schema files, defining the structure and data types involved
  • multiple concrete instantiations, that adhere to this schema (called messages in the protobuf lingo)
    • in the form of JSON files
    • Skywater 130A: klayout_pex_protobuf/sky130A_tech.pb.json
    • IHP SG13G2: klayout_pex_protobuf/ihp_sg13g2_tech.pb.json
Note

The built-in JSON tech files are programmatically generated during the build process2. Therefore they not part of the repository source code, but of course part of the deployed Python wheels. To review those, look into your Python site-packages3/klayout_pex_protobuf.

3.2 Customized PEX-“LVS” scripts

KLayout has built-in support for Layout-Versus-Schematic (LVS) scripts, based on its Ruby API. Customized “LVS” scripts are (“ab”)used in KPEX, not with the intent of comparing Layout-Versus-Schematic, but rather to extract the connectivity/net information for all polygons across multiple layers. The resulting net information is stored in a KLayout LVS Database (“LVSDB”).

KPEX Net Formation

These customized “LVS” scripts are stored in:

What’s specific about this customization:

The layer names in the script must correspond with the names configured in the tech JSON file.

4 KPEX/FasterCap Engine

FasterCap is a 3D and 2D parallel capacitance field solver, inspired by FastCap2. https://www.fastfieldsolvers.com/fastercap.htm

Starting from an input layout (e.g. GDS file) and a process stack-up (part of the Section 3.1), KPEX creates input geometries for FasterCap. After running FasterCap, the Maxwell capacitance matrix is parsed and interpreted to obtain the parasitic capacitances.

See Section 2.2 to get started with a first extraction example.

KPEX/FasterCap Engine

4.1 3D Input Geometries

FasterCap 3D Input: File System Overview

The FasterCap input files and their format is documented in (Di Lorenzo 2019), a PDF version of the Windows-specific *.chm file is available at https://github.com/martinjankoehler/FasterCap/tree/master/doc/pdf.

KPEX generates 3D input geometries:

  • *.lst file: Main input file
    • defines dielectric instances
    • defines conductor instances
    • each instance refers to a *.geo file
  • *.geo files: Defines single geometry
    • defines shapes (e.g. triangles)
    • Each shape has a reference point to define inside/outsides

FasterCap 3D Input: File Format

4.2 Example: MOM Capacitor

MOM Capacitor: GDS Layout

MOM Capacitor: MeshLab 3D Preview
Figure 1: MOM Capacitor

Figure 1 depicts the MOM capacitor example of a from Section 2.2).

The corresponding schematic representation of Figure 2 contains 3 conductors (\(N_1\), \(N_2\) and \(N_3\)), and coupling capacitances:

  • Capacitances between conductors: \(C_{ij} \text{ where } i \ne j\)
    • \(C_{23}\) is the capacitance “intended” by the MOM designer
  • Capacitances between conductors and ground: \(C_{ii}\)
Figure 2: Schematic representation of the MOM capacitor.

4.3 Output Maxwell Capacitance Matrix

A Maxwell capacitance matrix (Maxwell 1873) provides the relation between voltages on a set of conductors and the charges on these conductors, as described by the FasterCap author in the white paper (Di Lorenzo 2023).

FasterCap log output prints the Maxwell capacitance matrix (one for each iteration/refinement).

FasterCap Log Output: Maxwell Capacitance Matrix
  • Matrix Properties:
    • Scaling: units have to be divided by \(10^{-6}\)
    • rows and columns are the same (list of net names)
    • Row Cells:
      • off diagonals cells contains the coupling between row/col nets (times \(-1\))
      • diagonal cells contains the sum of the absolute values of all other cells in the row
    • Matrix Symmetry:
      • in theory (ideal world), the matrix would be symmetric
      • in practice it’s not
      • therefore FastCap2 did average the off-diagonals
      • FasterCap does not average, so it’s done as part of KPEX

FasterCap Maxwell Capacitance Matrix: Interpretation

5 KPEX/MAGIC Engine

This engine is merely just a wrapper around magic, which prepares a TCL script that opens the layout file and starts MAGIC’s PEX flow. See Section 2.3 to get started with a first extraction example.

The following chapter will illustrate concepts of the parasitic extraction done in MAGIC, also motivated by the fact that the engine in Section 6 will be based on those. Major parts of this illustration, the figures and concepts are based on work done by MAGIC maintainer Tim Edwards, especially his talk from FSiC conference 2022 (Edwards 2022) and a (conceptual follow-up) ChipsAlliance meeting on April 4, 2023, see (Edwards 2023b) and (Edwards 2023a). In addition, code review and debugging of the MAGIC codebase was performed.

5.1 MAGIC database units

  • To convert between MAGIC database units and \(\mu m\), a scaling factor \(\alpha\) is used, so that \(L_{\mu m} = \frac{L_{dbu}}{\alpha}\)
  • E.g. for sky130A, \(\alpha = 200.0\)

5.2 Types of Parasitic Capacitances

MAGIC models multiple types of capacitances:

  • Substrate Overlap: Overlap area of a metal with the substrate
  • Substrate Fringing: Sidewall of a metal fringes out to substrate
  • Sidewall Capacitance: Coupling between adjacent sidewalls on the same layer
  • Overlap Capacitance: Overlap on different metal layers
  • Fringe Capacitance (“Side Overlap”): Sidewall of a metal fringes out other metal layers

5.3 Substrate Capacitance

  • Overlapping area: \[ C_{area} = \frac{\epsilon_{si} * K}{d} * \text{area} \,\,\,\,\,\,\, \left[ \frac{F}{\mu m^2} * \mu m^2\right] \]

  • Fringe (“Perimeter”): \[ C_{fringe\,to\,substrate} = \text{perimeter} * C_{perim} = (2l + 2w)*C_{perim} \]

  • Coefficients like \(C_{perim}\) are part of the tech files (Parasitic Tables)

5.4 Sidewall Capacitance

\[ C_{sidewall} = \frac{\epsilon_{si} * K}{s} * \text{sidewall area} \,\,\,\,\,\,\, \left[ \frac{F}{\mu m^2} * \mu m^2\right] \] \[ \,\,\,\,\,\,\,\,\,\,= \frac{\epsilon_{si} * K}{s} * t * l \,\,\,\,\,\,\, \left[ \frac{F}{\mu m^2} * \mu m * \mu m\right] \] \[ C_{sidewall} = \frac{C_{sidewall\,coeff}}{s} * l \,\,\,\,\,\,\, \left[ \frac{F}{\mu m} * \mu m\right] \]

  • Coefficients are part of the tech files (Parasitic Tables)
  • Layer thickness \(t\) is normally multiplied into the coefficient
  • Foundry tables give constant coefficient referenced to \(s = 1\)

5.5 Overlap Capacitance

  • Overlapping area: \[ C_{area} = \frac{\epsilon_{si} * K}{d} * \text{area} \,\,\,\,\,\,\, \left[ \frac{F}{\mu m^2} * \mu m^2\right] \]

Overlap Capacitance

5.6 Fringe Capacitance

Fringe Capacitance: Overlapping (1)
  • Causing sidewall (its bottom edge depicted red)
  • Assume: Field is bounded by fringe halo (e.g. \(8\, \mu m\) away from edge)
  • Fractions of fringe goes to metal1 or substrate

Fringe Capacitance: Overlapping (2)
  • Multiplier \(\alpha\) (comes from tech files: overlap table)
    • determines how quickly fringe capacitance drops with increasing distance
    • \(\alpha\) is related to distance \(d\) between layers
    • \(\alpha\) is proportional to \(C_{overlap_{metal1 \leftrightarrow metal2}}= \frac{\epsilon_{si} * K}{d} * \text{area}\)
      (for fixed value of area \(1\, \mu m^2\))
  • Fringe Fractions:
    • \(\text{frac}_{metal1} = \tfrac{2}{\pi} * \text{atan}(\alpha_{metal2 \rightarrow metal1}*x)\)
    • \(\text{frac}_{sub} = \tfrac{2}{\pi} * \text{atan}(\alpha_{metal2 \rightarrow sub}*(\text{halo}-x))\)
    • \(\tfrac{2}{\pi}\) is multiplied because of scaling to interval \([0.0,\,1.0]\), as\(\text{atan}(\infty)=\tfrac{\pi}{2}\)
  • Overlap capacitance:
    • \(C_{overlap} = \frac{\epsilon_{si} * K}{d} * \text{area} \,\,\,\,\,\,\,\,(\text{with area}=1 \mu m^2)\)
  • Coupling capacitance \(metal1 \leftrightarrow metal2\):
    • \(\alpha_{metal1 \leftrightarrow metal2} = \alpha_{scalefac} * C_{overlap_{metal1 \leftrightarrow metal2}}\)
    • \(\text{frac}_{metal1} = \tfrac{2}{\pi} * \text{atan}(\alpha_{metal1 \leftrightarrow metal2}*x)\)
    • \(\text{effective length} = \text{edge length} * \text{frac}_{metal1}\)
    • \(C_{fringe_{metal2 \rightarrow metal1}} = \text{effective length} * C_{sideoverlap_{metal2 \rightarrow metal1}}\)
  • Coupling capacitance \(metal1 \leftrightarrow sub\):
    • \(\alpha_{metal1 \leftrightarrow sub} = \alpha_{scalefac} * C_{overlap_{metal1 \leftrightarrow sub}}\)
    • \(\text{frac}_{sub} = \tfrac{2}{\pi} * \text{atan}(\alpha_{metal1 \leftrightarrow sub}*(\text{halo}-x))\)
    • \(\text{effective length} = \text{edge length} * \text{frac}_{sub}\)
    • \(C_{fringe_{metal2 \rightarrow sub}} = \text{effective length} * C_{sideoverlap_{metal2 \rightarrow sub}}\)

Fringe Capacitance: Non Overlapping (1)
  • Partial side overlap
    • In case there is only a partial side overlap, the non-existing near fraction is subtracted from the far fraction
    • \(metal1\) wire is offset, starts at \(x_{near}\)
    • \(metal1\) ends at \(x_{far}\)

Fringe Capacitance: Non Overlapping (2)
  • \(\text{frac}_{near} = \tfrac{2}{\pi} * \text{atan}(\alpha*x_{near})\)
  • \(\text{frac}_{far} = \tfrac{2}{\pi} * \text{atan}(\alpha*x_{far})\)
  • \(\text{frac} = \text{frac}_{far}-\text{frac}_{near}\)

5.7 Shielding Effects

Table 1: Shielding effects
Type Shielding
To Substrate Between layers On same layer
Overlap shielding
Sidewall shielding
Lateral fringe shielding
Vertical fringe shielding

Overlap shielding

Sidewall shielding

Lateral fringe shielding (1/2)

Vertical fringe shielding
Figure 3: Shielding Effects

Note, given an analyzed sidewall (edge in 2D), lateral fringe shielding

  • is caused by opposing shapes on the same layer
    • even by the same polygon
    • by other polygons (same net)
    • by other polygons (different net) — this is what we also look at when analyzing sidewall coupling
  • will shield the fringing to the lower layers, i.e. in Figure 4 the coupling between the two shapes is the same in the above and below cases
Figure 4: Lateral fringe shielding (2/2)

5.8 Parasitic Resistance

Magic constructs a graph of resistors between nodes

  • device terminals
  • pins
  • junctions

5.8.1 Wire resistance

  • Given a wire with length \(l\) and height \(h\), the basic formula is \[ R_{wire} = \frac{l}{h} * R_{coeff} \,\,\,\,\,\,\, \left[ \frac{\mu m}{\mu m} * mΩ\right] \]

  • Coefficient \(R_{coeff}\) is part of the tech files (Parasitic Tables)

    • defined for every metal layer
    • in \(mΩ\) for \(1\,{\mu m}^2\)
    • Coefficient already includes the thickness aspect of the layer, so the formula works in 2D

5.8.2 Via resistance

Figure 5: Via dimensions)
  • Given
    • drawn via in the layout, with width \(w\) and height \(h\)
    • design rules defined for each via layer:
      • via width \(viawidth\)
      • \(spacing\) between vias (in case of a via array)
      • \(border\) on each side of the via
  • MAGIC interpretation of the via drawing
    • determine number of vias in \(x\) and \(y\) direction, i.e. \(n_x\) and \(n_y\)
    • if \(x\) and \(y\) dimensions are below the minimum size, MAGIC counts 1 via in each direction
    • if the dimensions are larger, we calculate how much vias fit

\[ R_{via} = \frac{R_{coeff}}{n_x * n_y} \,\,\,\,\,\,\, \left[\frac{mΩ}{\text{via count}}\right] \]

\[ n_x = 1 + \left\lfloor\frac{w - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

\[ n_y = 1 + \left\lfloor\frac{h - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

  • Coefficient \(R_{coeff}\) is part of the tech files (Parasitic Tables)
    • defined for every via layer
    • in \(mΩ\) per via
    • Coefficient already includes the thickness aspect of the layer, so the formula works in 2D

6 KPEX/2.5D Engine

Field solvers are precise, yet slow, they are useful to obtain a golden reference.

For most use cases, a faster engine is desirable-. KPEX/MAGIC is such an engine, but the MAGIC code is tightly coupled with the database, layer/via design choices, and user interface of MAGIC. For example, it runs single-threaded.

Therefore, the KPEX 2.5D Engine intends to implement the concepts and formulas of MAGIC (see Section 5.2), but in a way that is best suited to the KLayout API.

KPEX 2.5D Engine
Caution

This section is under heavy construction!

Under heavy construction

7 Comparison KPEX/2.5D with MAGIC

The initial goal of KPEX/2.5D is to basically come up with the same results as KPEX/MAGIC.

Note

Notes about this comparison:

  • Version Magic 8.3 rev 486 is used, but augmented with debug logging6, which will be shown and discussed for each example.
  • KPEX/MAGIC halo is set to --magic_halo=100000
    • NOTE: the screenshots however were created with --magic_halo=8 to give better illustrations
  • KPEX/2.5D halo is set to --halo=100000

7.1 Test Pattern single_plate_100um_x_100um_li1_over_substrate

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/single_plate_100um_x_100um_li1_over_substrate.gds.gz

Overlap capacitance li1 to substrate.
Extracted Parasitic Overlap Capacitances
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Overlap li1 li1 substrate VSUBS 369.9 369.9 4

Perimeter (fringe) capacitance li1 to substrate.
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Fringe (top) li1 li1 substrate VSUBS 4.07 4.07 5
Fringe (left) li1 li1 substrate VSUBS 4.07 4.07 6
Fringe (right) li1 li1 substrate VSUBS 4.07 4.07 7
Fringe (bottom) li1 li1 substrate VSUBS 4.07 4.07 8
Magic 8.3 revision 486 - Compiled on `date`.
----------------------------------------------------

CapDebug (extNodeAreaFunc/Area) layer li(90), net li_0_0#, area=400000000 (10000 µm^2) nreg_cap += 369.9 fF
CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer li(90), net li_0_0#, length=20000 (100 µm), nreg_cap += 4.07 fF (now nreg_cap = 373.97 fF)
CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer li(90), net li_0_0#, length=20000 (100 µm), nreg_cap += 4.07 fF (now nreg_cap = 378.04 fF)
CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer li(90), net li_0_0#, length=20000 (100 µm), nreg_cap += 4.07 fF (now nreg_cap = 382.11 fF)
CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer li(90), net li_0_0#, length=20000 (100 µm), nreg_cap += 4.07 fF (now nreg_cap = 386.18 fF)
CapDebug (extSetResist): li_0_0# area=400000000 (10000 µm^2) perim=80000 (400 µm)
CapDebug ---

7.2 Test Pattern sidewall_20um_length_distance_200nm_li1

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/sidewall_20um_length_distance_200nm_li1.gds.gz

Overlap capacitance of nets on li1.
Extracted Parasitic Overlap Capacitances
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Overlap li1 A substrate VSUBS 0.7398 0.74 4
Overlap li1 B substrate VSUBS 0.7398 0.74 11

Sidewall capacitance between nets A and B on li1.
Extracted Parasitic Sidewall Capacitances
Description Layer Net1 Net2 MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Sidewall li1 A B 0.75 0.75 18
Sidewall li1 B A 0.75 0.75 21

Fringe capacitance between net A and substrate.
Extracted Parasitic Fringe Capacitances between nets A, B on li1 and substrate
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Fringe (top) li1 A substrate VSUBS 0.814 0.814 5
Fringe (left) li1 A substrate VSUBS 0.0407 0.041 6
Fringe (bottom) li1 A substrate VSUBS 0.814 0.076 7
Fringe (bottom) li1 A substrate VSUBS -0.7379 19
Fringe (right) li1 A substrate VSUBS 0.0407 0.041 8
Fringe (top) li1 B substrate VSUBS 0.814 0.076 12
Fringe (top) li1 B substrate VSUBS -0.7379 22
Fringe (left) li1 B substrate VSUBS 0.0407 0.041 13
Fringe (bottom) li1 B substrate VSUBS 0.814 0.814 14
Fringe (right) li1 B substrate VSUBS 0.0407 0.041 15
Magic 8.3 revision 486 - Compiled on `date`.
----------------------------------------------------

CapDebug (extNodeAreaFunc/Area) layer li(90), net li_0_240#, area=800000 (20 µm^2) nreg_cap += 0.7398 fF
CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer li(90), net li_0_240#, length=4000 (20 µm), nreg_cap += 0.814 fF (now nreg_cap = 1.5538 fF)
CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer li(90), net li_0_240#, length=200 (1 µm), nreg_cap += 0.0407 fF (now nreg_cap = 1.5945 fF)
CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer li(90), net li_0_240#, length=4000 (20 µm), nreg_cap += 0.814 fF (now nreg_cap = 2.4085 fF)
CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer li(90), net li_0_240#, length=200 (1 µm), nreg_cap += 0.0407 fF (now nreg_cap = 2.4492 fF)
CapDebug (extSetResist): li_0_240# area=800000 (20 µm^2) perim=8400 (42 µm)
CapDebug ---
CapDebug (extNodeAreaFunc/Area) layer li(90), net li_0_0#, area=800000 (20 µm^2) nreg_cap += 0.7398 fF
CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer li(90), net li_0_0#, length=4000 (20 µm), nreg_cap += 0.814 fF (now nreg_cap = 1.5538 fF)
CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer li(90), net li_0_0#, length=200 (1 µm), nreg_cap += 0.0407 fF (now nreg_cap = 1.5945 fF)
CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer li(90), net li_0_0#, length=4000 (20 µm), nreg_cap += 0.814 fF (now nreg_cap = 2.4085 fF)
CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer li(90), net li_0_0#, length=200 (1 µm), nreg_cap += 0.0407 fF (now nreg_cap = 2.4492 fF)
CapDebug (extSetResist): li_0_0# area=800000 (20 µm^2) perim=8400 (42 µm)
CapDebug ---
CapDebug (sidewall): A-B (layer li), overlap=4000 (20 µm), sep=40 (0.2 µm), e->ec_cap=12.75 (0.0255 fF), e->ec_offset=28 (0.14 µm), delta += 0.75 fF …  now is 0.75 fF
CapDebug (obsolete_fringe (blocked)): A -= 0.737881 fF …    now A == 1.711319 fF
    overlapMult=0.003699 (3.699 aF/µm^2) dnear=40 (0.2 µm), snear=0.0935129 (0.000467564 µm), perimCap[90][0]=0.2035 (40.7 /µm), length=4000 (20 µm)
CapDebug (sidewall): A-B (layer li), overlap=4000 (20 µm), sep=40 (0.2 µm), e->ec_cap=12.75 (0.0255 fF), e->ec_offset=28 (0.14 µm), delta += 0.75 fF …  now is 1.5 fF
CapDebug (obsolete_fringe (blocked)): B -= 0.737881 fF …    now B == 1.711319 fF
    overlapMult=0.003699 (3.699 aF/µm^2) dnear=40 (0.2 µm), snear=0.0935129 (0.000467564 µm), perimCap[90][0]=0.2035 (40.7 /µm), length=4000 (20 µm)
exttospice finished.

7.3 Test Pattern sideoverlap_simple_plates_li1_m1

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/sideoverlap_simple_plates_li1_m1.gds.gz

Overlap capacitances to substrate.
Extracted Parasitic Overlap Capacitances
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Overlap li1 li1 substrate VSUBS 3.699 3.7 7
Overlap met1 met1 substrate VSUBS 232.02 232.02 15

Fringe capacitances li1 to substrate.

Fringe capacitances met1 to substrate.
Extracted Parasitic Fringe Capacitances between metals and substrate
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Fringe (top) li1 li1 substrate VSUBS 2.035 2.035 9
Fringe (bottom) li1 li1 substrate VSUBS 2.035 2.035 11
Fringe (left) li1 li1 substrate VSUBS 0.081 0.081 10
Fringe (right) li1 li1 substrate VSUBS 0.081 0.081 12
Fringe (top) met1 met1 substrate VSUBS 6.0855 6.085 17
Fringe (bottom) met1 met1 substrate VSUBS 6.0855 5.927 19
Fringe (bottom) met1 met1 substrate VSUBS -0.1579 19
Fringe (left) met1 met1 substrate VSUBS 2.4342 2.434 18
Fringe (right) met1 met1 substrate VSUBS 2.4342 2.434 20
Note

MAGIC handles shielding differently than KPEX/2.5D, it first assumes no shield exists, and later subtracts portions to arrive at the shielded value. That’s why the bold cells differ. Line 15 - 20 accumulate contributions, whereas line 34 subtracts a contribution:

  • Line 15: CapDebug (extNodeAreaFunc/Area) layer m1(97), net m1_10000_10000#, area=360000000 (9000 µm^2) nreg_cap += 232.02 fF
  • Line 17: CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer m1(97), net m1_10000_10000#, length=30000 (150 µm), nreg_cap += 6.0855 fF (now nreg_cap = 238.105 fF)
  • Line 18: CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer m1(97), net m1_10000_10000#, length=12000 (60 µm), nreg_cap += 2.4342 fF (now nreg_cap = 240.54 fF)
  • Line 19: CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer m1(97), net m1_10000_10000#, length=30000 (150 µm), nreg_cap += 6.0855 fF (now nreg_cap = 246.625 fF)
  • Line 20: CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer m1(97), net m1_10000_10000#, length=12000 (60 µm), nreg_cap += 2.4342 fF (now nreg_cap = 249.059 fF)
  • Line 34: nreg_cap -= 0.157966 fF (now nreg_cap = 248.901 fF)

Comparison:

  • KPEX/2.5D: \(4.86834 + 0.77242 + 0.2867 = 5.9275\)
  • MAGIC: \(6.0855 - 0.157966 = 5.9275\)

Fringe capacitances li1 to m1.

Fringe capacitances m1 to li1.
Extracted Parasitic Fringe Capacitances between metals
Description Layer Top Net Top Layer Bottom Net Bottom MAGIC [fF] KPEX/2.5D [fF] MAGIC Lines
Fringe (top) li1 li1 met1 met1 0.598 0.06 26
Fringe (bottom) met1 met1 li1 li1 0.0654 0.065 36
Magic 8.3 revision 486 - Compiled on `date`.

----------------------------------------------------

Extracting sideoverlap_simple_plates_li1_m1 into /Users/martin/Source/klayout-pex/output_sky130A/sideoverlap_simple_plates_li1_m1__sideoverlap_simple_plates_li1_m1/magic_CC/sideoverlap_simple_plates_li1_m1.ext:

CapDebug (extNodeAreaFunc/Area) layer li(90), net li_34000_9000, area=4000000 (100 µm^2) nreg_cap += 3.699 fF

CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer li(90), net li_34000_9000, length=10000 (50 µm), nreg_cap += 2.035 fF (now nreg_cap = 5.734 fF)
CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer li(90), net li_34000_9000, length=400 (2 µm), nreg_cap += 0.0814 fF (now nreg_cap = 5.8154 fF)
CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer li(90), net li_34000_9000, length=10000 (50 µm), nreg_cap += 2.035 fF (now nreg_cap = 7.8504 fF)
CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer li(90), net li_34000_9000, length=400 (2 µm), nreg_cap += 0.0814 fF (now nreg_cap = 7.9318 fF)
CapDebug (extSetResist): li_34000_9000 area=4000000 (100 µm^2) perim=20800 (104 µm)
CapDebug ---
CapDebug (extNodeAreaFunc/Area) layer m1(97), net m1_10000_10000#, area=360000000 (9000 µm^2) nreg_cap += 232.02 fF

CapDebug (extNodeAreaFunc/Perimeter/TopSide) layer m1(97), net m1_10000_10000#, length=30000 (150 µm), nreg_cap += 6.0855 fF (now nreg_cap = 238.105 fF)
CapDebug (extNodeAreaFunc/Perimeter/LeftSide) layer m1(97), net m1_10000_10000#, length=12000 (60 µm), nreg_cap += 2.4342 fF (now nreg_cap = 240.54 fF)
CapDebug (extNodeAreaFunc/Perimeter/BottomSide) layer m1(97), net m1_10000_10000#, length=30000 (150 µm), nreg_cap += 6.0855 fF (now nreg_cap = 246.625 fF)
CapDebug (extNodeAreaFunc/Perimeter/RightSide) layer m1(97), net m1_10000_10000#, length=12000 (60 µm), nreg_cap += 2.4342 fF (now nreg_cap = 249.059 fF)
CapDebug (extSetResist): m1_10000_10000# area=360000000 (9000 µm^2) perim=84000 (420 µm)
CapDebug ---
CapDebug (extSideOverlapHalo): (li-m1) length=30.000000 µm, mult=0.011420, dnear=3.000000 µm (600), dfar=8.000000 µm (1600), snear=0.907713, sfar=0.965163 (cfrac=0.057450)
CapDebug (extSideOverlapHalo) (li-substrate): mult=0.003699, snear=0.730477, sfar=0.893413 (sfrac=0.162935)
CapDebug (extSideOverlapHalo): efflength=1.72351 µm, cap+=0.299029 aF, cap=59.8059 aF, e->ec_cap=0.1735, so_coupfrac=0, subfrac+=0, subfrac=0, so_subfrac=0
CapDebug (sideoverlaphalo): met1-li1 += 0.059806 fF …   now met1-li1 == 0.059806 fF
CapDebug ---
CapDebug (extSideOverlapHalo): (m1-li) length=30.000000 µm, mult=0.011420, dnear=3.000000 µm (600), dfar=5.000000 µm (1000), snear=0.907713, sfar=0.944366 (cfrac=0.036653)
CapDebug (extSideOverlapHalo) (m1-substrate): mult=0.002578, snear=0.634619, sfar=0.764408 (sfrac=0.129789)
CapDebug (extSideOverlapHalo): efflength=1.0996 µm, cap+=0.327131 aF, cap=65.4263 aF, e->ec_cap=0.2975, so_coupfrac=0, subfrac+=0, subfrac=0, so_subfrac=0
CapDebug (extSideOverlapHalo/obsolete_perimcap) layer m1(97), net met1, 
    efflength=3.89366 µm (778.733) = (sfrac(0.129789) - subfrac(0)) * length(30 µm)
    exts_perimCap[m1][0] = 0.20285
    nreg_cap -= 0.157966 fF (now nreg_cap = 248.901 fF)
CapDebug (obsolete_perimcap): met1 -= 0.157966 fF … now met1 == 248.901423 fF
CapDebug (sideoverlaphalo): met1-li1 += 0.065426 fF …   now met1-li1 == 0.125232 fF

7.4 Test Pattern r_single_wire_li1

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/r_single_wire_li1.gds.gz

Resistance of a single wire on li1.
  • Wire length \(L = 9.85\,\mu m\)
  • Wire height \(H = 0.15\,\mu m\)
  • Layer is li1
  • Parasitic Table Coefficient \(R_{coeff}(li1) = 12800\,mΩ\)

If we apply the formula illustrated in Section 5.8.1, we get \[ R_{wire} = \frac{L}{H} * R_{coeff} \] \[ R_{wire} = \frac{9.85\,\mu m}{0.15\,\mu m} * 12800\,mΩ = 8405\dot{3}\,mΩ = 840.5\dot{3}\,Ω \]

Magic 8.3 revision 486 - Compiled on `date`.
----------------------------------------------------
...
Warning:  Ports "A" and "B" are electrically shorted.

Location is (1970, -15); drivepoint (1970, -15)
Location is (0, -15); drivepoint (0, -15)

ResCalcEastWest: A (0, -0.075) <-> B (9.85, -0.075) @ li
    exts_sheetResist[li]=12800, length=9.85, height=0.15, resistor->rr_value = 840533 mΩ
ResCalcEastWest: A (0, -0.075) <-> B (9.85, -0.075) @ li
    exts_sheetResist[li]=12800, length=9.85, height=0.15, resistor->rr_value = 840533 mΩ
Total Nets: 2
Note

MAGIC recognizes that ports A and B are shorted. The purpose of these test patterns is to look at minimized problems in isolation, like the resistance of the wire here. They are not realistic examples, so it appears to be a bug in that corner case, that the resistance is reported twice.

7.5 Test Pattern r_contact_1x1_minsize_mcon

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/r_contact_1x1_minsize_mcon.gds.gz

Resistance of a minimum sized via on mcon.
  • Layers:
    • Top Layer: met1
    • Via: mcon
    • Bottom Layer: li1
  • Design rules:
    • Via width: \(viawidth = 0.17\,\mu m\)
    • Via spacing: \(spacing = 0.19\,\mu m\)
    • Via border: \(border = 0.0\,\mu m\)
  • Parasitic Table Coefficient \(R_{coeff}(mcon) = 9300\,mΩ\)
  • Drawn via:
    • \(w = 0.17\,\mu m\)
    • \(h = 0.17\,\mu m\)

If we apply the formula illustrated in Section 5.8.2, we get

\[ n_x = 1 + \left\lfloor\frac{w - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

\[ n_x = 1 + \left\lfloor\frac{0.17\,\mu m - (0.17 + 2 * 0.0)\,\mu m}{0.17\,\mu m + 0.19\,\mu m}\right\rfloor = 1 \]

\[ n_y = 1 + \left\lfloor\frac{h - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

\[ n_y = 1 + \left\lfloor\frac{0.17\,\mu m - (0.17 + 2 * 0.0)\,\mu m}{0.17\,\mu m + 0.19\,\mu m}\right\rfloor = 1 \]

\[ R_{via} = \frac{R_{coeff}}{n_x * n_y} \,\,\,\,\,\,\, \left[\frac{mΩ}{\text{via count}}\right] \]

\[ R_{via} = \frac{9300\,mΩ}{1 * 1} = 9300\,mΩ = 9.3\,Ω \]

Magic 8.3 revision 486 - Compiled on `date`.
----------------------------------------------------
...
Warning:  Ports "TOP" and "BOT" are electrically shorted.
Location is (0, 0); drivepoint (0, 0)
Location is (0, 0); drivepoint (0, 0)

ResDoContacts: (null) (0.085, 0.085) <-> (null) (0.085, 0.085) @ v0
    W = 0.17 µm, H = 0.17 µm
    exts_viaResist[v0]=9300, viawidth=0.17 µm, spacing=0.19 µm, border=0 µm
    squaresx=1, squaresy=1, resistor->rr_value = 9300 mΩ

7.6 Test Pattern r_contact_2x2_minsize_mcon

GDS: https://github.com/martinjankoehler/klayout-pex/blob/main/testdata/designs/sky130A/test_patterns/r_contact_2x2_minsize_mcon.gds.gz

Resistance of a minimum sized 2x2 via on mcon.
  • Layers:
    • Top Layer: met1
    • Via: mcon
    • Bottom Layer: li1
  • Design rules:
    • Via width: \(viawidth = 0.17\,\mu m\)
    • Via spacing: \(spacing = 0.19\,\mu m\)
    • Via border: \(border = 0.0\,\mu m\)
  • Parasitic Table Coefficient \(R_{coeff}(mcon) = 9300\,mΩ\)
  • Drawn via:
    • \(w = 0.53\,\mu m\)
    • \(h = 0.53\,\mu m\)

If we apply the formula illustrated in Section 5.8.2, we get

\[ n_x = 1 + \left\lfloor\frac{w - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

\[ n_x = 1 + \left\lfloor\frac{0.53\,\mu m - (0.17 + 2 * 0.0)\,\mu m}{0.17\,\mu m + 0.19\,\mu m}\right\rfloor = 1 + \left\lfloor 1.0\right\rfloor = 2 \]

\[ n_y = 1 + \left\lfloor\frac{h - (viawidth + 2 * border)}{viawidth + spacing}\right\rfloor \]

\[ n_y = 1 + \left\lfloor\frac{0.53\,\mu m - (0.17 + 2 * 0.0)\,\mu m}{0.17\,\mu m + 0.19\,\mu m}\right\rfloor = 1 + \left\lfloor 1.0\right\rfloor = 2 \]

\[ R_{via} = \frac{R_{coeff}}{n_x * n_y} \,\,\,\,\,\,\, \left[\frac{mΩ}{\text{via count}}\right] \]

\[ R_{via} = \frac{9300\,mΩ}{2 * 2} = 2325\,mΩ = 2.325\,Ω \]

Magic 8.3 revision 486 - Compiled on `date`.
----------------------------------------------------
...
Warning:  Ports "TOP" and "BOT" are electrically shorted.
...
ResDoContacts: (null) (0.265, 0.265) <-> (null) (0.265, 0.265) @ v0
    W = 0.53 µm, H = 0.53 µm
    exts_viaResist[v0]=9300, viawidth=0.17 µm, spacing=0.19 µm, border=0 µm
    squaresx=2, squaresy=2, resistor->rr_value = 2325 mΩ

8 Appendix

8.1 References

Di Lorenzo, Enrico. 2019. “FasterCap Embedded Help.” 2019. https://www.fastfieldsolvers.com/Download/FasterCapHelp.chm.
———. 2023. “The Maxwell Capacitance Matrix: White Paper WP110301. Revision 03.” 2023. https://www.fastfieldsolvers.com/Papers/The_Maxwell_Capacitance_Matrix_WP110301_R03.pdf.
Edwards, R. Timothy. 2022. “Whom Do You Trust? Validating Process Parameters for Open-Source Tools.” https://wiki.f-si.org/index.php?title=Whom_do_you_trust%3F:_Validating_process_parameters_for_open-source_tools.
———. 2023a. “Full r-c Extraction in Magic (Presentation Slides).” https://lists.chipsalliance.org/g/analog-wg/attachment/99/0/AWG_040423_Tim_Edwards_chips_alliance_slides.pdf.
———. 2023b. “Full r-c Extraction in Magic (Presentation Video).” https://www.youtube.com/watch?v=4d2mtiEHHeo.
Maxwell, James Clerk. 1873. A Treatise on Electricity and Magnetism. Vol. 1. Clarendon Press.
Nagel, Laurence W. 1975. “SPICE2: A Computer Program to Simulate Semiconductor Circuits.” PhD thesis, EECS Department, University of California, Berkeley. http://www2.eecs.berkeley.edu/Pubs/TechRpts/1975/9602.html.

Footnotes

  1. Metal-Oxide-Metal capacitors↩︎

  2. C++ generator scripts the built-in tech files are located in cxx/gen_tech_pb/pdk/*.cpp.↩︎

  3. To find the site-packages directory for the klayout-pex package, call pip3 show klayout-pex.↩︎

  4. Metal-Oxide-Metal capacitors↩︎

  5. Metal-Insulator-Metal capacitors↩︎

  6. A fork of MAGIC which includes debug logging about the different parasitic contributions is hosted here: https://github.com/martinjankoehler/magic↩︎

Reuse

Apache-2.0 license