Skip to content

Commit

Permalink
SiN layer and library
Browse files Browse the repository at this point in the history
- SiN library for 895 nm components
- SiN Waveguide definition


Former-commit-id: feaf4f8
  • Loading branch information
lukasc-ubc committed Jan 24, 2023
1 parent d836bb4 commit d42fcaf
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 12 deletions.
24 changes: 14 additions & 10 deletions klayout/EBeam/klayout_Layers_EBeam.lyp → klayout/EBeam/EBeam.lyp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<marked>false</marked>
<xfill>false</xfill>
<animation>0</animation>
<name>Waveguides (silicon)</name>
<name>Waveguides</name>
<source>*/*@*</source>

<group-members>
Expand All @@ -34,23 +34,24 @@
<source>1/0@1</source>
<width>2.0</width>
</group-members>

<group-members>
<frame-color>#ff0000</frame-color>
<fill-color>#ff0000</fill-color>
<frame-color>#a6cee3</frame-color>
<fill-color>#a6cee3</fill-color>
<frame-brightness>0</frame-brightness>
<fill-brightness>0</fill-brightness>
<dither-pattern>I9</dither-pattern>
<dither-pattern>I6</dither-pattern>
<valid>true</valid>
<visible>true</visible>
<transparent>false</transparent>
<width>1</width>
<transparent>true</transparent>
<width/>
<marked>false</marked>
<animation>0</animation>
<name>31_Si_p6nm</name>
<source>31/0@1</source>
<name>SiN</name>
<source>1/5@1</source>
<width>2.0</width>
</group-members>

<group-members>
<frame-color>#80a8ff</frame-color>
<fill-color>#80a8ff</fill-color>
Expand Down Expand Up @@ -479,3 +480,6 @@
</properties>
<name/>
</layer-properties>



4 changes: 2 additions & 2 deletions klayout/EBeam/EBeam.lyt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<group/>
<dbu>0.001</dbu>
<base-path/>
<original-base-path>/Users/lukasc/Documents/GitHub/SiEPIC_EBeam_PDK/klayout_dot_config/tech/EBeam</original-base-path>
<layer-properties_file>klayout_Layers_EBeam.lyp</layer-properties_file>
<original-base-path>/Users/lukasc/Documents/GitHub/SiEPIC_EBeam_PDK/klayout/EBeam</original-base-path>
<layer-properties_file>EBeam.lyp</layer-properties_file>
<add-other-layers>true</add-other-layers>
<reader-options>
<gds2>
Expand Down
18 changes: 18 additions & 0 deletions klayout/EBeam/WAVEGUIDES.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,22 @@
<taper_pin_mm>opt2</taper_pin_mm>
</compound_waveguide>
</waveguide>
<waveguide>
<name>SiN Strip TE 895 nm, w=450 nm</name>
<CML>EBeam</CML>
<model>none</model>
<bezier>0.20</bezier>
<radius>15.0</radius>
<width>0.45</width>
<component>
<layer>SiN</layer>
<width>0.45</width>
<offset>0.0</offset>
</component>
<component>
<layer>DevRec</layer>
<width>1.5</width>
<offset>0.0</offset>
</component>
</waveguide>
</waveguides>
Binary file added klayout/EBeam/gds/EBeam_SiN/ebeam_BondPad.gds
Binary file not shown.
103 changes: 103 additions & 0 deletions klayout/EBeam/pymacros/SiEPIC_EBeam_Library_SiN.lym
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<klayout-macro>
<description/>
<version/>
<category>pymacros</category>
<prolog/>
<epilog/>
<doc/>
<autorun>true</autorun>
<autorun-early>false</autorun-early>
<priority>0</priority>
<shortcut/>
<show-in-menu>false</show-in-menu>
<group-name/>
<menu-path/>
<interpreter>python</interpreter>
<dsl-interpreter-name/>
<text>"""
This file is part of the SiEPIC_EBeam_PDK

This file implements a library called "EBeam-SiN", for silicon nitride
"""
print('siepic_ebeam_library_SiN')

import pya
from pya import *
from SiEPIC.utils import get_technology_by_name
import os
import pathlib
import sys

dir_path = os.path.dirname(os.path.realpath(__file__))
if dir_path not in sys.path:
sys.path.append(dir_path)

files = [f for f in os.listdir(os.path.join(os.path.dirname(
os.path.realpath(__file__)),'pcells_SiN')) if '.py' in pathlib.Path(f).suffixes and '__init__' not in f]
import pcells_SiN ### folder name ###
import importlib
importlib.invalidate_caches()
pcells_=[]
for f in files:
module = 'pcells_SiN.%s' % f.replace('.py','') ### folder name ###
print(' - found module: %s' % module)
m = importlib.import_module(module)
print(m)
pcells_.append(importlib.reload(m))


class siepic_ebeam_library_hubbard(Library):
"""
The library where we will put the PCells and GDS into
"""

def __init__(self):

tech_name = 'EBeam'
library = tech_name +'-SiN'
self.technology=tech_name

print("Initializing '%s' Library." % library)

# Set the description
self.description = "Silicon Nitride"

# Save the path, used for loading WAVEGUIDES.XML
import os
self.path = os.path.dirname(os.path.realpath(__file__))

# Import all the GDS files from the tech folder
import os, fnmatch
dir_path = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../gds/EBeam_SiN"))
print(' library path: %s' % dir_path)
search_str = '*.[Oo][Aa][Ss]' # OAS
for root, dirnames, filenames in os.walk(dir_path, followlinks=True):
for filename in fnmatch.filter(filenames, search_str):
file1=os.path.join(root, filename)
print(" - reading %s" % file1 )
self.layout().read(file1)
search_str = '*.[Gg][Dd][Ss]' # GDS
for root, dirnames, filenames in os.walk(dir_path, followlinks=True):
for filename in fnmatch.filter(filenames, search_str):
file1=os.path.join(root, filename)
print(" - reading %s" % file1 )
self.layout().read(file1)

# Create the PCell declarations
for m in pcells_:
mm = m.__name__.replace('pcells_SiN.','')
mm2 = m.__name__+'.'+mm+'()'
print(' - register_pcell %s, %s' % (mm,mm2))
self.layout().register_pcell(mm, eval(mm2))

print(' done with pcells')

# Register us the library with the technology name
# If a library with that name already existed, it will be replaced then.
self.register(library)

# Instantiate and register the library
siepic_ebeam_library_hubbard()
</text>
</klayout-macro>
147 changes: 147 additions & 0 deletions klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import pya
from pya import *

class ebeam_dc_SiN_TE_895(pya.PCellDeclarationHelper):
"""
The PCell declaration for the Directional Coupler
by Lukas Chrostowski, 2018/09
compact model in INTERCONNECT based on:
- https://kx.lumerical.com/t/lcml-directional-coupler-based-on-lookup-table-lcml-dc-strip-1550-lookuptable/2094
- only parameterized for Lc, for the 500 x 220 nm waveguide with 200 nm gap, and 5 micron radius
could be improved:
- https://kx.lumerical.com/t/lcml-directional-coupler-based-on-analytical-functions-lcml-dc-strip-1550-analytical/2091
- updated for SiN at 895 nm
"""

def __init__(self):

# Important: initialize the super class
super(ebeam_dc_SiN_TE_895, self).__init__()
from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')

# declare the parameters
self.param("Lc", self.TypeDouble, "Coupler Length", default = 20.0)
self.param("silayer", self.TypeLayer, "SiN Layer", default = TECHNOLOGY['SiN'])
self.param("pinrec", self.TypeLayer, "PinRec Layer", default = TECHNOLOGY['PinRec'])
self.param("devrec", self.TypeLayer, "DevRec Layer", default = TECHNOLOGY['DevRec'])
self.param("textl", self.TypeLayer, "Text Layer", default = LayerInfo(10, 0))

def display_text_impl(self):
# Provide a descriptive text for the cell
return "ebeam_dc_SiN_TE_895(Lc=" + ('%.3f' % self.Lc) + ")"

def can_create_from_shape_impl(self):
return False

def produce_impl(self):
# This is the main part of the implementation: create the layout

# Fixed PCell parameters
port_spacing = 2000 # spacing of the two ports, determines the angle required by the s-bend.
r = 25000 # radius
w = 450 # waveguide width
g = 400 # gap

from math import pi, cos, sin, acos
from SiEPIC.utils import arc_wg, arc_wg_xy
from SiEPIC._globals import PIN_LENGTH

# fetch the parameters
dbu = self.layout.dbu
ly = self.layout
shapes = self.cell.shapes
LayerSiN = ly.layer(self.silayer)
LayerPinRecN = ly.layer(self.pinrec)
LayerDevRecN = ly.layer(self.devrec)
TextLayerN = ly.layer(self.textl)

Lc = int(round(self.Lc/dbu))

# Create the parallel waveguides
if Lc > 0:
wg1 = Box(-Lc/2, -w/2+(w+g)/2, Lc/2, w/2+(w+g)/2)
shapes(LayerSiN).insert(wg1)
wg1 = Box(-Lc/2, -w/2-(w+g)/2, Lc/2, w/2-(w+g)/2)
shapes(LayerSiN).insert(wg1)

dc_angle = acos((r-abs(port_spacing/2))/r)*180/pi

# bottom S-bends
self.cell.shapes(LayerSiN).insert(arc_wg_xy(Lc/2,-r-(w+g)/2, r, w, 90-dc_angle, 90))
self.cell.shapes(LayerSiN).insert(arc_wg_xy(-Lc/2, -r-(w+g)/2, r, w, 90, 90+dc_angle))
y_bottom = round(-2*(1-cos(dc_angle/180.0*pi))*r)-(w+g)/2
x_bottom = round(2*sin(dc_angle/180.0*pi)*r)
t = Trans(Trans.R0,-x_bottom-Lc/2, y_bottom+r)
self.cell.shapes(LayerSiN).insert(arc_wg(r, w, -90, -90+dc_angle).transformed(t))
t = Trans(Trans.R0,x_bottom+Lc/2, y_bottom+r)
self.cell.shapes(LayerSiN).insert(arc_wg(r, w, -90-dc_angle, -90).transformed(t))

# top S-bends
self.cell.shapes(LayerSiN).insert(arc_wg_xy(Lc/2,r+(w+g)/2, r, w, 270, 270+dc_angle))
self.cell.shapes(LayerSiN).insert(arc_wg_xy(-Lc/2, r+(w+g)/2, r, w, 270-dc_angle, 270))
y_top = round(2*(1-cos(dc_angle/180.0*pi))*r)+(w+g)/2
x_top = round(2*sin(dc_angle/180.0*pi)*r)
t = Trans(Trans.R0,-x_top-Lc/2, y_top-r)
self.cell.shapes(LayerSiN).insert(arc_wg(r, w, 90-dc_angle, 90).transformed(t))
t = Trans(Trans.R0,x_top+Lc/2, y_top-r)
self.cell.shapes(LayerSiN).insert(arc_wg(r, w, 90, 90+dc_angle).transformed(t))

# Pins on the bottom waveguide side:
pin = Path([Point(-x_bottom+PIN_LENGTH/2-Lc/2, y_bottom), Point(-x_bottom-PIN_LENGTH/2-Lc/2, y_bottom)], w)
shapes(LayerPinRecN).insert(pin)
text = Text ("pin1", Trans(Trans.R0, -x_bottom-Lc/2, y_bottom))
shape = shapes(LayerPinRecN).insert(text)
shape.text_size = 0.4/dbu

pin = Path([Point(x_bottom-PIN_LENGTH/2+Lc/2, y_bottom), Point(x_bottom+PIN_LENGTH/2+Lc/2, y_bottom)], w)
shapes(LayerPinRecN).insert(pin)
text = Text ("pin3", Trans(Trans.R0, x_bottom+Lc/2, y_bottom))
shape = shapes(LayerPinRecN).insert(text)
shape.text_size = 0.4/dbu
shape.text_halign = 2

# Pins on the top waveguide side:
pin = Path([Point(-x_bottom+PIN_LENGTH/2-Lc/2, y_top), Point(-x_bottom-PIN_LENGTH/2-Lc/2, y_top)], w)
shapes(LayerPinRecN).insert(pin)
text = Text ("pin2", Trans(Trans.R0, -x_bottom-Lc/2, y_top))
shape = shapes(LayerPinRecN).insert(text)
shape.text_size = 0.4/dbu

pin = Path([Point(x_bottom-PIN_LENGTH/2+Lc/2, y_top), Point(x_bottom+PIN_LENGTH/2+Lc/2, y_top)], w)
shapes(LayerPinRecN).insert(pin)
text = Text ("pin4", Trans(Trans.R0, x_bottom+Lc/2, y_top))
shape = shapes(LayerPinRecN).insert(text)
shape.text_size = 0.4/dbu
shape.text_halign = 2

# Merge all the waveguide shapes, to avoid any small gaps
layer_temp = self.layout.layer(LayerInfo(913, 0))
shapes_temp = self.cell.shapes(layer_temp)
ShapeProcessor().merge(self.layout,self.cell,LayerSiN,shapes_temp,True,0,True,True)
self.cell.shapes(LayerSiN).clear()
shapes_SiN = self.cell.shapes(LayerSiN)
ShapeProcessor().merge(self.layout,self.cell,layer_temp, shapes_SiN,True,0,True,True)
self.cell.shapes(layer_temp).clear()

# Create the device recognition layer -- make it 1 * wg_width away from the waveguides.
dev = Box(-x_bottom-Lc/2, y_bottom-w/2-w, x_bottom+Lc/2, y_top+w/2+w )
shapes(LayerDevRecN).insert(dev)

# Compact model information
t = Trans(Trans.R0, 0, -w)
text = Text ("Lumerical_INTERCONNECT_library=Design kits/EBeam", t)
shape = shapes(LayerDevRecN).insert(text)
shape.text_size = r*0.017
t = Trans(Trans.R0, 0, 0)
text = Text ('Component=ebeam_dc_te1550', t)
shape = shapes(LayerDevRecN).insert(text)
shape.text_size = r*0.017
t = Trans(Trans.R0, 0, w)
text = Text ('Spice_param:wg_width=%.3fu gap=%.3fu radius=%.3fu Lc=%.3fu'%(w*dbu,g*dbu,r*dbu,self.Lc), t)
shape = shapes(LayerDevRecN).insert(text)
shape.text_size = r*0.017

print("Done drawing the layout for - ebeam_dc_SiN_TE_895: %.3f" % ( self.Lc) )

0 comments on commit d42fcaf

Please sign in to comment.