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 |
Show code cell source
from IPython.display import Code
import gdsfactory as gf
from gdsfactory.config import PATH
from gdsfactory.generic_tech import LAYER_STACK, get_generic_pdk
from gdsfactory.generic_tech.get_klayout_pyxs import get_klayout_pyxs
from gdsfactory.technology import LayerLevel, LayerMap, LayerStack, LayerViews
from gdsfactory.typings import Layer
class LAYER(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 = (999, 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.WG
<LAYER.WG: 1>
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.
PDK = get_generic_pdk()
PDK.activate()
LAYER_VIEWS = PDK.layer_views
c = LAYER_VIEWS.preview_layerset()
c.plot()
extract = c.extract(layers=((41, 0), (40, 0)))
extract.plot()
Remove layers#
You can remove layers using the remove_layers()
function.
removed = extract.remove_layers(layers=((40, 0),))
removed.plot()
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()
remap = c.remap_layers({(2, 0): (34, 0)})
remap.plot()
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: solid
width: 1
color: "#cc4c00"
VIA1:
layer: [44, 0]
layer_in_name: true
hatch_pattern: solid
width: 1
color: "grey"
VIA2:
layer: [43, 0]
layer_in_name: true
hatch_pattern: solid
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: "gray"
Errors:
layer: [69, 0]
hatch_pattern: hollow
width: 1
color: "gray"
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: [999, 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()
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()
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: coarsely dotted
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()
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.
Lets define the layer stack for the generic layers in the generic_technology.
import gdsfactory as gf
from gdsfactory.generic_tech.layer_map import LAYER
from gdsfactory.technology import LogicalLayer
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()