New forge coding added
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user