from ..gds_devices import gds_lib_load import nazca as nd from ..routing import Route from ..electronics import PADs CUMEC_LAYER_MAP = { (31,1): 'STRIP_COR', (31,2): 'STRIP_CLD', (31,3): 'STRIP_TRE', (31,4): 'STRIP_HOL', (32,1): 'SRIB_COR', (32,2): 'SRIB_CLD', (32,3): 'SRIB_TRE', (32,4): 'SRIB_HOL', (33,1): 'RIB_COR', (33,2): 'RIB_CLD', (33,3): 'RIB_TRE', (33,4): 'RIB_HOL', (11,1): 'METAL', (12,1): 'METAL_2', (51,1): 'VIA_H2M', (60,0): 'PASS1', (63,0): 'PASS2', (20,0): 'PAD', (61,0): 'GC_OPEN', } class PAD_60_80(gds_lib_load) : def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\bondpads" lib_name = "BP_60_80" cellname = "Fixed_BP_60_80" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False) self.add_pin(pin_name='p1',xya=(0,0,-90)) class GPD_1550(gds_lib_load): def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\photodetector" lib_name = "GPD_1550_unit" cell_name = "Fixed_GPD_1550_unit" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False, cellsreused=["Fixed_GPD_1550_unit"],layermap=CUMEC_LAYER_MAP) self.w_wg = 0.45 self.length = 110.4 self.add_pin(pin_name='ep1', xya=(55.2, 3.325, 90), width=1) ## anode self.add_pin(pin_name='en1', xya=(55.2,-3.325,-90), width=1) ## cathod self.add_pin(pin_name='a1', xya=(0,0,180), width=0.45) self.add_pin(pin_name='b1', xya=(110.4,0,0), width=self.w_wg) class EC_1550(gds_lib_load): ''' CUMEC TE Grating Coupler at 1550nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\edge_couplers" lib_name = "EC_1550" cell_name = "Fixed_EC_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False, cellsreused=["Fixed_EC_1550"],layermap=CUMEC_LAYER_MAP) self.w_wg = 0.45 self.length = 689.9 self.add_pin(pin_name='g1', xya=(0,0,0), width=self.w_wg) self.add_pin(pin_name='b0', xya=(-673.9,0,180)) self.add_pin(pin_name='a0',xya=(-673.9,0,0)) class GC_TE_1550(gds_lib_load): ''' CUMEC TE Grating Coupler at 1550nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\grating_couplers" lib_name = "GC_TE_1550" cell_name = "Fixed_GC_TE_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,cellsreused=["Fixed_GC_TE_1550"],layermap=CUMEC_LAYER_MAP) self.w_wg = 0.45 self.add_pin(pin_name='g1', xya=(0,0,0), width=self.w_wg) def generate_test_gds(self,gc2gc_dX=300): with nd.Cell(name=self.cell.cell_name+"_test",instantiate=False) as C: gc_input = self.cell.put('g1',-gc2gc_dX/2,0,180) gc_output = self.cell.put('g1',gc2gc_dX/2,0,0) stripe=Route(radius=5, width=self.w_wg, xs="strip") stripe.strt_p2p(pin1=gc_input.pin['g1'],pin2=gc_output.pin['g1'],arrow=False).put() return C class GC_TM_1550(gds_lib_load): ''' CUMEC TE Grating Coupler at 1550nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\grating_couplers" lib_name = "GC_TM_1550" cell_name = "Fixed_GC_TM_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,cellsreused=["Fixed_GC_TM_1550"],layermap=CUMEC_LAYER_MAP) self.w_wg = 0.5 self.add_pin(pin_name='g1', xya=(0,0,0), width=self.w_wg) def generate_test_gds(self,gc2gc_dX=300): with nd.Cell(name=self.cell.cell_name+"_test",instantiate=False) as C: gc_input = self.cell.put('g1',-gc2gc_dX/2,0,180) gc_output = self.cell.put('g1',gc2gc_dX/2,0,0) stripe=Route(radius=5, width=self.w_wg, xs="strip") stripe.strt_p2p(pin1=gc_input.pin['g1'],pin2=gc_output.pin['g1'],arrow=False).put() return C class GC_TE_1310(gds_lib_load): ''' CUMEC TE Grating Coupler at 1310nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\grating_couplers" lib_name = "GC_TE_1310" cell_name = "Fixed_GC_TE_1310" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,cellsreused=["Fixed_GC_TE_1310"],layermap=CUMEC_LAYER_MAP) self.w_wg = 0.38 self.add_pin(pin_name='g1', xya=(0,0,0), width=self.w_wg) class MMI_1x2_TE_1550(gds_lib_load): ''' CUMEC TE 1by 2 MMI at 1550nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK",sharp_patch: bool=True) -> None: lib_path = pdk_path + "\\mmis" lib_name = "M1X2_TE_1550" cellname = "Fixed_M1X2_TE_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Fixed_M1X2_TE_1550"],layermap=CUMEC_LAYER_MAP) self.length = 12 self.width = 1.55 self.w_wg = 0.45 self.add_pin(pin_name='a1', xya=(0,0,180), width=self.w_wg) self.add_pin(pin_name='b1', xya=(self.length,self.width/2,0), width=self.w_wg) self.add_pin(pin_name='b2', xya=(self.length,-self.width/2,0), width=self.w_wg) def generate_test_gds(self,gc,gc2gc_length=300): with nd.Cell(name=self.cell.cell_name+"_test", instantiate=False) as C: gc_input = gc.cell.put('g1',0,0,180) gc_output_1 = gc.cell.put('g1',gc2gc_length, 20,0) gc_output_2 = gc.cell.put('g1',gc2gc_length,-20,0) # Put DC dc = self.cell.put('a1',gc_input.pin['g1'].move((gc2gc_length-self.length)/2,0,0)) # Connect all the ports stripe=Route(radius=5, width=self.w_wg, xs="strip") stripe.sbend_route_p2p(pin1=gc_input.pin['g1'],pin2=dc.pin['a1'],arrow=False).put() stripe.sbend_route_p2p(pin1=gc_output_1.pin['g1'],pin2=dc.pin['b1'],arrow=False).put() stripe.sbend_route_p2p(pin1=gc_output_2.pin['g1'],pin2=dc.pin['b2'],arrow=False).put() return C class MMI_1x2_TE_1310(gds_lib_load): ''' CUMEC TE 1by 2 MMI at 1310nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK",sharp_patch: bool=True) -> None: lib_path = pdk_path + "\\mmis" lib_name = "M1X2_TE_1310" cellname = "Fixed_M1X2_TE_1310" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Fixed_M1X2_TE_1310"],layermap=CUMEC_LAYER_MAP) self.length = 15 self.width = 1.45 self.w_wg = 0.38 self.add_pin(pin_name='a1', xya=(0,0,180), width=self.w_wg) self.add_pin(pin_name='b1', xya=(self.length,self.width/2,0), width=self.w_wg) self.add_pin(pin_name='b2', xya=(self.length,-self.width/2,0), width=self.w_wg) class MMI_2x2_TE_1550(gds_lib_load): ''' CUMEC TE 1by 2 MMI at 1310nm. ''' def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\mmis" lib_name = "M2X2_TE_1550" cellname = "Fixed_M2X2_TE_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Fixed_M2X2_TE_1550"],layermap=CUMEC_LAYER_MAP) self.length = 125.4 self.width = 3 self.w_wg = 0.45 self.add_pin(pin_name='a1', xya=(0,self.width/2,180), width=self.w_wg) self.add_pin(pin_name='a2', xya=(0,-self.width/2,180), width=self.w_wg) self.add_pin(pin_name='b1', xya=(self.length,self.width/2,0), width=self.w_wg) self.add_pin(pin_name='b2', xya=(self.length,-self.width/2,0), width=self.w_wg) class CRX_TE_1550(gds_lib_load): def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\crossings" lib_name = "X_TE_1550" cellname = "Fixed_X_TE_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Fixed_X_TE_1550"],layermap=CUMEC_LAYER_MAP) self.length = 5 self.width = 5 self.w_wg = 0.45 self.xs = 'strip' self.L_arm = 5 self.add_pin(pin_name='a1',xya=(-5,0,180),width=self.w_wg) self.add_pin(pin_name='b1',xya=( 5,0,0),width=self.w_wg) self.add_pin(pin_name='a2',xya=( 0,5,90),width=self.w_wg) self.add_pin(pin_name='b2',xya=( 0,-5,-90),width=self.w_wg) def generate_test_gds(self,gc,num=5,dX_gc2gc=400,w_end=0.2,L_end=10): with nd.Cell(instantiate=False) as C: if (isinstance(gc,nd.Cell)): gc_cell = gc elif (hasattr(gc,'cell')): gc_cell = gc.cell else : raise Exception("ERROR: In , is not recongized") dL = self.L_arm*2 dX = dL*1.75 pic_strip = Route(radius=10,width=self.w_wg,xs=self.xs) gc_In = gc_cell.put('g1',-dX_gc2gc/2,0,180) pin_pre = gc_In.pin['g1'] for _idx_ in range(0,num): inst = self.cell.put('a0',_idx_*dX - (num/2 - 1/2)*dX) pic_strip.strt_p2p(pin1=pin_pre,pin2=inst.pin['a1'],arrow=False).put() pin_pre = inst.pin['b1'] nd.taper(length=L_end/2,width1=self.w_wg,width2=w_end,xs=self.xs).put(inst.pin['b2']) nd.strt(length=L_end/2,width=w_end,xs=self.xs).put() nd.taper(length=L_end/2,width1=self.w_wg,width2=w_end,xs=self.xs).put(inst.pin['a2']) nd.strt(length=L_end/2,width=w_end,xs=self.xs).put() gc_Out = gc_cell.put('g1', dX_gc2gc/2,0,0) pic_strip.strt_p2p(pin1=pin_pre,pin2=gc_Out.pin['g1'],arrow=False).put() return C class PBS_1550(gds_lib_load): def __init__(self,pdk_path: str="CUMEC_SiP130Cu_PDK") -> None: lib_path = pdk_path + "\\polarization_beam_splitter" lib_name = "PBS_1550" cellname = "Fixed_PBS_1550" super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=cellname,layermap=CUMEC_LAYER_MAP) self.length = 5 self.width = 5 self.w_wg = 0.45 self.xs = 'strip' self.add_pin(pin_name='a1',xya=(-0,0,180),width=self.w_wg) self.add_pin(pin_name='b1',xya=( 87.2,0,0),width=self.w_wg) self.add_pin(pin_name='b2',xya=( 87.2,-20,0),width=self.w_wg)