New forge coding added

This commit is contained in:
=
2026-06-04 23:21:39 +08:00
parent 518eb06591
commit 8da92ced57
288 changed files with 52017 additions and 1913 deletions
+44
View File
@@ -0,0 +1,44 @@
import nazca as nd
from ..gds_devices import gds_lib_load
class GC_TE_1550(gds_lib_load) :
'''
CUMEC TE Grating Coupler at 1550nm.
'''
def __init__(self,pdk_path: str="AMF_IPKISS_PDK") -> None:
lib_path = pdk_path
lib_name = "AMF_PDK_BB"
cell_name = "AMF_Si_GC1D_Cband_v3p0"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False)
self.w_wg = 0.5
self.add_pin(pin_name="a0", xya=(0,0,180))
self.add_pin(pin_name="g1", xya=(0,0,180), width=0.5)
class GC_TE_1310(gds_lib_load) :
'''
CUMEC TE Grating Coupler at 1310nm.
'''
def __init__(self,pdk_path: str="AMF_IPKISS_PDK") -> None:
lib_path = pdk_path
lib_name = "AMF_PDK_BB"
cell_name = "AMF_Si_GC1D_Oband_v3p0"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False)
self.w_wg = 0.41
self.add_pin(pin_name="a0", xya=(0,0,180))
self.add_pin(pin_name="g1", xya=(0,0,180), width=0.41)
class PD_Cband_Cell(gds_lib_load) :
'''
AMF Ge Power Monitor Cell at Cband.
'''
def __init__(self,pdk_path: str="AMF_IPKISS_PDK") -> None:
lib_path = pdk_path
lib_name = "AMF_PDK_BB"
cell_name = "AMF_Ge_PowMonitor_Cband_Cell_v3p0"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False)
self.w_wg = 0.5
self.add_pin(pin_name="a0", xya=(0,0,180))
self.add_pin(pin_name="a1", xya=(0,0,180), width=0.5)
self.add_pin(pin_name="ep1", xya=(129.8,0,0), width=5)
self.add_pin(pin_name="en1", xya=(129.8,(9+5.3)/2,0), width=3.7)
self.add_pin(pin_name="en2", xya=(129.8,-(9+5.3)/2,0), width=3.7)
+254
View File
@@ -0,0 +1,254 @@
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 <mxpiv::passive::cross::generate_test_gds>, <gc> 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)
+288
View File
@@ -0,0 +1,288 @@
from ..gds_devices import gds_lib_load
import nazca as nd
from ..routing import Route
from ..electronics import PADs
IMECAS_LAYER_MAP = {
(10,2): 'STRIP_COR',
(10,3): 'STRIP_CLD',
(10,4): 'STRIP_TRE',
(11,2): 'SRIB_COR',
(11,3): 'SRIB_CLD',
(11,4): 'SRIB_TRE',
(12,2): 'RIB_COR',
(12,3): 'RIB_CLD',
(12,4): 'RIB_TRE',
(31,0): 'METAL',
(34,0): 'METAL_2',
(36,0): 'PAD',
(80,0): 'DETCH',
}
class Template(gds_lib_load) :
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "IMECAS-templete"
cell_name = "IMECASTEST"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,cellsreused=["IMECASTEST"],layermap=IMECAS_LAYER_MAP)
class EC_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "EdegeCoupler_0_18_0_45"
cell_name = "EdegeCoupler_0_18_0_45"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["EdegeCoupler_0_18_0_45"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(220.00000,2.089,0), width=0.45)
self.add_pin(pin_name='a0', xya=(0,0,0))
class GC_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "FGC_C_TE_WG450"
cell_name = "FGC_C_TE_WG450"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["FGC_C_TE_WG450"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(43.91100,15,0), width=0.45)
self.add_pin(pin_name='a0', xya=(0,0,0))
class GC_TM_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "FGC_C_TM_WG450"
cell_name = "FGC_C_TM_WG450"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["FGC_C_TM_WG450"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(44.40100,15,0), width=0.45)
self.add_pin(pin_name='a0', xya=(0,0,0))
class GC_TE_1310(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "FGC_O_TE_WG380"
cell_name = "FGC_O_TE_WG380"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["FGC_O_TE_WG380"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(46.00000,15,0), width=0.38)
self.add_pin(pin_name='a0', xya=(0,0,0))
class GC_TM_1310(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "FGC_O_TM_WG380"
cell_name = "FGC_O_TM_WG380"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["FGC_O_TM_WG380"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(45.35500,15,0), width=0.38)
self.add_pin(pin_name='a0', xya=(0,0,0))
class DC_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "DC_C_TE_3dB"
cell_name = "DC_C_TE_3dB"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["DC_C_TE_3dB"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='a1', xya=(0,62.225,180), width=0.45)
self.add_pin(pin_name='a2', xya=(0, 2.225,180), width=0.45)
self.add_pin(pin_name='b1', xya=(67.33700,62.225,0), width=0.45)
self.add_pin(pin_name='b2', xya=(67.33700, 2.225,0), width=0.45)
self.add_pin(pin_name='a0', xya=(0,32.225,180))
self.add_pin(pin_name='b0', xya=(67.33700,32.225,0))
class MMI_2x2_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "MMI2x2_C_SE_WG450"
cell_name = "MMI2x2_C_SE_WG450"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["MMI2x2_C_SE_WG450"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='a1', xya=(0,11.325,180), width=0.45)
self.add_pin(pin_name='a2', xya=(0, 8.675,180), width=0.45)
self.add_pin(pin_name='b1', xya=(157.20000,11.325,0), width=0.45)
self.add_pin(pin_name='b2', xya=(157.20000, 8.675,0), width=0.45)
self.add_pin(pin_name='a0', xya=(157.20000/2,10, 0))
self.add_pin(pin_name='b0', xya=(157.20000/2,10,180))
class MMI_1x2_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "MMI1X2_C_WG450"
cell_name = "MMI1X2_C_WG450"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["MMI1X2_C_WG450"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.length = 12.41900
self.add_pin(pin_name='a1', xya=(0,3,180), width=0.45)
self.add_pin(pin_name='b1', xya=(12.41900,3.5,0), width=0.45)
self.add_pin(pin_name='b2', xya=(12.41900,2.5,0), width=0.45)
self.add_pin(pin_name='a0', xya=(12.41900/2,3, 0))
self.add_pin(pin_name='b0', xya=(12.41900/2,3,180))
class MMI_2x2_TE_1310(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "MMI2x2_O_WG380"
cell_name = "MMI2x2_O_WG380"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["MMI2x2_O_WG380"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='a1', xya=(0,4,180), width=0.38)
self.add_pin(pin_name='a2', xya=(0, 3,180), width=0.38)
self.add_pin(pin_name='b1', xya=(25.30000,4,0), width=0.38)
self.add_pin(pin_name='b2', xya=(25.30000,3,0), width=0.38)
self.add_pin(pin_name='a0', xya=(25.30000/2,3.5, 0))
self.add_pin(pin_name='b0', xya=(25.30000/2,3.5,180))
class MMI_1x2_TE_1310(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "MMI1x2_O_WG380"
cell_name = "MMI1x2_O_WG380"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["MMI1x2_O_WG380"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='a1', xya=(0,4,180), width=0.38)
self.add_pin(pin_name='b1', xya=(16.67800,4.5,0), width=0.38)
self.add_pin(pin_name='b2', xya=(16.67800,3.5,0), width=0.38)
self.add_pin(pin_name='a0', xya=(16.67800/2,3, 0))
self.add_pin(pin_name='b0', xya=(16.67800/2,3,180))
class Ybranch_TE(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "Ybranch_C_TE"
cell_name = "Ybranch_C_TE"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False,
cellsreused=["Ybranch_C_TE"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='a1', xya=(0,4,180), width=0.45)
self.add_pin(pin_name='b1', xya=(14.00000,4.875,0), width=0.45)
self.add_pin(pin_name='b2', xya=(14.00000,2.225,0), width=0.45)
self.add_pin(pin_name='a0', xya=(14.00000/2,3.05, 0))
self.add_pin(pin_name='b0', xya=(14.00000/2,3.05,180))
class CRX_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "Crossing_C_TE"
cellname = "Crossing_C_TE"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Crossing_C_TE"],layermap=IMECAS_LAYER_MAP)
self.length = 5
self.width = 5
self.w_wg = 0.45
self.xs = 'strip'
self.L_arm = 9.96400/2
self.add_pin(pin_name='a1',xya=( 0 ,4.982 ,180),width=self.w_wg)
self.add_pin(pin_name='b1',xya=( 9.96400,4.982 ,0),width=self.w_wg)
self.add_pin(pin_name='a2',xya=( 4.982 ,9.96400,90),width=self.w_wg)
self.add_pin(pin_name='b2',xya=( 4.982 ,0 ,-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 <mxpiv::passive::cross::generate_test_gds>, <gc> 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 CRX_TE_1310(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "Crossing_O_TE"
cellname = "Crossing_O_TE"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cellname, rename=cellname+"_WithPin", instantiate=False,cellsreused=["Crossing_O_TE"],layermap=IMECAS_LAYER_MAP)
self.length = 5
self.width = 5
self.w_wg = 0.38
self.xs = 'strip'
self.L_arm = 11.8280/2
self.add_pin(pin_name='a1',xya=( 0 ,5.914 ,180),width=self.w_wg)
self.add_pin(pin_name='b1',xya=( 11.8280,5.914 ,0),width=self.w_wg)
self.add_pin(pin_name='a2',xya=( 5.914 ,11.8280,90),width=self.w_wg)
self.add_pin(pin_name='b2',xya=( 5.914 ,0 ,-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 <mxpiv::passive::cross::generate_test_gds>, <gc> 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 EC_TE_1550(gds_lib_load):
def __init__(self,pdk_path: str="IMECAS_PDK2.1") -> None:
lib_path = pdk_path
lib_name = "EdegeCoupler_0_18_0_45"
cell_name = "EdegeCoupler_0_18_0_45"
super().__init__(lib_path=lib_path, lib_name=lib_name, cell_name=cell_name, rename=cell_name+"_WithPin", instantiate=False, cellsreused=["EdegeCoupler_0_18_0_45"],layermap=IMECAS_LAYER_MAP)
self.w_wg = 0.45
self.add_pin(pin_name='g1', xya=(220.00000,2.089,0), width=0.45)
self.add_pin(pin_name='a0', xya=(0,0,0))
+5
View File
@@ -0,0 +1,5 @@
from . import AMF_pdk
from . import CUMEC_pdk
from . import IMECAS_pdk
from . import hgl_pdk_A
from . import qy_pdk_A
+52
View File
@@ -0,0 +1,52 @@
import numpy as np
from ..primitives.passive import DC_bend
class DC_bend_50_50_Cband(DC_bend):
def __init__(self, w_wg: float, show_pins: bool=False) -> None:
'''
This is a wideband 50/50 Direction Coupler based on bend directional coupler, from 1500nm to 1600nm.
'''
w_in = 0.45
w_out = 0.45
gap = 0.2
r_in = 60
coupling_length = 19.08
theta_arc = coupling_length / (r_in+gap/2+w_in/2) * 180 / np.pi
super().__init__(w_in=w_in, w_out=w_out, gap=gap, r_in=r_in, theta_arc=theta_arc, w_wg=w_wg, theta_ext=10, xs_wg="strip", show_pins=show_pins)
self.cell = self.generate_gds(cellname="_50_50_Cband")
class DC_bend_20_80_Cband(DC_bend):
'''
This is a wideband 20/80 Direction Coupler based on bend directional coupler, from 1500nm to 1600nm.
Through: 80%
Cross: 20%
'''
def __init__(self, w_wg: float, show_pins: bool=False) -> None:
w_in = 0.45
w_out = 0.45
gap = 0.2
r_in = 41
coupling_length = 19.6
theta_arc = coupling_length / (r_in+gap/2+w_in/2) * 180 / np.pi
super().__init__(w_in=w_in, w_out=w_out, gap=gap, r_in=r_in, theta_arc=theta_arc, w_wg=w_wg, theta_ext=10, xs_wg="strip", show_pins=show_pins)
self.generate_gds(cellname="_20_80_Cband")
class DC_bend_4_96_Cband(DC_bend):
'''
This is a wideband 20/80 Direction Coupler based on bend directional coupler, from 1500nm to 1600nm.
Through: 96%
Cross: 4%
'''
def __init__(self, w_wg: float, show_pins: bool=False) -> None:
w_in = 0.45
w_out = 0.45
gap = 0.2
r_in = 30
coupling_length = 18.9
theta_arc = coupling_length / (r_in+gap/2+w_in/2) * 180 / np.pi
super().__init__(w_in=w_in, w_out=w_out, gap=gap, r_in=r_in, theta_arc=theta_arc, w_wg=w_wg, theta_ext=10, xs_wg="strip", show_pins=show_pins)
self.generate_gds(cellname="_4_96_Cband")
+146
View File
@@ -0,0 +1,146 @@
from typing import Optional
import numpy as np
import nazca as nd
from ..primitives.passive import *
from ..gds_devices import generate_gds_lib
""" test passed, in ANT-20230228 submission """
class DC_pX3_50_50_Cband(DC_pX_3sg):
def __init__(self, w_wg: float=0.5,gds_lib_generate: bool=False,name: Optional[str]=None) -> None:
# DC_50_50_pX3 = mx.passive.DC_pX_3sg(name="DC_50_50_pX3",Lc1=33, Lp1=0.55, Lc2=15, Lt=1, w_cp=0.5, dw=0.1, gap=0.2, R0=17.5, A=20, w_wg=0.5, pX_type='symmetric', sharp_patch=True)
super().__init__(name=name,xs_wg='strip', Lc1=33, Lp1=0.55, Lc2=15, Lt=1, w_cp=0.5, dw=0.1, gap=0.2, R0=17.5, A=20, w_wg=w_wg, pX_type='symmetric', sharp_patch=True)
if (gds_lib_generate):
self.generate_gds_lib()
def generate_gds_lib(self):
generate_gds_lib("DC_pX3_50_50_Cband",self.cell,with_txt=True)
class MMG_1D_D14um_1550_2modes(GC_STD_1D):
def __init__(self, w_wg: float = 0.5, gds_lib_generate:bool=False) -> None:
pitch_1D_apodized = np.linspace(0.602,0.602,40)
eta_1D_apodized = np.linspace(0.389,0.613,40)
super().__init__(xs_wg='strip', w_wg=w_wg, etch_type='SETCH', xs_open='gc_open', L_taper=500, L_end=5, A_taper=2.5,
Pitch=pitch_1D_apodized, eta_etch=eta_1D_apodized, num=len(eta_1D_apodized), shape='rectangle')
if (gds_lib_generate):
self.generate_gds_lib()
def generate_gds_lib(self):
generate_gds_lib("MMG_1D_D14um_1550_2modes",self.cell,with_txt=True)
""" Aborted due to failure testing, 2022.12.30 """
class MDM_ADC_TE1_1550(MDM):
def __init__(self,w_wg: float=0.45,gds_lib_generate: bool=False) -> None:
"""
w_wg the single mode input for the device
"""
self.wb0 = 0.44
self.wb1 = 0.61
self.wb_in = 0.45
self.wb_out = 0.85
self.w0 = 0.33
self.w1 = 0.2
self.w_wg = w_wg
self.xs='strip'
self.Lt_bus = 22
self.Lt_cp = 22
self.R0 = 40
self.Rmin=8
self.angle=22.5
self.gap0=0.2
self.gap1=0.2
super().__init__(xs=self.xs,
wb0=self.wb0, wb1=self.wb1, wb_in=self.wb_in, wb_out=self.wb_out,
w_wg=self.w_wg, w0=self.w0, w1=self.w1,
gap0=self.gap0, Lt_bus=self.Lt_bus, R0=self.R0, angle=self.angle, Lt_cp=self.Lt_cp, gap1=self.gap1,
name=None, Lb0=None, symmetric_BUS=False, single_end=True)
if (gds_lib_generate):
self.generate_gds_lib()
def generate_gds_lib(self):
generate_gds_lib("MDM_ADC_TE1_1550",self.cell,with_txt=True)
class MDM_ADC_TE2_1550(MDM):
def __init__(self,w_wg: float=0.45,gds_lib_generate: bool=False) -> None:
"""
w_wg the single mode input for the device
"""
self.wb0 = 0.85
self.wb1 = 1.04
self.wb_in = 0.85
self.wb_out = 1.2
self.w0 = 0.33
self.w1 = 0.2
self.w_wg = w_wg
self.xs='strip'
self.Lt_bus = 32
self.Lt_cp = 32
self.R0 = 40
self.Rmin=8
self.angle=22.5
self.gap0=0.2
self.gap1=0.2
super().__init__(xs=self.xs,
wb0=self.wb0, wb1=self.wb1, wb_in=self.wb_in, wb_out=self.wb_out,
w_wg=self.w_wg, w0=self.w0, w1=self.w1,
gap0=self.gap0, Lt_bus=self.Lt_bus, R0=self.R0, angle=self.angle, Lt_cp=self.Lt_cp, gap1=self.gap1,
name=None, Lb0=None, symmetric_BUS=False, single_end=None)
if (gds_lib_generate):
self.generate_gds_lib()
def generate_gds_lib(self):
generate_gds_lib("MDM_ADC_TE2_1550",self.cell,with_txt=True)
class MDM_ADC_TE3_1550(MDM):
def __init__(self,w_wg: float=0.45,gds_lib_generate: bool=False) -> None:
"""
w_wg the single mode input for the device
"""
self.wb0 = 1.25
self.wb1 = 1.41
self.wb_in = 1.2
self.wb_out = 1.8
self.w0 = 0.33
self.w1 = 0.2
self.w_wg = w_wg
self.xs = 'strip'
self.Lt_bus = 70
self.Lt_cp = 70
self.R0 = 40
self.Rmin=8
self.angle=22.5
self.gap0=0.2
self.gap1=0.2
super().__init__(xs=self.xs,
wb0=self.wb0, wb1=self.wb1, wb_in=self.wb_in, wb_out=self.wb_out,
w_wg=self.w_wg, w0=self.w0, w1=self.w1,
gap0=self.gap0, Lt_bus=self.Lt_bus, R0=self.R0, angle=self.angle, Lt_cp=self.Lt_cp, gap1=self.gap1,
name=None, Lb0=None, symmetric_BUS=False, single_end=None)
if (gds_lib_generate):
self.generate_gds_lib()
def generate_gds_lib(self):
generate_gds_lib("MDM_ADC_TE3_1550",self.cell,with_txt=True)