Technology

image.png

A typical fabrication process for microelectronics or photonics involves many layers of materials and processing steps to create active and passive devices. A process design kit (PDK) provided by the foundry describes this fabrication process, allowing us to convert 2D layout files to 3D representation of devices needed for electromagnetic simulations. In PhotonForge, this information is stored as a Technology object.

Loading a Technology

PhotonForge makes it really easy to load a technology and customize it. Each available PDK includes a technology function that can be called to create a Technology object with the desired specifications.

As an example, we will use the SiEPIC OpenEBL PDK through the siepic_forge module.

[1]:
import photonforge as pf
import siepic_forge as siepic

The technology function in the siepic_forge module is called ebeam, which defines the various layers, materials, thicknesses, and ports that we can use to build devices in this open-source platform.

If we want to, we can inspect the function to find out which parameters can be set:

[2]:
siepic.ebeam?

The default parameters represent the normal fabrication process for SiEPIC e-beam runs, but we can change those defaults if we want to test process variations.

We use the defaults to configure our project:

[3]:
pf.config.default_technology = siepic.ebeam()

That’s it! In 3 lines, we have loaded SiEPIC’s e-beam PDK and configured it to be the default technology in this PhotonForge project.

Note: PhotonForge supports a growing list of PDKs, and we are happy to assist you in creating your own custom technology if you require a specific process!

Technology Contents

Now that we have loaded the e-beam PDK, we can inspect this technology to find its definitions. Besides a name and version, all technologies contain 4 main attributes:

In most cases, the layer and port dictionaries are the most used when creating components. These are the layers defined in the SiEPIC e-beam PDK:

