Detecting and fixing DRC errors

In this example, we demonstrate how to run DRC on a GDSII file directly from IPKISS using KLayout as DRC engine. After analyzing the generated error report, we show how to use native IPKISS functions to easily fix these DRC violations.

This example is based on the SiFab demo PDK, which has been equipped with an example DRC deck compatible with KLayout.

Circuit definition

First, we define a circuit using components from the SiFab demonstration PDK. We then visualize the circuit layout and export it to GDSII format.

import si_fab.all as pdk
import ipkiss3.all as i3
import pathlib


rib_wg = pdk.SiRibWaveguideTemplate()
rib_wg.Layout(cladding_width=8.0)
mmi = pdk.MMI1x2Optimized1550()
ring = pdk.RacetrackResonator(length=150.0)
spiral = pdk.FixedLengthSpiralFixedBend(straight_trace_template=rib_wg)
spiral.Layout(spacing=8.0)
dc = pdk.SiDirectionalCouplerSPower(power_fraction=0.5)
fc = pdk.FC_TE_1550()


faulty_circuit = i3.Circuit(
    name="example_sifab_circuit",
    insts={
        "fc1": fc,
        "fc2": fc,
        "fc3": fc,
        "mmi": mmi,
        "ring": ring,
        "spiral": spiral,
        "dc": dc,
    },
    specs=[
        i3.Place("mmi", (0, 0)),
        i3.Place("ring:in", relative_to="mmi:out2", position=(30, 0)),
        i3.Place("spiral:in", relative_to="mmi:out1", position=(30, -5)),
        i3.Place("dc:in1", relative_to="mmi:out1", position=(300, 0)),
        i3.FlipV("spiral"),
        i3.Join("fc1:out", "mmi:in1"),
        i3.Place("fc2:out", relative_to="dc:out1", position=(20, -10), angle=180.0),
        i3.Place("fc3:out", relative_to="dc:out2", position=(20, 10), angle=180.0),
        i3.ConnectBend("mmi:out2", "ring:in"),
        i3.ConnectBend("mmi:out1", "spiral:in"),
        i3.ConnectBend("ring:out", "dc:in2"),
        i3.ConnectBend("spiral:out", "dc:in1"),
        i3.ConnectBend("dc:out1", "fc2:out"),
        i3.ConnectBend("dc:out2", "fc3:out"),
    ],
)

faulty_circuit_layout = faulty_circuit.Layout()
faulty_circuit_layout.visualize()
faulty_circuit_layout.write_gdsii("example_sifab_circuit.gds")
plot run drc sifab

Running DRC

We now run DRC on the generated GDSII file using KLayout as an engine. To do this, we use the built-in IPKISS function i3.run_drc_klayout.

drc_path = pathlib.Path(pdk.__file__).parent.parent.parent / "techfiles" / "klayout" / "ipkiss" / "si_fab.drc"
i3.run_drc_klayout("example_sifab_circuit.gds", drc_path, "example_sifab_circuit.lyrdb", open_in_klayout=True)

After this command, KLayout will open with the DRC errors shown in the Marker Database Browser:

KLayout showing DRC errors

DRC errors shown in KLayout after running i3.run_drc_klayout

Fixing DRC violations

Running DRC shows there are acute angles between the SHALLOW layers. We fix these by adding ‘stub’ elements in an automated way with the built-in IPKISS function i3.get_stub_elements.

stubs, _ = i3.get_stub_elements(faulty_circuit_layout, layers=[i3.TECH.PPLAYER.SHALLOW], stub_width=0.25)

corrected_circuit_layout = i3.LayoutCell("example_sifab_circuit_corrected").Layout(
    elements=faulty_circuit_layout.layout + stubs
)

Now we write the GDSII file again and run DRC. We can see that the DRC violations have been fixed, and our layout is now DRC error-free!

corrected_circuit_layout.write_gdsii("example_sifab_circuit_corrected.gds")
i3.run_drc_klayout(
    "example_sifab_circuit_corrected.gds",
    drc_path,
    "example_sifab_circuit_corrected.lyrdb",
    open_in_klayout=True,
)

After this command has run, KLayout opens again, and shows no DRC errors:

KLayout showing DRC errors

DRC errors are fixed after using i3.get_stub_elements.