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
+295
View File
@@ -0,0 +1,295 @@
import nazca as nd
import numpy as np
import math
from ...routing import Route
from ...structures import *
from ....technologies import *
import pandas as pd
from ...structures import _my_polygon
""" NEW Classes :: Transistion area of rib to strip, to minize the loss """
class transition:
def __init__(self,
layer_FETCH: str="STRIP_TRE",
layer_METCH: str="RIB_TRE",
w_rib: float=1.1,
dw_tolerance: float = 0.2,
w_grow_rib: float=2,
w_grow_strip: float=2,
Ltp1: int=15,
Ltp2: int=10,
Ltrans: int=5,
L_port: int=2,
show_pins: bool=False,
) -> None:
with nd.Cell(instantiate=False) as C:
""" Placing taper for rib etching"""
dLx = np.array([0,L_port+Ltp1+Ltrans+Ltp2,Ltp2])
vtx_x = np.cumsum(dLx)
vtx_x = np.r_[vtx_x,vtx_x[-1],0]
vtx_y = np.array([w_rib/2,w_rib/2,w_rib/2+dw_tolerance,w_rib/2+w_grow_rib+w_grow_strip,w_rib/2+w_grow_rib+w_grow_strip])
vtx = np.c_[vtx_x,vtx_y]
_my_polygon(layer_wg=layer_METCH,vtx=vtx).put(0,0,0)
vtx_y = -vtx_y
vtx = np.c_[vtx_x,vtx_y]
_my_polygon(layer_wg=layer_METCH,vtx=vtx).put(0,0,0)
""" Placing taper for rib etching"""
dLx = np.array([0,L_port,Ltp1,Ltp2,Ltrans+Ltp2+L_port])
vtx_x = np.cumsum(dLx)
vtx_x = np.r_[vtx_x,vtx_x[-1],0]
vtx_y = np.array([w_rib/2+w_grow_rib,w_rib/2+w_grow_rib,w_rib/2+dw_tolerance,w_rib/2,w_rib/2,w_rib/2+w_grow_rib+w_grow_strip,w_rib/2+w_grow_rib+w_grow_strip])
vtx = np.c_[vtx_x,vtx_y]
_my_polygon(layer_wg=layer_FETCH,vtx=vtx).put(0,0,0)
vtx_y = -vtx_y
vtx = np.c_[vtx_x,vtx_y]
_my_polygon(layer_wg=layer_FETCH,vtx=vtx).put(0,0,0)
nd.Pin(name='a0',width=w_rib).put(0,0,180)
nd.Pin(name='b0',width=w_rib).put(L_port*2+Ltrans+Ltp1+Ltp2*2,0,0)
if (show_pins):
nd.put_stub()
self.cell = C
class taper_xs2xs:
def __init__ (self,
xs_1:str='rib',
xs_2:str='strip',
L_taper:float=10,
w_1:float=0.45,
w_2:float=0.45,
L_port:float = 0) -> None:
"""_summary_
Args:
xs_1 (str, optional): fisrt xsection. Defaults to 'rib'.
xs_2 (str, optional): second xsection. Defaults to 'strip'.
L_taper (float, optional): length of the xsection taper. Defaults to 10.
w_1 (float, optional): first xsection width. Defaults to 0.45.
w_2 (float, optional): second xsection width. Defaults to 0.45.
L_port (float, optional): length attached to the end. Defaults to 0.
Raises:
Exception: No xsection input found
"""
with nd.Cell(instantiate=False) as C:
xs_1_layer_list = []
xs_2_layer_list = []
growx_1_list = []
growx_2_list = []
## input guard
try:
nd.get_xsection(xs_1)
except:
raise Exception("ERROR: in <mxpic.passive.pic.taper.taper_xs2xs> No xsection ==",xs_1,"== were found")
try:
nd.get_xsection(xs_2)
except:
raise Exception("ERROR: in <mxpic.passive.pic.taper.taper_xs2xs> No xsection ==",xs_2,"== were found")
for layers_1,growx,growy,acc in nd.layeriter(xs=xs_1):
xs_1_layer_list = xs_1_layer_list + [layers_1]
growx_1_list = growx_1_list + [growx]
for layers_2,growx,growy,acc in nd.layeriter(xs=xs_2):
xs_2_layer_list = xs_2_layer_list + [layers_2]
growx_2_list = growx_2_list + [growx]
for layers_1 in xs_1_layer_list:
if (layers_1 in xs_2_layer_list):
## same layer
(a1_1,b1_1), (a2_1,b2_1),c1,c2 = growx_1_list[xs_1_layer_list.index(layers_1)]
(a1_2,b1_2), (a2_2,b2_2),c1,c2 = growx_2_list[xs_2_layer_list.index(layers_1)]
w1 = w_1*(a1_1-a2_1) + (b1_1-b2_1)
w2 = w_2*(a1_2-a2_2) + (b1_2-b2_2)
nd.taper(length=L_taper,width1=w1,width2=w2,layer=layers_1).put(0,0,0)
else :
if (layers_1.find('COR')!=-1):
(a1_1,b1_1), (a2_1,b2_1),c1,c2 = growx_1_list[xs_1_layer_list.index(layers_1)]
w1 = w_1*(a1_1-a2_1) + (b1_1-b2_1)
w2 = w_2
nd.taper(length=L_taper,width1=w1,width2=w2,layer=layers_1).put(0,0,0)
else :
(a1_1,b1_1), (a2_1,b2_1),c1,c2 = growx_1_list[xs_1_layer_list.index(layers_1)]
w1 = w_1*(a1_1-a2_1) + (b1_1-b2_1)
w2 = w_2*(a1_1-a2_1) + (b1_1-b2_1)
nd.taper(length=L_taper,width1=w1,width2=w2,layer=layers_1).put(0,0,0)
for layers_2 in xs_2_layer_list:
if (layers_2 not in xs_1_layer_list):
if (layers_2.find('COR')!=-1):
(a1_2,b1_2), (a2_2,b2_2),c1,c2 = growx_2_list[xs_2_layer_list.index(layers_2)]
w1 = w_1
w2 = w_2*(a1_2-a2_2) + (b1_2-b2_2)
nd.taper(length=L_taper,width1=w1,width2=w2,layer=layers_2).put(0,0,0)
else :
(a1_1,b1_1), (a2_1,b2_1),c1,c2 = growx_2_list[xs_2_layer_list.index(layers_2)]
w1 = w_1*(a1_1-a2_1) + (b1_1-b2_1) ## Revised 2022.12.06, HGL
w2 = w_2*(a1_1-a2_1) + (b1_1-b2_1)
nd.taper(length=L_taper,width1=w1,width2=w2,layer=layers_2).put(0,0,0)
nd.strt(length=L_port,xs=xs_1,width=w_1).put(0,0,180)
nd.strt(length=L_port,xs=xs_2,width=w_2).put(L_taper,0,0)
nd.Pin(name='a0',width=w_1).put(-L_port,0,180)
nd.Pin(name='a1',width=w_1).put(-L_port,0,180)
nd.Pin(name='b0',width=w_2).put(L_taper+L_port,0,0)
nd.Pin(name='b1',width=w_2).put(L_taper+L_port,0,0)
self.cell = C
class PSR:
"""
Polarization Splitter & rotator
"""
def __init__ (self,
name : str="PSR_unit",
xs :str='rib',
layer_u: str=None, ## override xs_u
layer_d: str=None, ## override xs_d
w: list=[0.45,0.45,0.55,1.2,1.2],
Lt_rib: list=[10,30,30,10],
ws: list=[0.45,2,1.2],
Lt_slab: list=[40,40],
shape:str='sine',
L_port:float = 5,
res:float=0.01) -> None:
if (name==None):
instantiate = False
else :
instantiate = True
try:
nd.get_xsection(xs)
except:
raise Exception("ERROR: In <mxpic::passive::taper>, xs=",xs," is not defined in the tapeout")
if (len(w)!=len(Lt_rib)+1):
print("WARNING: In <mxpic::passive::taper>, rib area width section do not match with taper section")
return 0
if (len(w)!=len(Lt_rib)+1):
print("WARNING: In <mxpic::passive::taper>, slab area width section do not match with taper section")
return 0
w = np.array(w).tolist()
ws = np.array(ws).tolist()
Lt_rib = np.array(Lt_rib).tolist()
Lt_slab = np.array(Lt_slab).tolist()
self.w = w
self.ws = ws
self.Lt_rib = Lt_rib
self.Lt_slab = Lt_slab
## defining the shape of the PSR
if (shape=='sine'):
wu_final = []
Lu_final = []
for _idx_ in range(0,len(Lt_rib)):
Lt_seg = np.linspace(0,Lt_rib[_idx_],int(Lt_rib[_idx_]/res)+1)
wu_temp = (w[_idx_] + w[_idx_+1])/2 + (w[_idx_] - w[_idx_+1])/2*np.cos(Lt_seg/Lt_rib[_idx_]*pi)
if (_idx_>=0):
Lt_seg = Lt_seg + np.sum(Lt_rib[0:_idx_])
wu_final = np.r_[wu_final,wu_temp]
Lu_final = np.r_[Lu_final,Lt_seg]
wd_final = []
Ld_final = []
for _idx_ in range(0,len(Lt_slab)):
Lt_seg = np.linspace(0,Lt_slab[_idx_],int(Lt_slab[_idx_]/res)+1)
wd_temp = (ws[_idx_] + ws[_idx_+1])/2 + (ws[_idx_] - ws[_idx_+1])/2*np.cos(Lt_seg/Lt_slab[_idx_]*pi)
if (_idx_>0):
Lt_seg = Lt_seg + np.sum(Lt_slab[0:_idx_])
wd_final = np.r_[wd_final,wd_temp]
Ld_final = np.r_[Ld_final,Lt_seg]
elif(shape=='linear'):
wd_final = np.array(ws)
Ld_final = np.array(Lt_slab)
wu_final = np.array(w)
Lu_final = np.array(Lt_rib)
Lu_final = np.r_[0,np.cumsum(Lu_final)]
Ld_final = np.r_[0,np.cumsum(Ld_final)] ## FATAL ERROR CORRECTED: 2023.1.31
# print(wd_final,wu_final)
# print(Ld_final,Lu_final)
else:
wd_final = np.array(ws)
Ld_final = np.array(Lt_slab)
wu_final = np.array(w)
Lu_final = np.array(Lt_rib)
Lu_final = np.r_[0,np.cumsum(Lu_final)]
Ld_final = np.r_[0,np.cumsum(Ld_final)]
Lu_vtx = np.r_[Lu_final,np.flip(np.array(Lu_final),0)]
Ld_vtx = np.r_[Ld_final,np.flip(np.array(Ld_final),0)]
wu_vtx = np.r_[wu_final/2,np.flip(np.array(-wu_final/2),0)]
wd_vtx = np.r_[wd_final/2,np.flip(np.array(-wd_final/2),0)]
with nd.Cell(instantiate=instantiate,name=name) as C:
if (layer_u!=None and layer_d!=None):
vtx = np.c_[Lu_vtx,wu_vtx]
_my_polygon(layer_u,vtx).put(0,0,0)
vtx = np.c_[Ld_vtx,wd_vtx]
_my_polygon(layer_d,vtx).put(0,0,0)
else :
for layers,growx,growy,acc in nd.layeriter(xs=xs):
(a1,b1), (a2,b2),c1,c2 = growx
if (b1==0 and b2==0 and layers.find("COR")!=-1):
wu_temp = np.r_[wu_final/2,np.flip(np.array(-wu_final/2),0)]
vtx = np.c_[Lu_vtx,wu_temp]
_my_polygon(layers,vtx).put(0,0,0)
w0=wu_final[0]
w1=wu_final[-1]
elif (layers.find("COR")!=-1):
wd_temp = np.r_[wd_final/2,np.flip(np.array(-wd_final/2),0)]
vtx = np.c_[Ld_vtx,wd_temp]
_my_polygon(layers,vtx).put(0,0,0)
w0=wd_final[0]
w1=wd_final[-1]
else :
wd_temp = np.r_[(wd_final*(a1-a2)+(b1-b2))/2,np.flip(np.array(-(wd_final*(a1-a2)+(b1-b2))/2),0)]
vtx = np.c_[Ld_vtx,wd_temp]
_my_polygon(layers,vtx).put(0,0,0)
w0=(wd_final[0]*(a1-a2)+(b1-b2))
w1=(wd_final[-1]*(a1-a2)+(b1-b2))
nd.strt(width=w0,length=L_port,layer=layers).put(0,0,180)
nd.strt(width=w1,length=L_port,layer=layers).put(sum(Lt_rib),0,0)
nd.Pin(name='a1',width=w[0]).put(-L_port,0,180)
nd.Pin(name='b1',width=w[-1]).put(sum(Lt_rib)+L_port,0,0)
self.cell = C