Generic PDK#

gdsfactory includes a generic Process Design Kit PDK, which is a library of components associated to a generic foundry process gdsfactory.generic_tech. See components available in the generic component library that you can customize or adapt to create your own.

The generic process including layer numbers is based on the book “Silicon Photonics Design: From Devices to Systems Lukas Chrostowski, Michael Hochberg”. You can learn more about process design kits (PDKs) in this tutorial

LayerMap#

A layer map maps layer names to a integer numbers pair (GDSlayer, GDSpurpose)

Each foundry uses different GDS layer numbers for different process steps.

GDS (layer, purpose)

layer_name

Description

1 , 0

WG

220 nm Silicon core

2 , 0

SLAB150

150nm Silicon slab (70nm shallow Etch for grating couplers)

3 , 0

SLAB90

90nm Silicon slab (for modulators)

4, 0

DEEPTRENCH

Deep trench

47, 0

MH

heater

41, 0

M1

metal 1

45, 0

M2

metal 2

40, 0

VIAC

VIAC to contact Ge, NPP or PPP

44, 0

VIA1

VIA1

46, 0

PADOPEN

Bond pad opening

51, 0

UNDERCUT

Undercut

66, 0

TEXT

Text markup

64, 0

FLOORPLAN

Mask floorplan

Hide code cell source
import gdsfactory as gf
from gdsfactory.generic_tech import LAYER, LAYER_STACK
from gdsfactory.generic_tech.get_klayout_pyxs import get_klayout_pyxs
from gdsfactory.technology import LayerLevel, LayerStack, LayerViews, LayerMap
from gdsfactory.generic_tech import get_generic_pdk
from IPython.display import Code

from gdsfactory.config import PATH
Layer = tuple[int, int]


class GenericLayerMap(LayerMap):
    """Generic layermap based on book.

    Lukas Chrostowski, Michael Hochberg, "Silicon Photonics Design",
    Cambridge University Press 2015, page 353
    You will need to create a new LayerMap with your specific foundry layers.
    """

    WAFER: Layer = (99999, 0)

    WG: Layer = (1, 0)
    WGCLAD: Layer = (111, 0)
    SLAB150: Layer = (2, 0)
    SLAB90: Layer = (3, 0)
    DEEPTRENCH: Layer = (4, 0)
    GE: Layer = (5, 0)
    UNDERCUT: Layer = (6, 0)
    WGN: Layer = (34, 0)
    WGN_CLAD: Layer = (36, 0)

    N: Layer = (20, 0)
    NP: Layer = (22, 0)
    NPP: Layer = (24, 0)
    P: Layer = (21, 0)
    PP: Layer = (23, 0)
    PPP: Layer = (25, 0)
    GEN: Layer = (26, 0)
    GEP: Layer = (27, 0)

    HEATER: Layer = (47, 0)
    M1: Layer = (41, 0)
    M2: Layer = (45, 0)
    M3: Layer = (49, 0)
    VIAC: Layer = (40, 0)
    VIA1: Layer = (44, 0)
    VIA2: Layer = (43, 0)
    PADOPEN: Layer = (46, 0)

    DICING: Layer = (100, 0)
    NO_TILE_SI: Layer = (71, 0)
    PADDING: Layer = (67, 0)
    DEVREC: Layer = (68, 0)
    FLOORPLAN: Layer = (64, 0)
    TEXT: Layer = (66, 0)
    PORT: Layer = (1, 10)
    PORTE: Layer = (1, 11)
    PORTH: Layer = (70, 0)
    SHOW_PORTS: Layer = (1, 12)
    LABEL_SETTINGS: Layer = (202, 0)
    DRC_MARKER: Layer = (205, 0)
    LABEL_INSTANCE: Layer = (206, 0)

    SOURCE: Layer = (110, 0)
    MONITOR: Layer = (101, 0)


LAYER = GenericLayerMap
LAYER
<aenum 'GenericLayerMap'>
layer_wg = (1, 0)
print(layer_wg)
(1, 0)

Extract layers#

You can also extract layers using the extract function. This function returns a new flattened Component that contains the extracted layers. A flat Component does not have references, and all the polygons are absorbed into the top cell.

from gdsfactory.generic_tech import get_generic_pdk

PDK = get_generic_pdk()
PDK.activate()

