def _generate_instances(self, insts): # edge coupler fname = '../josep/thermo_optic_phase_shifter.gds' heater_gds_lay = i3.GDSCell(filename=fname).Layout() insts += i3.SRef(name=self.name + '_HEAT', reference=heater_gds_lay) return insts
def _generate_instances(self, insts): # edge coupler fname = os.path.dirname( os.path.realpath(__file__)) + '/gds/aim_edge_coupler_si.gds' edge_coupler_gds_lay = i3.GDSCell(filename=fname).Layout() insts += i3.SRef(name=self.name + '_EDGE_COUPLER', reference=edge_coupler_gds_lay, flatten=True) return insts
def _generate_instances(self, insts): # Generates taper pairs tp_name_list = [] # temporary? pick taper properties taper_prop_dict = { 'length': 79.0, 'width1': 0.50, 'width2': 6.50, 'width_etch': 2.0 } # generate a huge taper row tp_rows_layout = TaperPairRow().Layout( taper_prop_dict=taper_prop_dict, connect_length=0.0, pair_connect_length=10.0, n_pairs=self.n_pairs) # load the aim gds just to get its positions and stuff # main chip GDS fname = os.path.dirname( os.path.realpath(__file__)) + '/gds/ap_suny_v20a_chipframe.gds' main_chip_gds_cell = i3.GDSCell(filename=fname) # grab layout size info main_chip_gds_lay = main_chip_gds_cell.Layout() main_chip_gds_lay_size_info = main_chip_gds_lay.size_info() # grab relevant positions chip_edge_east = main_chip_gds_lay_size_info.east chip_edge_west = main_chip_gds_lay_size_info.west # make edge coupler and add to layout # edge coupler edge_coupler_gds_lay = EdgeCoupler(name=self.name + 'edge_coupler_si').Layout() # add and route input/west edgecoupler # position edge coupler on west side of chip chip_port_west = i3.OpticalPort(position=(chip_edge_west, 0.0), angle_deg=0.0) edge_coupler_west_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_west_port, chip_port_west) edge_coupler_west_name = self.name + '_EDGE_COUPLER_WEST' west_edge_coupler = i3.SRef(name=edge_coupler_west_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], west_edge_coupler.ports['in']) lin_taper_lay_name = self.name + '_EDGETAPER_WEST' insts += i3.SRef(name=lin_taper_lay_name, reference=lin_taper_lay, transformation=t, flatten=True) # add taper rows taper_row_name = self.name + '_TAPERSSSSSSSS' t = i3.vector_match_transform( tp_rows_layout.ports['left'], insts[lin_taper_lay_name].ports['out']) insts += i3.SRef(name=taper_row_name, reference=tp_rows_layout, transformation=t, flatten=True) # add east coupler chip_port_east = i3.OpticalPort(position=(chip_edge_east, 0.0), angle_deg=180.0) edge_coupler_east_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_east_port, chip_port_east, mirrored=True) edge_coupler_east_name = self.name + '_EDGE_COUPLER_EAST' east_edge_coupler = i3.SRef(name=edge_coupler_east_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], east_edge_coupler.ports['in'], mirrored=True) lin_taper_lay_name = self.name + '_EDGETAPER_EAST' insts += i3.SRef(name=lin_taper_lay_name, reference=lin_taper_lay, transformation=t, flatten=True) # route the east coupler to the east edge of the taper pairs route_wg_row_taper = i3.Shape([ insts[taper_row_name].ports['right'].position, insts[lin_taper_lay_name].ports['out'].position ]) wg_name = self.name + '_WG' wg_lay = i3.Waveguide(trace_template=StripWgTemplate(), name=wg_name).get_default_view(i3.LayoutView) wg_lay.set(shape=route_wg_row_taper) insts += i3.SRef(name=wg_name, reference=wg_lay, flatten=True) return insts
def _generate_instances(self, insts): # Generates a long ass row of gratings # serp_grating_layout = SerpGratingArray().get_default_view(i3.LayoutView) # serp_grating_layout.set( pitch = 0.5, # grat_wg_width = 6.5, # flyback_wg_width = 6.5, # grating_amp = grating_amps[i_row][i_col], # duty_cycle = duty_cycle, # period = period, # numrows = numrows_tx, # grating_type = grating_types[i_row][i_col], # length = 100.0 ) # load the aim gds just to get its positions and stuff # main chip GDS fname = '../PDK_Library_Layout_GDS/ap_suny_v20a_chipframe.gds' main_chip_gds_cell = i3.GDSCell(filename=fname) # grab layout size info main_chip_gds_lay = main_chip_gds_cell.Layout() main_chip_gds_lay_size_info = main_chip_gds_lay.size_info() # grab relevant positions chip_edge_east = main_chip_gds_lay_size_info.east chip_edge_west = main_chip_gds_lay_size_info.west # make edge coupler edge_coupler_gds_lay = EdgeCoupler( name=self.name + 'edge_coupler_mmmmffff').Layout() # add and route input/west edgecoupler # position edge coupler on west side of chip chip_port_west = i3.OpticalPort(position=(chip_edge_west, 0.0), angle_deg=0.0) edge_coupler_west_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_west_port, chip_port_west) edge_coupler_west_name = self.name + '_EDGE_COUPLER_WEST' west_edge_coupler = i3.SRef(name=edge_coupler_west_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], west_edge_coupler.ports['in']) lin_taper_lay_name = self.name + '_EDGETAPER_WEST' insts += i3.SRef(name=lin_taper_lay_name, reference=lin_taper_lay, transformation=t, flatten=True) # Hard code the tapers into here: (I hate hardcoding stuff, but no choice here) taper_length = 79.0 # 79 is the best according to deniz' sims width_etch = 4.0 wg_width = 0.5 taper_swg_lay_1 = ParabolicTaper( name=self.name + '_TAPER_1').get_default_view(i3.LayoutView) taper_swg_lay_1.set(length=taper_length, width1=wg_width, width2=self.grat_wg_width, width_etch=width_etch) taper_swg_name_1 = self.name + '_TAPER_1' t = i3.vector_match_transform( taper_swg_lay_1.ports['left'], insts[lin_taper_lay_name].ports['out']) insts += i3.SRef(name=taper_swg_name_1, reference=taper_swg_lay_1, transformation=t, flatten=True) # add grating array # make grating layout swg_l_name = self.name + '_SWG' if self.grating_type == 'one_sidewall': # single sidewall grating swg_l = SidewallGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, both_sides=False) elif self.grating_type == 'two_sidewalls': # double sidewall grating swg_l = SidewallGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, both_sides=True) elif self.grating_type == 'nitride_vertical_top': # nitride vertical grating, top layer swg_l = NitrideGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, grating_type='vertical', nitride_layer='top') elif self.grating_type == 'nitride_vertical_bottom': # nitride vertical grating, top layer swg_l = NitrideGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, grating_type='vertical', nitride_layer='bottom') elif self.grating_type == 'nitride_one_sidewall_top': # nitride vertical grating, top layer swg_l = NitrideGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, grating_type='one_sidewall', nitride_layer='top') elif self.grating_type == 'nitride_one_sidewall_bottom': # nitride vertical grating, top layer swg_l = NitrideGratingWg(name=swg_l_name).get_default_view( i3.LayoutView) swg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=self.grating_amp, wg_width=self.grat_wg_width, length=self.length, grating_type='one_sidewall', nitride_layer='bottom') # end getting grating layout # add waveguide instance t = i3.vector_match_transform( swg_l.ports['in'], insts[taper_swg_name_1].ports['right']) insts += i3.SRef(name=swg_l_name, reference=swg_l, transformation=t, flatten=True) # add east coupler chip_port_east = i3.OpticalPort(position=(chip_edge_east, 0.0), angle_deg=180.0) edge_coupler_east_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_east_port, chip_port_east, mirrored=True) edge_coupler_east_name = self.name + '_EDGE_COUPLER_EAST' east_edge_coupler = i3.SRef(name=edge_coupler_east_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], east_edge_coupler.ports['in'], mirrored=True) lin_taper_lay_name_east = self.name + '_EDGETAPER_EAST' insts += i3.SRef(name=lin_taper_lay_name_east, reference=lin_taper_lay, transformation=t, flatten=True) # east taper taper_swg_lay_2 = ParabolicTaper( name=self.name + '_TAPER_2').get_default_view(i3.LayoutView) taper_swg_lay_2.set(length=taper_length, width1=wg_width, width2=self.grat_wg_width, width_etch=width_etch) taper_swg_name_2 = self.name + '_TAPER_2' t = i3.vector_match_transform( taper_swg_lay_2.ports['left'], insts[lin_taper_lay_name_east].ports['out'], mirrored=True) insts += i3.SRef(name=taper_swg_name_2, reference=taper_swg_lay_2, transformation=t, flatten=True) # connect with fat waveguide, which is just a sidewall grating with no amp connect_len = insts[taper_swg_name_2].ports['right'].position[ 0] - insts[swg_l_name].ports['out'].position[0] fat_wg_l = SidewallGratingWg().get_default_view(i3.LayoutView) fat_wg_l_name = self.name + '_FAT_WG_CON' fat_wg_l.set(period=self.period, duty_cycle=self.duty_cycle, grating_amp=0.0, wg_width=self.grat_wg_width, length=connect_len, both_sides=False) t = i3.vector_match_transform(fat_wg_l.ports['in'], insts[swg_l_name].ports['out']) insts += i3.SRef(name=fat_wg_l_name, reference=fat_wg_l, transformation=t, flatten=True) return insts
def _generate_instances(self, insts): # Generates taper pairs w edge couplers # load the aim gds just to get its positions and stuff # main chip GDS fname = '../PDK_Library_Layout_GDS/ap_suny_v20a_chipframe.gds' main_chip_gds_cell = i3.GDSCell(filename=fname) # grab layout size info main_chip_gds_lay = main_chip_gds_cell.Layout() main_chip_gds_lay_size_info = main_chip_gds_lay.size_info() # grab relevant positions chip_edge_east = main_chip_gds_lay_size_info.east chip_edge_west = main_chip_gds_lay_size_info.west # make edge coupler edge_coupler_gds_lay = EdgeCoupler(name=self.name + 'edge_coupler_sffdfi').Layout() # add and route input/west edgecoupler # position edge coupler on west side of chip chip_port_west = i3.OpticalPort(position=(chip_edge_west, 0.0), angle_deg=0.0) edge_coupler_west_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_west_port, chip_port_west) edge_coupler_west_name = self.name + '_EDGE_COUPLER_WEST' west_edge_coupler = i3.SRef(name=edge_coupler_west_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], west_edge_coupler.ports['in']) lin_taper_lay_name = self.name + '_EDGETAPER_WEST' insts += i3.SRef(name=lin_taper_lay_name, reference=lin_taper_lay, transformation=t, flatten=True) # route wg to wg with arc bend_radius = 10.0 arc_center_1 = ( insts[lin_taper_lay_name].ports['out'].position[0], insts[lin_taper_lay_name].ports['out'].position[1] + bend_radius) route_wg_shape_arc1 = i3.ShapeArc(radius=bend_radius, angle_step=1.0, center=arc_center_1, start_angle=269.5, end_angle=0.5, closed=False, clockwise=False) wg_name_arc1 = self.name + '_ARC1' wg_lay_arc1 = i3.Waveguide(trace_template=StripWgTemplate(), name=wg_name_arc1).get_default_view( i3.LayoutView) wg_lay_arc1.set(shape=route_wg_shape_arc1) insts += i3.SRef(name=wg_name_arc1, reference=wg_lay_arc1, flatten=True) # add the bends bend_clip_lay = BendClip( name=self.name + '_BEND_CLIP').get_default_view(i3.LayoutView) bend_clip_lay.set(n_pairs=self.n_pairs) # add to insts bend_clip_lay_name = self.name + '_BEND_CLIP' t = i3.vector_match_transform(bend_clip_lay.ports['in'], insts[wg_name_arc1].ports['out']) insts += i3.SRef(name=bend_clip_lay_name, reference=bend_clip_lay, transformation=t, flatten=True) # add output bend arc_center_2 = ( insts[bend_clip_lay_name].ports['out'].position[0] + bend_radius, insts[bend_clip_lay_name].ports['out'].position[1]) route_wg_shape_arc2 = i3.ShapeArc(radius=bend_radius, angle_step=1.0, center=arc_center_2, start_angle=180.5, end_angle=89.5, closed=False, clockwise=True) wg_name_arc2 = self.name + '_ARC2' wg_lay_arc2 = i3.Waveguide(trace_template=StripWgTemplate(), name=wg_name_arc2).get_default_view( i3.LayoutView) wg_lay_arc2.set(shape=route_wg_shape_arc2) insts += i3.SRef(name=wg_name_arc2, reference=wg_lay_arc2, flatten=True) # add east coupler chip_port_east = i3.OpticalPort( position=(chip_edge_east, insts[wg_name_arc2].ports['out'].position[1]), angle_deg=180.0) edge_coupler_east_port = edge_coupler_gds_lay.ports['out'] t = i3.vector_match_transform(edge_coupler_east_port, chip_port_east, mirrored=True) edge_coupler_east_name = self.name + '_EDGE_COUPLER_EAST' east_edge_coupler = i3.SRef(name=edge_coupler_east_name, reference=edge_coupler_gds_lay, transformation=t, flatten=False) # add a small linear taper to go from 0.4 to 0.5um wg lin_taper_lay = LinearTaper().get_default_view(i3.LayoutView) lin_taper_lay.set(wg_width_in=0.4, wg_width_out=0.5, length=10.0) t = i3.vector_match_transform(lin_taper_lay.ports['in'], east_edge_coupler.ports['in'], mirrored=True) lin_taper_lay_name = self.name + '_EDGETAPER_EAST' insts += i3.SRef(name=lin_taper_lay_name, reference=lin_taper_lay, transformation=t, flatten=True) # route arc to arc with straight section route_wg_shape_out = i3.Shape([ insts[wg_name_arc2].ports['out'].position, insts[lin_taper_lay_name].ports['out'].position ]) wg_name_out = self.name + '_WG_CON_OUT' wg_lay_out = i3.Waveguide(trace_template=StripWgTemplate(), name=wg_name_out).get_default_view( i3.LayoutView) wg_lay_out.set(shape=route_wg_shape_out) insts += i3.SRef(name=wg_name_out, reference=wg_lay_out, flatten=True) return insts