[4]:
pf.config.default_technology.layers
[4]:
{'BlackBox': LayerSpec(layer=(998, 0), description="SiEPIC", color="#00408018", pattern="solid"),
 'FDTD': LayerSpec(layer=(733, 0), description="SiEPIC", color="#80005718", pattern="hollow"),
 'FbrTgt': LayerSpec(layer=(81, 0), description="SiEPIC", color="#00408018", pattern="/"),
 'Errors': LayerSpec(layer=(999, 0), description="SiEPIC", color="#00008018", pattern="/"),
 'PinRecM': LayerSpec(layer=(1, 11), description="SiEPIC", color="#00408018", pattern="/"),
 'DevRec': LayerSpec(layer=(68, 0), description="SiEPIC", color="#00408018", pattern="hollow"),
 'Chip design area': LayerSpec(layer=(290, 0), description="Misc", color="#80005718", pattern="hollow"),
 'Dicing': LayerSpec(layer=(210, 0), description="Misc", color="#a0a0c018", pattern="solid"),
 'Deep Trench': LayerSpec(layer=(201, 0), description="Misc", color="#c0c0c018", pattern="solid"),
 'FloorPlan': LayerSpec(layer=(99, 0), description="Misc", color="#8000ff18", pattern="hollow"),
 'PinRec': LayerSpec(layer=(1, 10), description="SiEPIC", color="#00408018", pattern="/"),
 'Waveguide': LayerSpec(layer=(1, 99), description="Waveguides", color="#ff80a818", pattern="\"),
 'SiN': LayerSpec(layer=(1, 5), description="Waveguides", color="#a6cee318", pattern="\\"),
 'M_Open': LayerSpec(layer=(13, 0), description="Metal", color="#00000018", pattern="xx"),
 'Si': LayerSpec(layer=(1, 0), description="Waveguides", color="#ff80a818", pattern="\\"),
 'M2_router': LayerSpec(layer=(12, 0), description="Metal", color="#3471eb18", pattern="xx"),
 'SEM': LayerSpec(layer=(200, 0), description="Misc", color="#ff00ff18", pattern="\"),
 'VC': LayerSpec(layer=(40, 0), description="Metal", color="#3a027f18", pattern="xx"),
 'Keep out': LayerSpec(layer=(202, 0), description="Misc", color="#a0a0c018", pattern="//"),
 'Si slab': LayerSpec(layer=(2, 0), description="Waveguides", color="#80a8ff18", pattern="/"),
 'Si_Litho193nm': LayerSpec(layer=(1, 69), description="Waveguides", color="#cc80a818", pattern="\"),
 'Text': LayerSpec(layer=(10, 0), description="", color="#0000ff18", pattern="\"),
 'Si N': LayerSpec(layer=(20, 0), description="Doping", color="#7000ff18", pattern="\\"),
 'Si N++': LayerSpec(layer=(24, 0), description="Doping", color="#0000ff18", pattern=":"),
 'Oxide open (to BOX)': LayerSpec(layer=(6, 0), description="Waveguides", color="#ffae0018", pattern="\"),
 'M1_heater': LayerSpec(layer=(11, 0), description="Metal", color="#ebc63418", pattern="xx")}

Any place where a layer must be specified will accept a layer name instead of the layer tuple and use this dictionary to match the name. More information about layers can be found in the layers guide.

Similarly, we can take a look at the available ports:

[5]:
pf.config.default_technology.ports
[5]:
{'SiN_TE_1310_750': PortSpec(description="SiN Strip TE 1310 nm, w=750 nm", width=3, limits=(-1, 1.4), num_modes=1, polarization="", target_neff=2.1, path_profiles={(0.75, 0, (1, 5))}),
 'TE_1550_500': PortSpec(description="Strip TE 1550 nm, w=500 nm", width=2, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(0.5, 0, (1, 0))}),
 'TE_1310_410': PortSpec(description="Strip TE 1310 nm, w=410 nm", width=2, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(0.41, 0, (1, 0))}),
 'SiN_TE_895_450': PortSpec(description="SiN Strip TE 895 nm, w=450 nm", width=4, limits=(-2, 2.4), num_modes=2, polarization="", target_neff=2.1, path_profiles={(0.45, 0, (1, 5))}),
 'SiN_TM_1310_750': PortSpec(description="SiN Strip TM 1310 nm, w=750 nm", width=3, limits=(-1.5, 1.9), num_modes=2, polarization="", target_neff=2.1, path_profiles={(0.75, 0, (1, 5))}),
 'TE_1310_350': PortSpec(description="Strip TE 1310 nm, w=350 nm", width=2, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(0.35, 0, (1, 0))}),
 'TM_1550_500': PortSpec(description="Strip TM 1550 nm, w=500 nm", width=2.5, limits=(-1, 1.22), num_modes=2, polarization="", target_neff=3.5, path_profiles={(0.5, 0, (1, 0))}),
 'SiN_TM_1550_1000': PortSpec(description="SiN Strip TM 1550 nm, w=1000 nm", width=3, limits=(-1.5, 1.9), num_modes=2, polarization="", target_neff=2.1, path_profiles={(1, 0, (1, 5))}),
 'SiN_TE_1550_1000': PortSpec(description="SiN Strip TE 1550 nm, w=1000 nm", width=3, limits=(-1, 1.4), num_modes=1, polarization="", target_neff=2.1, path_profiles={(1, 0, (1, 5))}),
 'SiN_TE_1550_800': PortSpec(description="SiN Strip TE 1550 nm, w=800 nm", width=3, limits=(-1, 1.4), num_modes=1, polarization="", target_neff=2.1, path_profiles={(0.8, 0, (1, 5))}),
 'Rib_TE_1550_500': PortSpec(description="Rib (90 nm slab) TE 1550 nm, w=500 nm", width=2.5, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(3, 0, (2, 0)), (0.5, 0, (1, 0))}),
 'TE-TM_1550_450': PortSpec(description="Strip TE-TM 1550, w=450 nm", width=2, limits=(-1, 1.22), num_modes=2, polarization="", target_neff=3.5, path_profiles={(0.45, 0, (1, 0))}),
 'Rib_TE_1310_350': PortSpec(description="Rib (90 nm slab) TE 1310 nm, w=350 nm", width=2.35, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(3, 0, (2, 0)), (0.35, 0, (1, 0))}),
 'MM_TE_1550_2000': PortSpec(description="Multimode Strip TE 1550 nm, w=2000 nm", width=6, limits=(-2, 2.22), num_modes=10, polarization="", target_neff=3.5, path_profiles={(2, 0, (1, 0))}),
 'MM_TE_1550_3000': PortSpec(description="Multimode Strip TE 1550 nm, w=3000 nm", width=6, limits=(-2, 2.22), num_modes=14, polarization="", target_neff=3.5, path_profiles={(3, 0, (1, 0))}),
 'MM_SiN_TE_1550_3000': PortSpec(description="Multimode SiN Strip TE 1550 nm, w=3000 nm", width=8, limits=(-2.5, 2.9), num_modes=6, polarization="", target_neff=2.1, path_profiles={(3, 0, (1, 5))}),
 'Slot_TE_1550_500': PortSpec(description="Slot TE 1550 nm, w=500 nm, gap=100nm", width=2, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(0.2, 0.15, (1, 0)), (0.2, -0.15, (1, 0))}),
 'eskid_TE_1550': PortSpec(description="eskid TE 1550", width=3.31, limits=(-1, 1.22), num_modes=1, polarization="", target_neff=3.5, path_profiles={(0.06, 0.625, (1, 0)), (0.06, 0.505, (1, 0)), (0.06, -0.625, (1, 0)), (0.06, -0.505, (1, 0)), (0.06, 0.385, (1, 0)), (0.06, -0.265, (1, 0)), (0.06, 0.265, (1, 0)), (0.06, -0.385, (1, 0)), (0.35, 0, (1, 0))}),
 'SiN_TE_1550_750': PortSpec(description="SiN Strip TE 1550 nm, w=750 nm", width=3, limits=(-1, 1.4), num_modes=1, polarization="", target_neff=2.1, path_profiles={(0.75, 0, (1, 5))})}

If required, new port specifications can also be included to allow us to work with custom waveguide interconnections.