LAYER_VIEWS = PDK.layer_views
c = LAYER_VIEWS.preview_layerset()
c.plot()
../_images/03081bbe065cbb4f9eaadb08a142206042e5fd58bd854e4e7e3b412fc1fd3318.png
extract = c.extract(layers=((41, 0), (40, 0)))
extract.plot()
../_images/f5a0f3249aaae91350ff52d103e82bbc2ecca48f3f2b0a6dd89f38b753fdef29.png

Remove layers#

You can remove layers using the remove_layers() function.

removed = extract.remove_layers(layers=((40, 0),))
removed.plot()
../_images/b7cac8d1387cc6637f73dc0251388a991d6ed98d706b35239faae8549b6259b4.png

Remap layers#

You can remap (change the polygons from one layer to another layer) using the remap_layer, which will return a new Component

c = gf.components.straight(layer=(2, 0))
c.plot()
../_images/17a9e854becae81ef3fa6a5ec97c7210442e8a773a82569054af5d4f9e80acda.png
remap = c.remap_layers({(2, 0): (34, 0)})
remap.plot()
../_images/891edab7cab77248f1fd2200b36ca33f53122ae1f2b1cc20b9fc2143c72ca14e.png

LayerViews#

Klayout shows each GDS layer with a color, style and transparency

You can define your layerViews in a klayout Layer Properties file layers.lyp or in YAML format

We recommend using YAML and then generate the lyp in klayout, as YAML is easier to modify than XML.

