Examples of the application in silicon photonics design
A simple IPKISS script : generation of circular and elliptic arcs on GDS layer 0 and export of the structure to GDSII.
from ipkiss.all import *
import sys
from math import *
class ElementsExample(Structure):
def define_elements(self, elems):
for i in range (5, 50, 5):
#circular arc
elems += ArcPath(layer = Layer(0), center = (0,0),
radius = i, start_angle = 0,
end_angle = 120, line_width = 1.0)
#elliptical_arc
elems += EllipseArcPath(layer = Layer(0), center = (120,0),
box_size = (2 * i, i) , start_angle = 45,
end_angle = 270, line_width = 1.0)
return elems
layout = ElementsExample(name = "layout")
my_lib = Library(name = "ELEMENTS", unit = 1E-6, grid = 5E-9)
my_lib += layout
o= FileOutputGdsii("example_elements.gds")
o.write(my_lib)
The GDSII file looks as follows :
Definition of a simple ring resonator with access waveguide using the IPKISS photonics plug-in : from ipkiss.plugins.photonics.technology.default import *
from ipkiss.plugins.photonics.wg.basic import *
from ipkiss.plugins.photonics.port import *
from ipkiss.all import * class MyRing ( Structure ): radius = PositiveNumberProperty ( default = TECH . WG . BEND_RADIUS ) spacing = PositiveNumberProperty ( default = TECH . WG . WIRE_WIDTH * 4.0 ) wg_definition = WgDefProperty ( default = TECH . WGDEF . WIRE )
#specify the elements making up the layout
def define_elements ( self , elems ):
#the ring c = ShapeCircle ( center = ( 0.0 , 0.0 ), radius = self . radius , start_face_angle = 90.0 , end_face_angle = 90.0 )
#the access waveguide ( w_y_co , w_half_length ) = self . get_access_waveguide_specs () w = Shape ([( - w_half_length , w_y_co ), ( w_half_length , w_y_co )])
#compose to the elements elems += self . wg_definition ( shape = c ) elems += self . wg_definition ( shape = w ) return elems
#define the input/output ports
def define_ports ( self , ports ): ( w_y_co , w_half_length ) = self . get_access_waveguide_specs () ports += InOpticalPort ( position = ( - w_half_length , w_y_co ), angle = 180.0 , wg_definition = self . wg_definition ) ports += OutOpticalPort ( position = ( w_half_length , w_y_co ), angle = 0.0 , wg_definition = self . wg_definition ) return ports
#'w_y_co' and 'w_half_length' are needed in both
#'define_elements' and 'define_ports' . Therefore make seperate function.
def get_access_waveguide_specs ( self ): w_y_co = - self . radius - self . spacing w_half_length = self . radius + self . wg_definition . trench_width return ( w_y_co , w_half_length )
wg_def = WgElDefinition ( wg_width = 0.60 , trench_width = 0.8 )
r = MyRing ( radius = 5.0 , wg_definition = wg_def )
r . write_gdsii ( "my_ring.gds" )
The GDSII file looks as follows :
Manhattan routing between two MMI's and a ring resonator from the Picazzo component library. Virtual fabrication and 2D visualizationof the this structure.
from technologies.si_photonics.picazzo.default import *
from ipkiss.all import *
from ipkiss.plugins.photonics.routing import *
from ipkiss.plugins.photonics.wg import *
from ipkiss.plugins.vfabrication import *
from picazzo.filters.mmi import Mmi1x2Tapered
from picazzo.filters.ring import RingRectNotchFilter
class MyDesign(Structure):
position_mmi_1 = Coord2Property(required = True)
position_mmi_2 = Coord2Property(required = True)
position_ring = Coord2Property(required = True)
def define_elements(self, elems):
#create the two MMI's
mmi_1 = SRef(reference = Mmi1x2Tapered(width = 2.8,
length = 8.98,
wg_offset = 0.67, taper_width = 0.8),
position = self.position_mmi_1)
mmi_2 = SRef(reference = Mmi1x2Tapered(width = 4.8,
length = 12.14,
wg_offset = 0.50, taper_width = 0.7),
position = self.position_mmi_2)
elems += mmi_1
elems += mmi_2
#create the route from the 1st MMI to the 2nd MMI
route_mmi = RouteManhattan(input_port = mmi_1.ports["E1"],
output_port = mmi_2.ports["W0"])
elems += RouteConnectorRoundedExpanded(route_mmi)
#create the ring resonator
ring = SRef(
reference = RingRectNotchFilter(
ring_wg_definition = WgElDefinition(wg_width = 0.5),
coupler_wg_definitions = [WgElDefinition(wg_width = 0.4)],
coupler_spacings = [0.65],
straights=(TECH.WG.SHORT_STRAIGHT,TECH.WG.SHORT_STRAIGHT+3.0), ),
position = self.position_ring)
elems += ring
#create the route from the 1st MMI to the ring resonator
route_ring = RouteManhattan(input_port = mmi_1.ports["E0"],
output_port = ring.ports["W0"])
elems += RouteConnectorRoundedExpanded(route_ring)
return elems
d = MyDesign(position_mmi_1 = (0.0,50.0),
position_mmi_2 = (60.0,70.0),
position_ring = (60.0,30.0))
d. write_gdsii("design.gds")
d. visualize_2d()
Virtual fabrication (2D) the looks as follows :
Simulation of an MMI aperture in Meep FDTD : Ipkiss is used to export a geometry specification to Meep and launch the simulation in a convenient way with the correct parameters.
From the IPKISS script, we can export a GDSII mask layout :
Secondly, we run a virtual fabrication. Using Pysimul, we add a source and fluxplanes. The mode profile of the source is shaped according to the ground mode of the input port (calculated with CAMFR):
We then export the geometry to Meep :
Finally, we launch an FDTD simulation in Meep with the necessary parameters.
|