From d42fcaffd76e9f614d3f83a3ce2d5bcae3e7967c Mon Sep 17 00:00:00 2001 From: Lukas Chrostowski Date: Tue, 24 Jan 2023 00:13:06 -0800 Subject: [PATCH] SiN layer and library - SiN library for 895 nm components - SiN Waveguide definition Former-commit-id: feaf4f8c6d058e4fd93fefef189c23c5001e1db9 --- .../{klayout_Layers_EBeam.lyp => EBeam.lyp} | 24 +-- klayout/EBeam/EBeam.lyt | 4 +- klayout/EBeam/WAVEGUIDES.xml | 18 +++ klayout/EBeam/gds/EBeam_SiN/ebeam_BondPad.gds | Bin 0 -> 844 bytes .../pymacros/SiEPIC_EBeam_Library_SiN.lym | 103 ++++++++++++ .../pcells_SiN/ebeam_dc_SiN_TE_895.py | 147 ++++++++++++++++++ 6 files changed, 284 insertions(+), 12 deletions(-) rename klayout/EBeam/{klayout_Layers_EBeam.lyp => EBeam.lyp} (97%) create mode 100644 klayout/EBeam/gds/EBeam_SiN/ebeam_BondPad.gds create mode 100644 klayout/EBeam/pymacros/SiEPIC_EBeam_Library_SiN.lym create mode 100644 klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py diff --git a/klayout/EBeam/klayout_Layers_EBeam.lyp b/klayout/EBeam/EBeam.lyp similarity index 97% rename from klayout/EBeam/klayout_Layers_EBeam.lyp rename to klayout/EBeam/EBeam.lyp index 18076d64..b91a9979 100644 --- a/klayout/EBeam/klayout_Layers_EBeam.lyp +++ b/klayout/EBeam/EBeam.lyp @@ -15,7 +15,7 @@ false false 0 - Waveguides (silicon) + Waveguides */*@* @@ -34,23 +34,24 @@ 1/0@1 2.0 - + - #ff0000 - #ff0000 + #a6cee3 + #a6cee3 0 0 - I9 + I6 true true - false - 1 + true + false 0 - 31_Si_p6nm - 31/0@1 + SiN + 1/5@1 + 2.0 - + #80a8ff #80a8ff @@ -479,3 +480,6 @@ + + + diff --git a/klayout/EBeam/EBeam.lyt b/klayout/EBeam/EBeam.lyt index 6bc6d99c..16d03381 100644 --- a/klayout/EBeam/EBeam.lyt +++ b/klayout/EBeam/EBeam.lyt @@ -5,8 +5,8 @@ 0.001 - /Users/lukasc/Documents/GitHub/SiEPIC_EBeam_PDK/klayout_dot_config/tech/EBeam - klayout_Layers_EBeam.lyp + /Users/lukasc/Documents/GitHub/SiEPIC_EBeam_PDK/klayout/EBeam + EBeam.lyp true diff --git a/klayout/EBeam/WAVEGUIDES.xml b/klayout/EBeam/WAVEGUIDES.xml index bedfbf6d..84fc32f3 100755 --- a/klayout/EBeam/WAVEGUIDES.xml +++ b/klayout/EBeam/WAVEGUIDES.xml @@ -239,4 +239,22 @@ opt2 + + SiN Strip TE 895 nm, w=450 nm + EBeam + none + 0.20 + 15.0 + 0.45 + + SiN + 0.45 + 0.0 + + + DevRec + 1.5 + 0.0 + + \ No newline at end of file diff --git a/klayout/EBeam/gds/EBeam_SiN/ebeam_BondPad.gds b/klayout/EBeam/gds/EBeam_SiN/ebeam_BondPad.gds new file mode 100644 index 0000000000000000000000000000000000000000..f5decb055a19acb64257f01ef961f40bba56742d GIT binary patch literal 844 zcmZQzV_;&6V31*CVt>lO&LGFY$e_<4i_B)=Vq$Z3N=?jVU=U$uwR7w=_dd4#gQd$3 z{ROk5LKtLNaqHw`V{^*SO9@C!Q88p-VBuh3VB=+C;9+3nV`5-n&=Ft;k_f=qwtxW{ zBV>Sj1rhprk@a&PVPJq_#+o|}$QULLqQUyv8SuJRh>a~Z3FyywsGET{axpOQ2_gG| zO^OldEFKwFr!7$D@qm1BH~@^nws1mx$q05OHv^j@$gdpyKvh;V7(`%xKJ*5n|L_)w z+lbNi|G%vWNZ0@WHa^7ZLeT-zN~8;sTnE?11NWC069dp+kdTmOb&#A10<##vApuej z3=KX>w%quF%)I!L`~s-0#Oeq7ZUch=On*{-NlAV##NC8V0LDuc$OS+EbPd=f5F75A eoYb@u^2~z7G0-fy%Zf77GfJR-1Ewq%76t%aT6PTp literal 0 HcmV?d00001 diff --git a/klayout/EBeam/pymacros/SiEPIC_EBeam_Library_SiN.lym b/klayout/EBeam/pymacros/SiEPIC_EBeam_Library_SiN.lym new file mode 100644 index 00000000..3240d693 --- /dev/null +++ b/klayout/EBeam/pymacros/SiEPIC_EBeam_Library_SiN.lym @@ -0,0 +1,103 @@ + + + + + pymacros + + + + true + false + 0 + + false + + + python + + """ +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() + + diff --git a/klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py b/klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py new file mode 100644 index 00000000..e59328cd --- /dev/null +++ b/klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py @@ -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) ) +