Code(filename=PATH.klayout_yaml)
LayerViews:
  Waveguide:
    layer: [1, 0]
    hatch_pattern: dotted
    width: 1
    color: "#ff9d9d"
  WGCLAD:
    layer: [111, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    visible: false
    width: 1
    color: "silver"
  SLAB150:
    layer: [2, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    transparent: true
    width: 1
    color: "cyan"
  SHALLOW_ETCH:
    layer: [2, 6]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    color: "blue"
  SLAB90:
    layer: [3, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    transparent: true
    width: 1
    color: "#805000"
  DEEP_ETCH:
    layer: [3, 6]
    layer_in_name: true
    hatch_pattern: left-hatched
    color: "#cc0000"
  SLAB150CLAD:
    layer: [2, 9]
    layer_in_name: true
    frame_color: "#9999cc"
    fill_color: "#80a8ff"
    hatch_pattern: coarsely dotted
    visible: false
    width: 1
  SLAB90CLAD:
    layer: [3, 1]
    layer_in_name: true
    frame_color: "#9999cc"
    fill_color: "#80a8ff"
    hatch_pattern: hollow
    visible: false
    width: 1
  Doping:
    group_members:
      N:
        layer: [20, 0]
        layer_in_name: true
        hatch_pattern: lightly left-hatched
        width: 1
        color: "red"
      NP:
        layer: [22, 0]
        layer_in_name: true
        hatch_pattern: lightly left-hatched
        width: 1
        color: "red"
      NPP:
        layer: [24, 0]
        layer_in_name: true
        hatch_pattern: coarsely dotted
        width: 1
        color: "red"
      P_210:
        layer: [21, 0]
        hatch_pattern: lightly left-hatched
        transparent: true
        width: 1
        color: "blue"
      PP:
        layer: [23, 0]
        layer_in_name: true
        hatch_pattern: lightly left-hatched
        width: 1
        color: "blue"
      PPP:
        layer: [25, 0]
        layer_in_name: true
        hatch_pattern: strongly left-hatched dense
        width: 1
        color: "blue"
      PDPP:
        layer: [27, 0]
        layer_in_name: true
        hatch_pattern: lightly cross-hatched
        width: 1
        color: "#ccb27f"
      GENPP:
        layer: [26, 0]
        layer_in_name: true
        hatch_pattern: plus
        width: 1
        color: "#cc00cc"
      GEPPP:
        layer: [29, 0]
        layer_in_name: true
        hatch_pattern: plus
        width: 1
        color: "#cc00cc"
  WGN_Nitride:
    layer: [34, 0]
    layer_in_name: true
    hatch_pattern: left-hatched
    transparent: true
    width: 1
    color: "#ff8000"
  WGclad_material:
    layer: [36, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    visible: false
    width: 1
    color: "silver"
  GE:
    layer: [5, 0]
    layer_in_name: true
    hatch_pattern: dotted
    width: 1
    color: "magenta"
  SILICIDE:
    layer: [39, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "#cc4c00"
  MH:
    layer: [47, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    transparent: true
    width: 1
    color: "#ff8000"
  M1:
    layer: [41, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "#01ff6b"
    brightness: -16
  M2:
    layer: [45, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "#008050"
  M3:
    layer: [49, 0]
    layer_in_name: true
    frame_color: "teal"
    fill_color: "#800057"
    hatch_pattern: coarsely dotted
  VIAC:
    layer: [40, 0]
    layer_in_name: true
    hatch_pattern: hollow
    width: 1
    color: "#cc4c00"
  VIA1:
    layer: [44, 0]
    layer_in_name: true
    hatch_pattern: hollow
    width: 1
    color: "grey"
  VIA2:
    layer: [43, 0]
    layer_in_name: true
    hatch_pattern: hollow
    width: 1
    color: "#805000"
  CAPACITOR:
    layer: [42, 0]
    layer_in_name: true
    hatch_pattern: dotted
    width: 1
    color: "#805000"
  METALOPEN:
    layer: [46, 0]
    layer_in_name: true
    hatch_pattern: cross-hatched
    width: 1
    color: "#606060"
  DEEPTRENCH:
    layer: [4, 0]
    layer_in_name: true
    hatch_pattern: lightly right-hatched
    width: 1
    color: "#9999cc"
  OXIDE_ETCH:
    layer: [6, 0]
    layer_in_name: true
    hatch_pattern: strongly left-hatched dense
    width: 1
    color: "grey"
  SITILES:
    layer: [190, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "grey"
  M1TILES:
    layer: [191, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "#91ff00"
  LABEL_OPTICAL_IO:
    layer: [201, 0]
    layer_in_name: true
    hatch_pattern: hollow
    width: 1
    color: "blue"
  LABEL_SETTINGS:
    layer: [202, 0]
    layer_in_name: true
    hatch_pattern: hollow
    visible: false
    width: 1
    color: "magenta"
  TE:
    layer: [203, 0]
    layer_in_name: true
    transparent: true
    width: 1
    color: "blue"
  TM:
    layer: [204, 0]
    layer_in_name: true
    width: 1
    color: "red"
  LABEL_INSTANCES:
    layer: [206, 0]
    layer_in_name: true
    hatch_pattern: lightly left-hatched
    color: "red"
  DICING:
    layer: [65, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    width: 1
    color: "#cc0000"
  DRC_EXCLUDE:
    layer: [67, 0]
    layer_in_name: true
    hatch_pattern: hollow
    visible: false
    width: 2
    color: "grey"
  FLOORPLAN:
    layer: [64, 0]
    layer_in_name: true
    hatch_pattern: hollow
    color: "pink"
  simulation:
    group_members:
      SIM_REGION:
        layer: [100, 0]
        layer_in_name: true
        hatch_pattern: hollow
        color: "grey"
      MONITOR:
        layer: [101, 0]
        layer_in_name: true
        hatch_pattern: hollow
        color: "blue"
      SOURCE:
        layer: [110, 0]
        layer_in_name: true
        hatch_pattern: hollow
        color: "red"
  Lumerical:
    layer: [733, 0]
    hatch_pattern: hollow
    width: 3
    color: "#800057"
  DevRec:
    layer: [68, 0]
    hatch_pattern: hollow
    visible: false
    transparent: true
    width: 1
    color: "#004080"
  PinRec:
    layer: [1, 10]
    hatch_pattern: hollow
    color: "#404040"
  FbrTgt:
    layer: [81, 0]
    hatch_pattern: lightly right-hatched
    width: 2
    color: "#004080"
  Text:
    layer: [66, 0]
    hatch_pattern: hollow
    width: 1
    color: "blue"
  Errors:
    layer: [69, 0]
    hatch_pattern: hollow
    width: 1
    color: "blue"
  PinRecM:
    layer: [1, 11]
    hatch_pattern: hollow
    width: 1
    color: "#004080"
  XSECTION:
    group_members:
      XS_BOX:
        layer: [300, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_SI:
        layer: [301, 0]
        layer_in_name: true
        width: 1
        color: "grey"
        hatch_pattern: solid
      XS_SIN:
        layer: [319, 0]
        layer_in_name: true
        width: 1
        color: "grey"
        hatch_pattern: solid
      XS_N:
        layer: [320, 0]
        layer_in_name: true
        width: 1
        color: "#008ca5"
        hatch_pattern: solid
      XS_NPP:
        layer: [321, 0]
        layer_in_name: true
        width: 1
        color: "#004ca5"
        hatch_pattern: solid
      XS_P:
        layer: [330, 0]
        layer_in_name: true
        width: 1
        color: "#00f233"
        hatch_pattern: solid
      XS_PDPP:
        layer: [327, 0]
        layer_in_name: true
        width: 1
        color: "#00f233"
        hatch_pattern: solid
      XS_PPP:
        layer: [331, 0]
        layer_in_name: true
        width: 1
        color: "#00b233"
        hatch_pattern: solid
      XS_SI_SLAB:
        layer: [313, 0]
        layer_in_name: true
        width: 1
        color: "#80a8ff"
        hatch_pattern: solid
      XS_OVERLAY:
        layer: [311, 0]
        layer_in_name: true
        width: 1
        color: "blue"
        hatch_pattern: solid
      XS_OX_SI:
        layer: [302, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_GE:
        layer: [315, 0]
        layer_in_name: true
        width: 1
        color: "#004ca5"
        hatch_pattern: solid
      XS_VIAC:
        layer: [303, 0]
        layer_in_name: true
        width: 1
        color: "grey"
        hatch_pattern: solid
      XS_OX_NIT_CLAD:
        layer: [304, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_OXIDE_M1:
        layer: [305, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_MH:
        layer: [306, 0]
        layer_in_name: true
        width: 1
        color: "green"
        hatch_pattern: solid
      XS_OXIDE_M2:
        layer: [307, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_OXIDE_MH:
        layer: [317, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_OXIDE_ML:
        layer: [309, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_VIA1:
        layer: [308, 0]
        layer_in_name: true
        width: 1
        color: "grey"
        hatch_pattern: solid
      XS_M2:
        layer: [399, 0]
        layer_in_name: true
        width: 1
        color: "#805000"
        hatch_pattern: solid
      XS_OXIDE_M3:
        layer: [311, 0]
        layer_in_name: true
        width: 1
        color: "#f3ff80"
        hatch_pattern: solid
      XS_VIA2:
        layer: [310, 0]
        layer_in_name: true
        width: 1
        color: "grey"
        hatch_pattern: solid
      XS_SIN2:
        layer: [305, 0]
        layer_in_name: true
        width: 1
        color: "#805000"
        hatch_pattern: solid
  DRC_MARKER:
    layer: [205, 0]
    layer_in_name: true
    transparent: true
    width: 3
    color: "red"
  NOTILE_M1:
    layer: [71, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    visible: false
    color: "grey"
  NOTILE_M2:
    layer: [72, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    visible: false
    color: "grey"
  NOTILE_M3:
    layer: [73, 0]
    layer_in_name: true
    hatch_pattern: coarsely dotted
    visible: false
    color: "#606060"
  gdsfactory:
    group_members:
      ERROR_PATH:
        layer: [1000, 0]
        layer_in_name: true
        transparent: true
        width: 3
        color: "red"
      SHOW_PORTS:
        layer: [1, 12]
        layer_in_name: true
        hatch_pattern: lightly left-hatched
        color: "#ff80a8"
      WAFER:
        layer: [99999, 0]
        hatch_pattern: lightly left-hatched
        color: "#ff80a8"
        visible: false

Once you modify the YAML file you can easily write it to klayout layer properties lyp or the other way around.

YAML <---> LYP

The functions LayerView.to_lyp(filepath) and LayerView.to_yaml(filepath) allow you to convert from each other.

LYP is based on XML so it’s much easier to make changes and maintain the equivalent YAML file.

YAML -> LYP#

You can easily convert from YAML into Klayout Layer Properties.

LAYER_VIEWS = LayerViews(filepath=PATH.klayout_lyp)
LAYER_VIEWS.to_lyp("extra/klayout_layers.lyp")
PosixPath('extra/klayout_layers.lyp')

LYP -> YAML#

Sometimes you start from an LYP XML file. We recommend converting to YAML and using the YAML as the layer views source of truth.

Layers in YAML are easier to read and modify than doing it in klayout XML format.

LAYER_VIEWS = LayerViews(filepath=PATH.klayout_lyp)
LAYER_VIEWS.to_yaml("extra/layers.yaml")

Preview layerset#

You can preview all the layers defined in your LayerViews

c = LAYER_VIEWS.preview_layerset()
c.plot()
../_images/9c0aa55e65b6e86c15924abbb598119aa41e9cf8535682f51c04b6a45e8f0da7.png

By default the generic PDK has some layers that are not visible and therefore are not shown.

c_wg_clad = c.extract(layers=[(1, 0)])
c_wg_clad.plot()
../_images/d895a0878625df6de289899cfa75d01a3483f0f2f93935d529b183eb3accb59a.png
LAYER_VIEWS.layer_views["WGCLAD"]
LayerView:
	info: None
	layer: (111, 0)
	layer_in_name: True
	frame_color: silver
	fill_color: silver
	frame_brightness: 0
	fill_brightness: 0
	hatch_pattern: None
	line_style: None
	valid: True
	visible: False
	transparent: False
	width: 1
	marked: False
	xfill: False
	animation: 0
	group_members: {}
LAYER_VIEWS.layer_views["WGCLAD"].visible
False

You can make it visible

LAYER_VIEWS.layer_views["WGCLAD"].visible = True
LAYER_VIEWS.layer_views["WGCLAD"].visible
True
c_ge = c.extract(layers=[(5, 0)])
c_ge.plot()
../_images/6906709bcb67bf37fc39e948537a13887a0c73ff1785a6915df5089ad3c6bd06.png

LayerStack#

Each layer also includes the information of thickness and position of each layer after fabrication.

This LayerStack can be used for creating a 3D model with Component.to_3d or running Simulations.

A GDS has different layers to describe the different fabrication process steps. And each grown layer needs thickness information and z-position in the stack.

layer stack

Lets define the layer stack for the generic layers in the generic_technology.

from gdsfactory.generic_tech.layer_map import LAYER
from gdsfactory.technology import LogicalLayer, LayerStack, LayerLevel
import gdsfactory as gf

nm = 1e-3
thickness_wg = 220 * nm
thickness_slab_deep_etch = 90 * nm
thickness_slab_shallow_etch = 150 * nm

sidewall_angle_wg = 0
layer_core = LogicalLayer(layer=LAYER.WG)
layer_shallow_etch = LogicalLayer(layer=LAYER.SHALLOW_ETCH)
layer_deep_etch = LogicalLayer(layer=LAYER.DEEP_ETCH)


layers = {
    "core": LayerLevel(
        layer=layer_core - layer_deep_etch - layer_shallow_etch,
        thickness=thickness_wg,
        zmin=0.0,
        material="si",
        mesh_order=2,
        sidewall_angle=sidewall_angle_wg,
        width_to_z=0.5,
        derived_layer=layer_core,
    ),
    "shallow_etch": LayerLevel(
        layer=LogicalLayer(layer=LAYER.SHALLOW_ETCH),
        thickness=thickness_wg - thickness_slab_shallow_etch,
        zmin=0.0,
        material="si",
        mesh_order=1,
        derived_layer=LogicalLayer(layer=LAYER.SLAB150),
    ),
    "deep_etch": LayerLevel(
        layer=LogicalLayer(layer=LAYER.DEEP_ETCH),
        thickness=thickness_wg - thickness_slab_deep_etch,
        zmin=0.0,
        material="si",
        mesh_order=1,
        derived_layer=LogicalLayer(layer=LAYER.SLAB90),
    ),
    "slab150": LayerLevel(
        layer=LogicalLayer(layer=LAYER.SLAB150),
        thickness=150e-3,
        zmin=0,
        material="si",
        mesh_order=3,
    ),
    "slab90": LayerLevel(
        layer=LogicalLayer(layer=LAYER.SLAB90),
        thickness=thickness_slab_deep_etch,
        zmin=0.0,
        material="si",
        mesh_order=2,
    ),
}


layer_stack = LayerStack(layers=layers)

c = gf.c.grating_coupler_elliptical_trenches()
s = c.to_3d(layer_stack=layer_stack)
s.show()