-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- SiN library for 895 nm components - SiN Waveguide definition Former-commit-id: feaf4f8
- Loading branch information
1 parent
d836bb4
commit d42fcaf
Showing
6 changed files
with
284 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
147
klayout/EBeam/pymacros/pcells_SiN/ebeam_dc_SiN_TE_895.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) ) | ||
|