New forge coding added
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
from .unit import PSR_1x2 , Brag_WDM
|
||||
from .unit import waveguide,PS_2st, PS_2st_Straight
|
||||
|
||||
from .rings import STD_ring_AMZI_adddrop, MRR_MM_Adddrop, MRR_MM_Allpass, MRR_STD_Adddrop,MRR_STD_Allpass,MRR_DW_Adddrop,MRR_DW_Allpass
|
||||
from .rings import SOCR_Adiabatic, SOCR_Adiabatic_Cband
|
||||
from .rings import SOCR, SOCR_Cband
|
||||
|
||||
|
||||
from .crows import CROW_Eul_Ring,CROW_Eul_RCK,CROW_AED,CROW_STD_Adddrop,CROW_STD_Allpass
|
||||
|
||||
from ..pic import *
|
||||
from ...electronics import ISL
|
||||
@@ -0,0 +1,983 @@
|
||||
from typing import Any, Optional
|
||||
from turtle import ht
|
||||
import nazca as nd
|
||||
import numpy as np
|
||||
import nazca.interconnects as IC
|
||||
|
||||
from ...structures import *
|
||||
from ...routing import *
|
||||
|
||||
from .unit import *
|
||||
from .rings import *
|
||||
from ..pic import *
|
||||
from ...electronics import Vias
|
||||
|
||||
|
||||
from ...basic import __array_convert__,__list_convert__,__xs_exist__,__cell_arg__
|
||||
|
||||
class STD_CROW_V:
|
||||
def __init__(self,
|
||||
|
||||
ring: Any,
|
||||
bus: Any,
|
||||
w_bus:'float|list',
|
||||
w_ring:'float|list',
|
||||
sz_ring:'float|list',
|
||||
sz_bus:'float|list',
|
||||
name:str=None,
|
||||
gap_crows:'float|list'=[0.4],
|
||||
gap_cp:'float|list'=[0.45,0.45],
|
||||
w_heater:'float|list'=0,
|
||||
xs_heater:'str'='heater',
|
||||
connected:'bool'=True,
|
||||
w_metal:'float'=8,
|
||||
xs_metal:'str'='metal',
|
||||
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
ht_shift: int=0,
|
||||
A_ht: int = 45,
|
||||
ISL_LEFT:'bool'=True,ISL_RIGHT:'bool'=True,
|
||||
show_pins:'bool'=False) -> None:
|
||||
"""_summary_
|
||||
|
||||
Args:
|
||||
ring (_type_): Class, nazca.Cell or Class containing nazca.Cell
|
||||
bus (_type_): Class, nazca.Cell or Class containing nazca.Cell
|
||||
w_bus (float|list, optional): width of the bus waveguide, [w0,w1] w0 is the middle width.
|
||||
w_ring (float|list, optional): width of the ring waveguide, [w0,w1] w0 is the middle width in X axis, and w1 is in Y.
|
||||
sz_ring (float|list, optional): width of the ring waveguide, [s0,s1] s0 is the center distance in X axis, and w1 is in Y,standard input rules [[sz0,sz1],[sz0,sz1],....[sz0,sz1]]
|
||||
sz_bus (float|list, optional): width of the bus waveguide, [s0,s1] s0 is the center distance in X axis, and w1 is in Y.
|
||||
gap_crows (float|list, optional): list of gaps between rings. Defaults to [0.4].
|
||||
gap_cp (float|list, optional): gap between ring and BUS. Defaults to 0.45.
|
||||
w_heater (float, optional): width of heater. Defaults to 0.
|
||||
xs_heater (str, optional): nazca xsection of heater. Defaults to 'heater'.
|
||||
connected (bool, optional): the heaters in rings are whether connected together. Defaults to True.
|
||||
w_metal (float, optional): width of metal attachment. Defaults to 8.
|
||||
xs_metal (str, optional): nazca xsection of metal attachment. Defaults to 'metal'.
|
||||
sz_via_h2m (float, optional): width of the VIA holes. Defaults to 0.3.
|
||||
sp_via_h2m (float, optional): spacing of the VIA holes. Defaults to 0.3.
|
||||
xs_via_h2m (str, optional): nazca xsection of the VIA holes. Defaults to 'via_h2m'.
|
||||
w_isl (float, optional): width of the theimal isolation trench. Defaults to 5.
|
||||
sp_isl (float, optional): spacing between the theimal isolation trench and heaters|metal. Defaults to 5.
|
||||
xs_isl (str, optional): nazca xsection of the theimal isolation trench. Defaults to 'isl'.
|
||||
ISL_LEFT (bool, optional): whether isolation on the left. Defaults to True.
|
||||
ISL_RIGHT (bool, optional): whether isolation on the right. Defaults to True.
|
||||
show_pins (bool, optional): _description_. Defaults to False.
|
||||
|
||||
"""
|
||||
""" """
|
||||
self.ht_shift = ht_shift ## temporary variable
|
||||
self.A_ht = A_ht
|
||||
""" """
|
||||
self.sz_ring = sz_ring
|
||||
self.w_ring = w_ring
|
||||
self.w_bus = w_bus
|
||||
self.sz_bus = sz_bus
|
||||
|
||||
self.via_h2m = via_h2m
|
||||
self.isl = isl
|
||||
|
||||
## refreshed 2022.12.28
|
||||
self.gap_crows = __array_convert__(gap_crows,'gap_crows','mxpic::passive::STD_CROW_V')
|
||||
self.gap_cp = __array_convert__(gap_cp,'gap_cp','mxpic::passive::STD_CROW_V')
|
||||
|
||||
self.name = name
|
||||
if (name is None):
|
||||
self.instantiate = False
|
||||
else:
|
||||
self.instantiate = True
|
||||
|
||||
self.connected = connected
|
||||
|
||||
if (isinstance(ring,list)):
|
||||
self.ring_uniform = False
|
||||
self.ring_cell = ring
|
||||
self.connected = False
|
||||
if (len(ring)!=len(self.gap_crows)+1):
|
||||
raise Exception("ERROR: In <mxpic::passive::crows::STD_CROW_V>, ring list does not match gap list")
|
||||
else :
|
||||
self.ring_uniform = True
|
||||
self.ring_cell = [ring]*(len(self.gap_crows)+1)
|
||||
|
||||
if (isinstance(bus,list)):
|
||||
self.bus_uniform = False
|
||||
self.bus_cell = bus
|
||||
|
||||
else :
|
||||
self.bus_uniform = True
|
||||
self.bus_cell = [bus]*(len(self.gap_cp))
|
||||
|
||||
### standard input rules [[sz0,sz1],[sz0,sz1],....[sz0,sz1]]
|
||||
if (isinstance(self.sz_ring,int) or isinstance(self.sz_ring,float)):
|
||||
self.sz_ring=[[self.sz_ring,self.sz_ring]]*len(self.ring_cell)
|
||||
elif (isinstance(self.sz_ring,list)):
|
||||
_sz_ = np.shape(self.sz_ring)
|
||||
if (len(_sz_)==1):
|
||||
self.sz_ring=[[self.sz_ring[0],self.sz_ring[1]]]*len(self.ring_cell) ## y axis
|
||||
elif (_sz_[0]!=len(self.ring_cell)):
|
||||
raise Exception("ERROR: In <mxpic::passive::crows::STD_CROW_V>, ring list does not match sz_ring list")
|
||||
|
||||
if (isinstance(self.w_ring,int) or isinstance(self.w_ring,float)):
|
||||
self.w_ring=[[self.w_ring,self.w_ring]]*len(self.ring_cell) ## y axis
|
||||
|
||||
elif (isinstance(self.w_ring,list)):
|
||||
_sz_ = np.shape(self.w_ring)
|
||||
if (len(_sz_)==1):
|
||||
self.w_ring=[[self.w_ring[0],self.w_ring[1]]]*len(self.ring_cell) ## y axis
|
||||
elif (_sz_[0]!=len(self.ring_cell)):
|
||||
raise Exception("ERROR: In <mxpic::passive::crows::STD_CROW_V>, ring list does not match w_ring list")
|
||||
# print(type(w_heater))
|
||||
if (isinstance(w_heater,int) or isinstance(w_heater,float)):
|
||||
self.w_heater = [w_heater]*len(self.ring_cell)
|
||||
else:
|
||||
self.w_heater = w_heater
|
||||
|
||||
if (isinstance(self.w_bus,list) or isinstance(self.w_bus,np.ndarray)):
|
||||
self.w_bus=self.w_bus[1] ## y axis
|
||||
|
||||
if (isinstance(self.sz_bus,int) or isinstance(self.sz_bus,float)):
|
||||
self.sz_bus=[[self.sz_bus,self.sz_bus]] ## y axis
|
||||
elif (isinstance(self.sz_bus,list)):
|
||||
if (len(np.shape(self.sz_bus))==1): ## only one dimension
|
||||
self.sz_bus=[self.sz_bus] ## y axis
|
||||
|
||||
|
||||
self.cell_pic = self.generate_pic_gds()
|
||||
|
||||
### ================== ###
|
||||
|
||||
self.w_metal = w_metal
|
||||
self.ISL_LEFT = ISL_LEFT
|
||||
self.ISL_RIGHT = ISL_RIGHT
|
||||
|
||||
|
||||
try :
|
||||
nd.get_xsection(xs_heater)
|
||||
nd.get_xsection(xs_metal)
|
||||
self.xs_heater=xs_heater
|
||||
self.xs_metal=xs_metal
|
||||
|
||||
try :
|
||||
if (w_heater>0):
|
||||
self.cell_eic = self.generate_eic_gds()
|
||||
else :
|
||||
self.cell_eic = None
|
||||
except :
|
||||
raise Exception("ERROR: In <mxpic.passive:STD_CROW_V>, func [generate_eic_gds] errors")
|
||||
except :
|
||||
self.xs_heater=None
|
||||
self.xs_metal=None
|
||||
self.cell_eic = None
|
||||
|
||||
### ======================== ###
|
||||
### Building Final GDS ###
|
||||
if (self.cell_eic!=None and self.cell_pic!=None):
|
||||
with nd.Cell(instantiate=self.instantiate,name=self.name) as C:
|
||||
try :
|
||||
C_eic = self.cell_eic.put(0,0,0)
|
||||
C_pic = self.cell_pic.put(0,0,0)
|
||||
|
||||
## transporting pins
|
||||
for str,Pin in C_eic.ic_pins():
|
||||
nd.Pin(name=str,pin=Pin).put()
|
||||
for str,Pin in C_pic.ic_pins():
|
||||
nd.Pin(name=str,pin=Pin).put()
|
||||
|
||||
if (show_pins):
|
||||
nd.put_stub(pinsize=2)
|
||||
except Exception as ex:
|
||||
print("ERROR :: ",ex)
|
||||
|
||||
self.cell = C
|
||||
|
||||
elif (self.cell_eic==None and self.cell_pic!=None):
|
||||
self.cell = self.cell_pic
|
||||
|
||||
|
||||
def generate_pic_gds(self):
|
||||
|
||||
if (self.name is not None):
|
||||
instantiate = True
|
||||
name_pic = self.name + "_pic"
|
||||
else:
|
||||
instantiate = False
|
||||
name_pic = None
|
||||
|
||||
with nd.Cell(instantiate=instantiate,name=name_pic) as C:
|
||||
try :
|
||||
instr = __cell_arg__(arg=self.ring_cell[0],arg_name="ring_cell[0]",func_name="STD_CROW_V::generate_pic_gds").put(0,0,0)
|
||||
|
||||
instr.raise_pins(['r1','r2','r3','r4'],['ra1','ra2','ra3','ra4'])
|
||||
# print(self.sz_ring,self.w_ring,self.gap_cp[0])
|
||||
BUS_d = self.bus_cell[0].put(0,-self.sz_ring[0][1]/2-self.w_ring[0][1]/2-self.w_bus/2-self.gap_cp[0])
|
||||
nd.Pin(name='a1',pin=BUS_d.pin['a1']).put()
|
||||
nd.Pin(name='b1',pin=BUS_d.pin['b1']).put()
|
||||
|
||||
dy = 0
|
||||
for _idx_ in range(0,len(self.gap_crows)):
|
||||
# print(self.sz_ring)
|
||||
dy = dy + self.sz_ring[_idx_][1]/2 + self.sz_ring[_idx_+1][1]/2 + self.w_ring[_idx_][1]/2+self.w_ring[_idx_+1][1]/2 + self.gap_crows[_idx_]
|
||||
|
||||
# instr = self.ring_cell[_idx_+1].put(0,dy,0)
|
||||
instr = __cell_arg__(arg=self.ring_cell[_idx_+1],arg_name="ring_cell[_idx_+1]",func_name="STD_CROW_V::generate_pic_gds").put(0,dy,0)
|
||||
|
||||
if (_idx_==0):
|
||||
instr.raise_pins(['r1','r2','r3','r4'],['rb1','rb2','rb3','rb4'])
|
||||
|
||||
|
||||
if (len(self.gap_cp)==2):
|
||||
|
||||
BUS_u = self.bus_cell[1].put(0,dy+self.sz_ring[-1][1]/2+self.w_ring[-1][1]/2+self.w_bus/2+self.gap_cp[1],flip=1)
|
||||
nd.Pin(name='a2',pin=BUS_u.pin['a1']).put()
|
||||
nd.Pin(name='b2',pin=BUS_u.pin['b1']).put()
|
||||
|
||||
except Exception as ex:
|
||||
print("ERROR :: ",ex)
|
||||
|
||||
return C
|
||||
|
||||
def generate_eic_gds(self):
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
|
||||
ht_box = [self.sz_ring[0][0],self.sz_ring[0][1]]
|
||||
|
||||
""" BUG : Revised 2023.04.01 """
|
||||
if (self.via_h2m is None):
|
||||
# self.via_h2m = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks
|
||||
VIA = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks
|
||||
|
||||
else:
|
||||
if (hasattr(self.via_h2m,"cell")):
|
||||
# self.via_h2m = self.via_h2m
|
||||
VIA = self.via_h2m
|
||||
else :
|
||||
# self.via_h2m = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias
|
||||
VIA = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias
|
||||
|
||||
# VIA = self.via_h2m
|
||||
|
||||
HT,r_ht,Large_crow = self._generate_HT_box_cell_(ht_box=ht_box,w_heater=self.w_heater[0])
|
||||
cell_pre = HT.put(0,0,0)
|
||||
|
||||
dy = 0
|
||||
|
||||
eic_mt = IC.Interconnect(radius=10,width=self.w_metal,xs=self.xs_metal)
|
||||
eic_ht = IC.Interconnect(radius=10,width=self.w_heater[0],xs=self.xs_heater)
|
||||
|
||||
|
||||
""" Generating heaters """
|
||||
if (self.connected==True and Large_crow==False):
|
||||
|
||||
if (self.via_h2m is None):
|
||||
temp_L = eic_ht.strt(length=self.w_metal+self.w_heater[0],pin=cell_pre.pin['ed1'],arrow=False).put()
|
||||
eic_ht.strt(length=self.w_metal/2+self.ht_shift/2,width=self.w_metal).put(temp_L.pin['b0'].x,temp_L.pin['b0'].y+self.w_metal/2,180)
|
||||
temp_L = VIA.cell.put(temp_L.pin['b0'].x-self.w_metal/2-self.w_heater[0]/2,temp_L.pin['b0'].y+self.w_metal/2,-90)
|
||||
nd.Pin(name='ep1',pin=temp_L.pin['b0']).put()
|
||||
|
||||
temp_R = eic_ht.strt(length=self.w_metal+self.w_heater[0],pin=cell_pre.pin['ed2'],arrow=False).put()
|
||||
eic_ht.strt(length=self.w_metal/2+self.ht_shift/2,width=self.w_metal).put(temp_R.pin['b0'].x,temp_R.pin['b0'].y+self.w_metal/2,0)
|
||||
temp_R = VIA.cell.put(temp_R.pin['b0'].x+self.w_metal/2+self.w_heater[0]/2,temp_R.pin['b0'].y+self.w_metal/2,-90)
|
||||
nd.Pin(name='en1',pin=temp_R.pin['b0']).put()
|
||||
else:
|
||||
temp_L = VIA.cell.put(cell_pre.pin['ed1'],flip=1)
|
||||
nd.Pin(name='ep1',pin=temp_L.pin['b0']).put()
|
||||
|
||||
temp_R = VIA.cell.put(cell_pre.pin['ed2'])
|
||||
nd.Pin(name='en1',pin=temp_R.pin['b0']).put()
|
||||
|
||||
|
||||
|
||||
|
||||
else :
|
||||
nd.Pin(name='ep1',pin=cell_pre.pin['ed1']).put()
|
||||
nd.Pin(name='en1',pin=cell_pre.pin['ed2'].move(0,0,180)).put()
|
||||
|
||||
for _idx_ in range(0,len(self.gap_crows)):
|
||||
|
||||
|
||||
eic_mt = IC.Interconnect(radius=10,width=self.w_metal,xs=self.xs_metal)
|
||||
eic_ht = IC.Interconnect(radius=10,width=self.w_heater[_idx_],xs=self.xs_heater)
|
||||
|
||||
dy = dy + self.sz_ring[_idx_][1]/2 + self.sz_ring[_idx_+1][1]/2 + self.w_ring[_idx_][1]/2+self.w_ring[_idx_+1][1]/2 + self.gap_crows[_idx_]
|
||||
|
||||
ht_box = [self.sz_ring[_idx_+1][0],self.sz_ring[_idx_+1][1]]
|
||||
HT,r_ht,Large_crow = self._generate_HT_box_cell_(ht_box=ht_box,w_heater=self.w_heater[_idx_])
|
||||
cell_cur = HT.put(0,dy,0)
|
||||
|
||||
if (self.connected==True):
|
||||
if (Large_crow==True):
|
||||
eic_mt.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_cur.pin['ed1'],arrow=False).put()
|
||||
eic_mt.strt_p2p(pin1=cell_pre.pin['eu2'],pin2=cell_cur.pin['ed2'],arrow=False).put()
|
||||
else :
|
||||
eic_ht.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_cur.pin['ed1'],arrow=False).put()
|
||||
eic_ht.strt_p2p(pin1=cell_pre.pin['eu2'],pin2=cell_cur.pin['ed2'],arrow=False).put()
|
||||
|
||||
else :
|
||||
# print(_idx_)
|
||||
nd.Pin(name='ep'+str(_idx_+2),pin=cell_cur.pin['ed1']).put()
|
||||
nd.Pin(name='en'+str(_idx_+2),pin=cell_cur.pin['ed2'].move(0,0,180)).put()
|
||||
|
||||
cell_pre = cell_cur
|
||||
|
||||
if (self.connected==True and Large_crow==False): ## revised in 2022.09.23, it cannot work in single ring
|
||||
|
||||
VIA = Vias(xs=VIA.xs,area=self.w_metal,sz=VIA.sz,spacing=VIA.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal,
|
||||
sp_via_xs=VIA.sp_via_xs)
|
||||
temp_L = eic_ht.strt(length=self.w_metal+self.w_heater[-1],pin=cell_pre.pin['eu1'],arrow=False).put()
|
||||
temp_L = VIA.cell.put(temp_L.pin['b0'].x-self.w_metal/2,temp_L.pin['b0'].y-self.w_metal/2,90)
|
||||
|
||||
temp_R = eic_ht.strt(length=self.w_metal+self.w_heater[-1],pin=cell_pre.pin['eu2'],arrow=False).put()
|
||||
temp_R = VIA.cell.put(temp_R.pin['b0'].x+self.w_metal/2,temp_R.pin['b0'].y-self.w_metal/2,-90)
|
||||
eic_mt.strt_p2p(pin1=temp_L.pin['b0'],pin2=temp_R.pin['b0'],arrow=False).put()
|
||||
|
||||
elif (self.connected==True):
|
||||
eic_mt.strt_p2p(pin1=cell_pre.pin['eu1'],pin2=cell_pre.pin['eu2'],arrow=False).put()
|
||||
|
||||
if (self.isl is not None):
|
||||
# print(dy,self.sz_ring,self.sz_bus)
|
||||
L_isl = dy+self.sz_ring[0][1]/2+self.sz_ring[-1][1]/2 - self.sz_bus[0][1] - self.sz_bus[-1][1] - self.isl.sp_isl_wg*2
|
||||
if (L_isl>0):
|
||||
_x_ = []
|
||||
for _sz_ in self.sz_ring:
|
||||
_x_.append(_sz_[0])
|
||||
|
||||
x_isl = max(_x_)/2 + max(self.w_heater) + self.isl.sp_isl_metal
|
||||
if (self.ISL_RIGHT):
|
||||
ISL(xs=self.isl.xs,width=self.isl.width,length=L_isl,Lmax=self.isl.Lmax,spacing=self.isl.spacing).cell.put(x_isl,dy/2-L_isl/2,90)
|
||||
|
||||
if (self.ISL_LEFT):
|
||||
ISL(xs=self.isl.xs,width=self.isl.width,length=L_isl,Lmax=self.isl.Lmax,spacing=self.isl.spacing).cell.put(-x_isl,dy/2-L_isl/2,90)
|
||||
|
||||
return C
|
||||
|
||||
def _generate_HT_box_cell_(self,ht_box,w_heater):
|
||||
r_ht = min(ht_box)/2
|
||||
l_ht = ht_box[1]-r_ht*2
|
||||
|
||||
if (hasattr(self,'A_ht')):
|
||||
A_ht = self.A_ht
|
||||
else :
|
||||
A_ht = 45
|
||||
Arc_ht = A_ht/180*np.pi
|
||||
Large_crow = r_ht*np.sin(Arc_ht)>=self.w_metal
|
||||
|
||||
## generate heater unit cell
|
||||
### if heater side-side distance is larger than w_metal, vias will be added
|
||||
with nd.Cell(instantiate=False) as HT:
|
||||
x_ht = ht_box[0]/2-r_ht+self.ht_shift/2
|
||||
y_ht = ht_box[1]/2-r_ht
|
||||
circle(radius=r_ht,width=w_heater,theta_start=0 ,theta_stop=A_ht,res=0.05,
|
||||
xs=self.xs_heater).cell.put(x_ht,y_ht,0)
|
||||
circle(radius=r_ht,width=w_heater,theta_start=180-A_ht,theta_stop=180,res=0.05,
|
||||
xs=self.xs_heater).cell.put(-x_ht,y_ht,0)
|
||||
nd.strt(length=l_ht,width=w_heater,xs=self.xs_heater).put(-(x_ht+r_ht),-l_ht/2,90)
|
||||
nd.strt(length=l_ht,width=w_heater,xs=self.xs_heater).put( (x_ht+r_ht),-l_ht/2,90)
|
||||
|
||||
""" Revised in 2023.2.2, """
|
||||
circle(radius=r_ht,width=w_heater,theta_start=180,theta_stop=180+A_ht,res=0.05,
|
||||
xs=self.xs_heater).cell.put(-x_ht,-y_ht,0) ## revised : 2023.2.2, <x_ht> -> <x_ht>
|
||||
circle(radius=r_ht,width=w_heater,theta_start=360-A_ht,theta_stop=360,res=0.05,
|
||||
xs=self.xs_heater).cell.put(x_ht,-y_ht,0)
|
||||
|
||||
## used to see whether crow is large
|
||||
|
||||
""" Generate VIAS, two situations: 1. Heaters not connected, 2.Side-Side distance larger than w_metal """
|
||||
if (self.connected==False or Large_crow==True):
|
||||
|
||||
VIA_MT = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal)
|
||||
|
||||
_x_via_ = x_ht-r_ht*(1-np.cos(Arc_ht))+r_ht
|
||||
temp = VIA_MT.cell.put( _x_via_, y_ht+r_ht*np.sin(Arc_ht),0)
|
||||
nd.Pin(name='eu1',pin=temp.pin['a0'].rot(180)).put()
|
||||
if (self.connected==False):
|
||||
nd.strt(length=r_ht*np.cos(Arc_ht)*2,width=self.w_metal,xs=self.xs_metal).put(temp.pin['a0'].x,temp.pin['a0'].y,180)
|
||||
|
||||
temp = VIA_MT.cell.put( _x_via_,-y_ht-r_ht*np.sin(Arc_ht),0)
|
||||
nd.Pin(name='ed1',pin=temp.pin['a0'].rot(180)).put()
|
||||
|
||||
temp = VIA_MT.cell.put( -_x_via_, y_ht+r_ht*np.sin(Arc_ht),0)
|
||||
nd.Pin(name='eu2',pin=temp.pin['a0'].rot(180)).put()
|
||||
|
||||
temp = VIA_MT.cell.put( -_x_via_,-y_ht-r_ht*np.sin(Arc_ht),0)
|
||||
nd.Pin(name='ed2',pin=temp.pin['a0'].rot(180)).put()
|
||||
|
||||
|
||||
else:
|
||||
L_cnt = w_heater
|
||||
|
||||
x_ht_cnt = (r_ht-w_heater/2)*np.cos(Arc_ht)+w_heater/2+x_ht
|
||||
|
||||
y_ht_cnt = y_ht+(r_ht-w_heater/2)*np.sin(Arc_ht)
|
||||
temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put(-x_ht_cnt, y_ht_cnt,90)
|
||||
nd.Pin(name='eu1',pin=temp.pin['b0']).put()
|
||||
|
||||
temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put( x_ht_cnt, y_ht_cnt,90)
|
||||
nd.Pin(name='eu2',pin=temp.pin['b0']).put()
|
||||
|
||||
temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put(-x_ht_cnt,-y_ht_cnt,-90)
|
||||
nd.Pin(name='ed1',pin=temp.pin['b0']).put()
|
||||
|
||||
temp = nd.strt(length=L_cnt,width=w_heater,xs=self.xs_heater).put( x_ht_cnt,-y_ht_cnt,-90)
|
||||
nd.Pin(name='ed2',pin=temp.pin['b0']).put()
|
||||
|
||||
return HT,r_ht,Large_crow
|
||||
|
||||
|
||||
class CROW_Eul_Ring(STD_CROW_V) :
|
||||
def __init__(self,
|
||||
name: str,
|
||||
R0: int = 10, R1: int=3,
|
||||
w0: float = 0.38,w1: float=0.65,
|
||||
w_bus: float=0.35,
|
||||
R_att: int=15,
|
||||
R_att_min: int = 3,
|
||||
A_att: int=30,w_wg: float=0.45,
|
||||
dLx: float = 0, dLy: float=0,
|
||||
xs_wg: str='strip',
|
||||
gap_crows: list=[0.4],
|
||||
gap_cp: float=0.45,
|
||||
w_heater: float=0, xs_heater: str='heater',
|
||||
connected: bool=True,
|
||||
w_metal: float=8, xs_metal: str='metal',
|
||||
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
ISL_LEFT: bool=True, ISL_RIGHT: bool=True, show_pins: bool=False,
|
||||
sharp_patch: bool=True,
|
||||
dL_p2p: Optional[float] = None,
|
||||
Ltp_bus: int = 0,
|
||||
ht_shift: int = 0,
|
||||
A_ht: int=45,
|
||||
R_cp: Any = None,
|
||||
bus_order: float = 1.0,
|
||||
width_type: str = 'crow_customize',
|
||||
A_cp: int=0,) -> None:
|
||||
|
||||
if (R_cp==None):
|
||||
if (isinstance(gap_cp,int) or isinstance(gap_cp,float)):
|
||||
R_cp = R0+w0/2+gap_cp+w_bus/2
|
||||
else:
|
||||
R_cp = R0+w0/2+gap_cp[0]+w_bus/2
|
||||
|
||||
""" Revised in 2022.11.25 """
|
||||
self.w0 = w0
|
||||
self.w1 = w1
|
||||
self.R0 = R0
|
||||
self.R1 = R1
|
||||
self.xs_wg = xs_wg
|
||||
|
||||
self.R_att = R_att
|
||||
self.A_att = A_att
|
||||
|
||||
self.width_type = width_type
|
||||
euler = Clothoid(R = [R0,R1],w=[w0,w1],Rmax=max([R0,R1])*10,A=[0,90],xs=xs_wg,width_type=width_type,dL_wg=0.05)
|
||||
ring = Racetrack(bend_cell=euler,xs=xs_wg,layer=None,dLx=dLx,dLy=dLy)
|
||||
sz_ring = ring.sz
|
||||
w_ring = ring.w
|
||||
# ring = ring.cell
|
||||
ring = ring
|
||||
|
||||
bus = ring_bus_wg(xs=xs_wg, R_cp=R_cp, ### Revise 2022.11.25
|
||||
w_bus=w_bus,bend_DC=True, w_wg=w_wg, dAc=A_cp,
|
||||
euler_anti_bend=True,euler_transistion=True,
|
||||
R_max_trans=R_att,dA_trans=A_att,dL_trans=0,
|
||||
w_trans=w_bus,
|
||||
R_max_anti=R_att,R_min_anti=R_att_min,sharp_patch=sharp_patch,
|
||||
show_pins=False,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,
|
||||
res=0.05,
|
||||
clothoid_order=bus_order
|
||||
)
|
||||
|
||||
self.bus = bus
|
||||
|
||||
super().__init__(ring=ring,
|
||||
name= name,
|
||||
bus=bus.cell,
|
||||
w_bus=bus.w,
|
||||
w_ring=w_ring,
|
||||
sz_ring=sz_ring,
|
||||
sz_bus=bus.sz,
|
||||
gap_crows=gap_crows,
|
||||
gap_cp=gap_cp,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=ISL_LEFT,
|
||||
ISL_RIGHT=ISL_RIGHT,
|
||||
show_pins=show_pins,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
class CROW_Eul_RCK(STD_CROW_V) :
|
||||
def __init__(self,
|
||||
R0: int = 10, R1: int=3,R2: int=20,
|
||||
w0: float = 0.38,w1: float=0.65,
|
||||
w_bus: float=0.35,
|
||||
R_att: int=15,
|
||||
R_att_min: int = 3,
|
||||
A_att: int=30,w_wg: float=0.45,dAc: float=0,
|
||||
dLx: float = 0, dLy: float=0,
|
||||
xs_wg: str='strip',
|
||||
gap_crows: list=[0.4],
|
||||
gap_cp: float=0.45,
|
||||
w_heater: float=0, xs_heater: str='heater',
|
||||
connected: bool=True,
|
||||
w_metal: float=8, xs_metal: str='metal',
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
ISL_LEFT: bool=True, ISL_RIGHT: bool=True, show_pins: bool=False,
|
||||
sharp_patch: bool=True,
|
||||
dL_p2p: Optional[float] = None,
|
||||
Ltp_bus: int = 0,
|
||||
ht_shift: int = 0,
|
||||
A_ht: int=45) -> None:
|
||||
|
||||
if (isinstance(gap_cp,int) or isinstance(gap_cp,float)):
|
||||
R_cp = R0+w0/2+gap_cp+w_bus/2
|
||||
else:
|
||||
R_cp = R0+w0/2+gap_cp[0]+w_bus/2
|
||||
|
||||
# euler = spiral_dual(R0=R0,R1=R1,R2=R2,w0=w0,w1=w1,Rmax=max([R0,R1,R2])*10,xs=xs_wg,width_type='sine')
|
||||
""" Revised in 2022.11.25 """
|
||||
euler = Clothoid(R = [R0,R1,R2],w=[w0,w1],Rmax=max([R0,R1,R2])*10,A=[0,45,90],xs=xs_wg,width_type='sine' )
|
||||
ring = Racetrack(bend_cell=euler,xs=xs_wg,layer=None,dLx=dLx,dLy=dLy)
|
||||
sz_ring = ring.sz
|
||||
w_ring = ring.w
|
||||
ring = ring.cell
|
||||
# ring,sz_ring,w_ring = euler.racetrack(dLy=dLy,dLx=dLx)
|
||||
|
||||
bus = ring_bus_wg(xs=xs_wg, R_cp=R_cp, ### Revise 2022.11.25
|
||||
w_bus=w_bus,bend_DC=True, w_wg=w_wg, dAc=dAc,
|
||||
euler_anti_bend=True,euler_transistion=True,
|
||||
R_max_trans=R_att,dA_trans=A_att,dL_trans=0,
|
||||
w_trans=w_bus,
|
||||
R_max_anti=R_att,R_min_anti=R_att_min,sharp_patch=sharp_patch,
|
||||
show_pins=False,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,
|
||||
)
|
||||
|
||||
|
||||
|
||||
super().__init__(ring=ring,
|
||||
|
||||
bus=bus.cell,
|
||||
w_bus=bus.w,
|
||||
w_ring=w_ring,
|
||||
sz_ring=sz_ring,
|
||||
sz_bus=bus.sz,
|
||||
gap_crows=gap_crows,
|
||||
gap_cp=gap_cp,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=ISL_LEFT,
|
||||
ISL_RIGHT=ISL_RIGHT,
|
||||
show_pins=show_pins,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
""" Circular ring """
|
||||
class CROW_Circular_ring(STD_CROW_V):
|
||||
def __init__(self,
|
||||
r_ring: float = 10, w_ring:float = 0.45,xs_ring: str='strip',
|
||||
w1_bus: float = 0.45,A1_cp: int = 10,
|
||||
w2_bus: float = 0.45,A2_cp: int = 10,
|
||||
gap1: float = 0.45, gap2: float = 0.45,
|
||||
w_wg: float = 0.45,
|
||||
Euler_trasition: bool=True,
|
||||
R1_cp: Any = None,
|
||||
R2_cp: Any = None,
|
||||
R1_att:float = 10,
|
||||
R2_att:float = 10,
|
||||
R1_att_min: float = 5,
|
||||
R2_att_min: float = 5,
|
||||
A1_att: int = 45,
|
||||
A2_att: int = 45,
|
||||
gap_crows: 'float|list' = [0.4],
|
||||
w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater',
|
||||
connected: 'bool' = True, w_metal: 'float' = 8,
|
||||
xs_metal: 'str' = 'metal',
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
ISL_LEFT: 'bool' = True, ISL_RIGHT: 'bool' = True,
|
||||
show_pins: 'bool' = False,
|
||||
sharp_patch: bool = True,
|
||||
dL_p2p: Optional[float] = None,
|
||||
Ltp_bus: int = 0,
|
||||
ht_shift: int=0,
|
||||
A_ht: int = 45) -> None:
|
||||
|
||||
## defining ring list
|
||||
if (isinstance(r_ring,int) or isinstance(r_ring,float)):
|
||||
ring = circle(radius=r_ring,width=w_ring,
|
||||
# n_points=128,
|
||||
res=0.05,
|
||||
xs=xs_ring)
|
||||
ring_cell = ring.cell
|
||||
ring_sz = ring.sz
|
||||
ring_w = ring.w
|
||||
r_ring = [r_ring]
|
||||
w_ring = [w_ring]
|
||||
|
||||
elif (isinstance(r_ring,list) or isinstance(r_ring,np.ndarray)):
|
||||
if (len(r_ring)!=len(w_ring)):
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <r_ring> does not match <w_ring>")
|
||||
|
||||
ring_cell = []
|
||||
ring_sz = []
|
||||
ring_w = []
|
||||
for _idx_ in range(0,len(r_ring)):
|
||||
_ring_ = circle(radius=r_ring[_idx_],width=w_ring[_idx_],res=0.05,
|
||||
# n_points=128,
|
||||
xs=xs_ring)
|
||||
ring_cell.append(_ring_.cell)
|
||||
ring_sz.append(_ring_.sz)
|
||||
ring_w.append(_ring_.w)
|
||||
|
||||
## expand to N*2 dimension list, [[sz0,sz1],[sz0,sz1]]
|
||||
# ring_sz = [ring_sz,ring_sz]
|
||||
# ring_w = [ring_w,ring_w]
|
||||
else :
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <r_ring> is not recongized, please input type <int,float,list,numpy.ndarray>")
|
||||
|
||||
if (w1_bus<=0):
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <w1_bus> should larger than 0")
|
||||
|
||||
if (R1_cp==None):
|
||||
R1_cp = w1_bus/2 + r_ring[0] + w_ring[0]/2 + gap1
|
||||
|
||||
BUS_U = ring_bus_wg(xs=xs_ring, R_cp=R1_cp, ### Revise 2022.11.25
|
||||
w_bus=w1_bus,bend_DC=True, w_wg=w_wg, dAc=A1_cp,
|
||||
euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition,
|
||||
R_max_trans=R1_att,dA_trans=A1_att,dL_trans=0,
|
||||
w_trans=w1_bus,
|
||||
R_max_anti=R1_att,R_min_anti=R1_att_min,sharp_patch=sharp_patch,
|
||||
show_pins=False,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,
|
||||
res=0.05,
|
||||
)
|
||||
|
||||
bus_cell = [BUS_U.cell]
|
||||
bus_w = BUS_U.w
|
||||
bus_sz = BUS_U.sz
|
||||
gap_cp = [gap1]
|
||||
|
||||
""" Add-drop CROW """
|
||||
if (w2_bus>0):
|
||||
|
||||
if (R2_cp==None):
|
||||
R2_cp = w2_bus/2 + r_ring[-1] + w_ring[-1]/2 + gap2
|
||||
|
||||
BUS_D = ring_bus_wg(xs=xs_ring, R_cp=R2_cp, ### Revise 2022.11.25
|
||||
w_bus=w2_bus,bend_DC=True, w_wg=w_wg, dAc=A2_cp,
|
||||
|
||||
euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition,
|
||||
R_max_trans=R2_att,dA_trans=A2_att,dL_trans=0,
|
||||
w_trans=w2_bus,
|
||||
R_max_anti=R2_att,R_min_anti=R2_att_min,sharp_patch=sharp_patch,
|
||||
show_pins=False,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,
|
||||
)
|
||||
|
||||
bus_cell = [BUS_U.cell,BUS_D.cell]
|
||||
bus_w = [BUS_U.w,BUS_D.w]
|
||||
bus_sz = [BUS_U.sz,BUS_D.sz]
|
||||
gap_cp = [gap1,gap2]
|
||||
|
||||
|
||||
super().__init__(ring=ring_cell,
|
||||
|
||||
bus=bus_cell,
|
||||
w_bus=bus_w,
|
||||
w_ring=ring_w,
|
||||
sz_ring=ring_sz,
|
||||
sz_bus=bus_sz,
|
||||
gap_crows=gap_crows,
|
||||
gap_cp=gap_cp,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=ISL_LEFT,
|
||||
ISL_RIGHT=ISL_RIGHT,
|
||||
show_pins=show_pins,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
""" CROW with standard identical ring """
|
||||
class CROW_STD_Allpass(CROW_Circular_ring):
|
||||
def __init__(self,
|
||||
r_ring: float=10,
|
||||
w_ring: float = 0.45,
|
||||
xs_ring: str='strip',
|
||||
w_bus: float=0.45,
|
||||
A_cp: int=10,
|
||||
gap_bus: float=0.45,
|
||||
w_wg: float=0.45,
|
||||
Euler_trasition: bool=True,
|
||||
R_att: float = 10,
|
||||
R_att_min: float = 5,
|
||||
A_att: int=45,
|
||||
gap_crows: 'float|list' = [0.4],
|
||||
w_heater: 'float|list' = 0,
|
||||
xs_heater: 'str' = 'heater',
|
||||
connected: 'bool' = True,
|
||||
w_metal: 'float' = 8,
|
||||
xs_metal: 'str' = 'metal',
|
||||
via_h2m: Any=None,
|
||||
isl: Any=None,
|
||||
show_pins: 'bool' = False,
|
||||
sharp_patch: bool=True,
|
||||
dL_p2p: Optional[float]=None,
|
||||
Ltp_bus: int=0,
|
||||
ht_shift: int=0,
|
||||
A_ht: int=45) -> None:
|
||||
|
||||
super().__init__(r_ring=r_ring, w_ring=w_ring,
|
||||
xs_ring=xs_ring,
|
||||
w1_bus=w_bus,
|
||||
A1_cp=A_cp,
|
||||
w2_bus=0,
|
||||
A2_cp=0,
|
||||
gap1=gap_bus,
|
||||
gap2=gap_bus,
|
||||
w_wg=w_wg,
|
||||
Euler_trasition=Euler_trasition,
|
||||
R1_cp=None,
|
||||
R2_cp=None,
|
||||
R1_att=R_att,
|
||||
R2_att=R_att,
|
||||
R1_att_min=R_att_min,
|
||||
R2_att_min=R_att_min,
|
||||
A1_att=A_att,
|
||||
A2_att=A_att,
|
||||
gap_crows=gap_crows,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=True,
|
||||
ISL_RIGHT=True,
|
||||
show_pins=show_pins,
|
||||
sharp_patch=sharp_patch,
|
||||
dL_p2p=dL_p2p,
|
||||
Ltp_bus=Ltp_bus,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
class CROW_STD_Adddrop(CROW_Circular_ring):
|
||||
def __init__(self,
|
||||
r_ring: float=10,
|
||||
w_ring: float = 0.45,
|
||||
xs_ring: str='strip',
|
||||
w_bus: float=0.45,
|
||||
A_cp: int=10,
|
||||
gap_bus: float=0.45,
|
||||
w_wg: float=0.45,
|
||||
Euler_trasition: bool=True,
|
||||
R_att: float = 10,
|
||||
R_att_min: float = 5,
|
||||
A_att: int=45,
|
||||
gap_crows: 'float|list' = [0.4],
|
||||
w_heater: 'float|list' = 0,
|
||||
xs_heater: 'str' = 'heater',
|
||||
connected: 'bool' = True,
|
||||
w_metal: 'float' = 8,
|
||||
xs_metal: 'str' = 'metal',
|
||||
via_h2m: Any=None,
|
||||
isl: Any=None,
|
||||
show_pins: 'bool' = False,
|
||||
sharp_patch: bool=True,
|
||||
dL_p2p: Optional[float]=None,
|
||||
Ltp_bus: int=0,
|
||||
ht_shift: int=0,
|
||||
A_ht: int=45) -> None:
|
||||
|
||||
super().__init__(r_ring=r_ring, w_ring=w_ring,
|
||||
xs_ring=xs_ring,
|
||||
w1_bus=w_bus,
|
||||
A1_cp=A_cp,
|
||||
w2_bus=w_bus,
|
||||
A2_cp=A_cp,
|
||||
gap1=gap_bus,
|
||||
gap2=gap_bus,
|
||||
w_wg=w_wg,
|
||||
Euler_trasition=Euler_trasition,
|
||||
R1_cp=None,
|
||||
R2_cp=None,
|
||||
R1_att=R_att,
|
||||
R2_att=R_att,
|
||||
R1_att_min=R_att_min,
|
||||
R2_att_min=R_att_min,
|
||||
A1_att=A_att,
|
||||
A2_att=A_att,
|
||||
gap_crows=gap_crows,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=True,
|
||||
ISL_RIGHT=True,
|
||||
show_pins=show_pins,
|
||||
sharp_patch=sharp_patch,
|
||||
dL_p2p=dL_p2p,
|
||||
Ltp_bus=Ltp_bus,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
|
||||
""" Adiabatic Elipse Diameter """
|
||||
class CROW_AED(STD_CROW_V):
|
||||
def __init__(self,
|
||||
r_outer: float = 10,
|
||||
wa: float = 0.45,
|
||||
wb: float = 0.45,
|
||||
xs_ring: str='strip',
|
||||
w1_bus: float = 0.45,A1_cp: int = 10,
|
||||
w2_bus: float = 0.45,A2_cp: int = 10,
|
||||
gap1: float = 0.45, gap2: float = 0.45,
|
||||
w_wg: float = 0.45,
|
||||
Euler_trasition: bool=True,
|
||||
R1_cp:float = None,
|
||||
R2_cp:float = None,
|
||||
|
||||
R1_att:float = 15,
|
||||
R2_att:float = 15,
|
||||
R1_att_min:float = 5,
|
||||
R2_att_min:float = 5,
|
||||
L_tilt: int = 0,
|
||||
A1_att: int = 45,
|
||||
A2_att: int = 45,
|
||||
Ltp_bus: int = 0,
|
||||
dL_p2p: Optional[float]=None,
|
||||
gap_crows: 'float|list' = [0.4],
|
||||
gap_cp: 'float|list' = [0.45, 0.45],
|
||||
w_heater: 'float|list' = 0, xs_heater: 'str' = 'heater',
|
||||
connected: 'bool' = True, w_metal: 'float' = 8,
|
||||
xs_metal: 'str' = 'metal',
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
ISL_LEFT: 'bool' = True, ISL_RIGHT: 'bool' = True,
|
||||
show_pins: 'bool' = False,
|
||||
sharp_patch: bool=True,
|
||||
ht_shift: int = 0,
|
||||
A_ht: int=45) -> None:
|
||||
|
||||
## defining ring list
|
||||
if (isinstance(r_outer,int) or isinstance(r_outer,float)):
|
||||
ring = Elipse_dual(ORx=r_outer,ORy=r_outer,IRx=r_outer-wa,IRy=r_outer-wb,
|
||||
# n_points=128,
|
||||
xs=xs_ring)
|
||||
ring_cell = ring.cell
|
||||
ring_sz = ring.sz
|
||||
ring_w = ring.wb
|
||||
r_outer = [r_outer]
|
||||
wa = [wa]
|
||||
wb = [wb]
|
||||
|
||||
elif (isinstance(r_outer,list) or isinstance(r_outer,np.ndarray)):
|
||||
if (len(r_outer)!=len(wa)):
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <r_outer> does not match <w_ring>")
|
||||
|
||||
ring_cell = []
|
||||
ring_sz = []
|
||||
ring_w = []
|
||||
for _idx_ in range(0,len(r_outer)):
|
||||
_ring_ = Elipse_dual(ORx=r_outer[_idx_],ORy=r_outer[_idx_],IRx=r_outer[_idx_]-wa[_idx_],IRy=r_outer[_idx_]-wb[_idx_],
|
||||
# n_points=128,
|
||||
xs=xs_ring)
|
||||
ring_cell.append(_ring_.cell)
|
||||
ring_sz.append(_ring_.sz)
|
||||
ring_w.append(_ring_.wb)
|
||||
|
||||
## expand to N*2 dimension list, [[sz0,sz1],[sz0,sz1]]
|
||||
# ring_sz = [ring_sz,ring_sz]
|
||||
# ring_w = [ring_w,ring_w]
|
||||
else :
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <r_ring> is not recongized, please input type <int,float,list,numpy.ndarray>")
|
||||
|
||||
if (w1_bus<=0):
|
||||
raise Exception("ERROR: In <mxpic::passive::STD_circle_ring_CROW>, <w1_bus> should larger than 0")
|
||||
|
||||
R1_cp = w1_bus/2 + r_outer[0] + wb[0]/2 + gap1
|
||||
|
||||
### generating coupling BUS waveguide
|
||||
BUS_U = ring_bus_wg(xs=xs_ring, R_cp=R1_cp,
|
||||
w_bus=w1_bus,bend_DC=True, w_wg=w_wg, dAc=A1_cp,
|
||||
euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition,
|
||||
R_max_trans=R1_att,dA_trans=A1_att,dL_trans=L_tilt,
|
||||
w_trans=w1_bus,
|
||||
R_max_anti=R1_att,R_min_anti=R1_att_min,sharp_patch=sharp_patch,show_pins=show_pins,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,
|
||||
)
|
||||
|
||||
bus_cell = [BUS_U.cell]
|
||||
bus_w = BUS_U.w
|
||||
bus_sz = BUS_U.sz
|
||||
|
||||
|
||||
if (w2_bus>0):
|
||||
|
||||
R2_cp = w2_bus/2 + r_outer[-1] + wb[-1]/2 + gap2
|
||||
BUS_D = ring_bus_wg(xs=xs_ring, R_cp=R2_cp,
|
||||
w_bus=w2_bus,bend_DC=True, w_wg=w_wg, dAc=A2_cp,
|
||||
euler_anti_bend=Euler_trasition,euler_transistion=Euler_trasition,
|
||||
R_max_trans=R2_att,dA_trans=A2_att,dL_trans=L_tilt,
|
||||
w_trans=w2_bus,
|
||||
R_max_anti=R2_att,R_min_anti=R2_att_min,sharp_patch=sharp_patch,show_pins=show_pins,
|
||||
dL_p2p=dL_p2p,
|
||||
wg_Ltp=Ltp_bus,)
|
||||
|
||||
bus_cell = [BUS_U.cell,BUS_D.cell]
|
||||
bus_w = [BUS_U.w,BUS_D.w]
|
||||
bus_sz = [BUS_U.sz,BUS_D.sz]
|
||||
|
||||
|
||||
super().__init__(ring=ring_cell,
|
||||
|
||||
bus=bus_cell,
|
||||
w_bus=bus_w,
|
||||
w_ring=ring_w,
|
||||
sz_ring=ring_sz,
|
||||
sz_bus=bus_sz,
|
||||
gap_crows=gap_crows,
|
||||
gap_cp=gap_cp,
|
||||
w_heater=w_heater,
|
||||
xs_heater=xs_heater,
|
||||
connected=connected,
|
||||
w_metal=w_metal,
|
||||
xs_metal=xs_metal,
|
||||
via_h2m=via_h2m,
|
||||
isl=isl,
|
||||
ISL_LEFT=ISL_LEFT,
|
||||
ISL_RIGHT=ISL_RIGHT,
|
||||
show_pins=show_pins,
|
||||
ht_shift=ht_shift,
|
||||
A_ht=A_ht)
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,527 @@
|
||||
|
||||
from typing import Any, Optional
|
||||
import nazca as nd
|
||||
import numpy as np
|
||||
|
||||
from ...structures import *
|
||||
from ....technologies import *
|
||||
from ...electronics import Vias
|
||||
from ...electronics import ISL
|
||||
|
||||
import nazca.interconnects as IC
|
||||
from ...basic import __xs_exist__,__cell_arg__
|
||||
from ..pic import taper_xs2xs
|
||||
from ...routing import Route
|
||||
# class Route(IC.Interconnect):
|
||||
# pass
|
||||
|
||||
|
||||
class waveguide:
|
||||
def __init__(self,
|
||||
w_heater: float=2.5,
|
||||
L_wg: int=150,
|
||||
L_heater: int=150,
|
||||
w_metal: float=10,
|
||||
|
||||
xs_heater: str='heater',
|
||||
xs_metal: str='metal',
|
||||
xs_wg: str = 'strip',
|
||||
|
||||
w_wg: float = 0.45,
|
||||
w_port: Optional[float] = None,
|
||||
Ltp: Any = None,
|
||||
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
|
||||
euler_bend: bool = False,
|
||||
Rmin: int = 5,
|
||||
thin_attach: bool = False,
|
||||
UPPER_ISL: bool = True,
|
||||
LOWER_ISL: bool = True,
|
||||
shape: str = 'strip',
|
||||
R_bend: int=10,
|
||||
ubend_offset: int=20,
|
||||
show_pins: bool=False) -> None:
|
||||
|
||||
|
||||
""" Revised in 2022.12.30, to simplify the function logic """
|
||||
if (w_heater>0 and xs_heater!=None and xs_metal!=None):
|
||||
|
||||
xs_heater = __xs_exist__(xs=xs_heater,para_name="xs_heater",func_name="mxpic::passive::waveguide")
|
||||
xs_metal = __xs_exist__(xs=xs_metal,para_name="xs_metal",func_name="mxpic::passive::waveguide")
|
||||
|
||||
|
||||
if (w_port==None):
|
||||
w_port = w_wg
|
||||
if (Ltp==None):
|
||||
Ltp=0
|
||||
|
||||
""" Generating the basic via_h2m """
|
||||
if (via_h2m==None):
|
||||
vias = Vias(xs=None,area=w_metal,sz=0,spacing=0,xs_l1=xs_heater,xs_l2=xs_metal) ## only putting metal blocks
|
||||
|
||||
else:
|
||||
if (hasattr(via_h2m,"cell")):
|
||||
vias = via_h2m
|
||||
else :
|
||||
vias = Vias(xs=via_h2m.xs,area=w_metal,sz=via_h2m.sz,spacing=via_h2m.spacing,xs_l1=xs_heater,xs_l2=xs_metal) ## placing vias
|
||||
|
||||
if (L_heater==None):
|
||||
L_heater = L_wg
|
||||
### Adding the straight waveguide
|
||||
if (shape=='strip'):
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
nd.taper(length=Ltp,width1=w_port,width2=w_wg,xs=xs_wg).put(-L_wg/2,0,0)
|
||||
nd.strt(length=L_wg-2*Ltp,width=w_wg,xs=xs_wg).put()
|
||||
nd.taper(length=Ltp,width2=w_port,width1=w_wg,xs=xs_wg).put()
|
||||
nd.Pin(name='a1',width=w_wg).put(-L_wg/2,0,180)
|
||||
nd.Pin(name='b1',width=w_wg).put( L_wg/2,0,0)
|
||||
L_heater = np.min([L_wg,L_heater])
|
||||
|
||||
### placing heaters
|
||||
if (w_heater>0 and xs_heater!=None and xs_metal!=None):
|
||||
nd.strt(length=L_heater,width=w_heater,xs=xs_heater).put(-L_heater/2,0,0)
|
||||
|
||||
if (thin_attach==False):
|
||||
# VIAL = vias.cell.put(-L_heater/2+w_metal/2,0,180,flip=1)
|
||||
# VIAR = vias.cell.put( L_heater/2-w_metal/2,0,0)
|
||||
VIAL = vias.cell.put(-L_heater/2,0,180,flip=1)
|
||||
VIAR = vias.cell.put( L_heater/2,0,0)
|
||||
|
||||
else :
|
||||
# VIAL = vias.cell.put(-L_heater/2+w_metal/2,0,180,flip=1)
|
||||
# VIAR = vias.cell.put( L_heater/2-w_metal/2,0,0)
|
||||
VIAL = vias.cell.put(-L_heater/2,0,180,flip=1)
|
||||
VIAR = vias.cell.put( L_heater/2,0,0)
|
||||
|
||||
nd.Pin(name='ep1',width=w_metal,pin=VIAL.pin['b0']).put()
|
||||
nd.Pin(name='en1',width=w_metal,pin=VIAR.pin['b0']).put()
|
||||
|
||||
if (isl!=None):
|
||||
if (UPPER_ISL):
|
||||
ISL(length=L_heater, ## variables
|
||||
xs=isl.xs,width=isl.width,spacing=isl.spacing,Lmax=isl.Lmax ## default parameters
|
||||
).cell.put(-L_heater/2,-w_metal/2-isl.width/2-isl.sp_isl_metal,0)
|
||||
if (LOWER_ISL):
|
||||
ISL(length=L_heater, ## variables
|
||||
xs=isl.xs,width=isl.width,spacing=isl.spacing,Lmax=isl.Lmax ## default parameters
|
||||
).cell.put(-L_heater/2,w_metal/2+isl.width/2+isl.sp_isl_metal,0)
|
||||
|
||||
### Adding the bend shape waveguide
|
||||
elif (shape == 'ubend'):
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
if (euler_bend):
|
||||
bd = Clothoid(R=[R_bend,Rmin,R_bend],w=[w_wg,w_wg],A=[0,90,180],xs=xs_wg,n_points=64)
|
||||
ubend_offset = bd.sz[1]
|
||||
R_ht = bd.sz[1]/2
|
||||
L_wg_mid = 0
|
||||
L_wg_side = (L_wg-L_wg_mid)/2-R_bend
|
||||
wg_in = nd.strt(length=L_wg_side,width=w_wg,xs=xs_wg).put(-ubend_offset/2,0,90)
|
||||
bd.cell.put(flip=1)
|
||||
wg_out = nd.strt(length=L_wg_side,width=w_wg,xs=xs_wg).put()
|
||||
nd.Pin(name='a1',width=w_wg,pin=wg_in.pin['a0']).put()
|
||||
nd.Pin(name='b1',width=w_wg,pin=wg_out.pin['b0']).put()
|
||||
else:
|
||||
R_ht = R_bend
|
||||
L_wg_mid = ubend_offset-R_bend*2
|
||||
L_wg_side = (L_wg-L_wg_mid-R_bend*np.pi)/2
|
||||
wg_in = nd.strt(length=L_wg_side,width=w_wg,xs=xs_wg).put(-ubend_offset/2,0,90)
|
||||
nd.bend(radius=R_bend,width=w_wg,xs=xs_wg).put(flip=1)
|
||||
nd.strt(length=L_wg_mid,width=w_wg,xs=xs_wg).put()
|
||||
nd.bend(radius=R_bend,width=w_wg,xs=xs_wg).put(flip=1)
|
||||
wg_out = nd.strt(length=L_wg_side,width=w_wg,xs=xs_wg).put()
|
||||
nd.Pin(name='a1',width=w_wg,pin=wg_in.pin['a0']).put()
|
||||
nd.Pin(name='b1',width=w_wg,pin=wg_out.pin['b0']).put()
|
||||
|
||||
L_heater = np.max([L_wg_mid+R_bend+w_metal*2,L_heater])
|
||||
L_heater = np.min([L_wg,L_heater])
|
||||
|
||||
if (w_heater>0):
|
||||
|
||||
L_ht_side = (L_heater-L_wg_mid)/2-R_bend
|
||||
ht_in = nd.strt(length=L_ht_side,width=w_heater,xs=xs_heater).put(-ubend_offset/2,L_wg_side-L_ht_side,90)
|
||||
nd.bend(radius=R_ht,width=w_heater,xs=xs_heater).put(flip=1)
|
||||
nd.strt(length=(ubend_offset-R_ht*2),width=w_heater,xs=xs_heater).put()
|
||||
nd.bend(radius=R_ht,width=w_heater,xs=xs_heater).put(flip=1)
|
||||
ht_out = nd.strt(length=L_ht_side,width=w_heater,xs=xs_heater).put()
|
||||
|
||||
# nd.strt(length=w_metal,width=w_metal,xs=xs_metal).put(-ubend_offset/2,L_wg_side-L_ht_side,90)
|
||||
# nd.strt(length=w_metal,width=w_metal,xs=xs_heater).put(-ubend_offset/2,L_wg_side-L_ht_side,90)
|
||||
# nd.strt(length=w_metal,width=w_metal,xs=xs_metal).put( ubend_offset/2,L_wg_side-L_ht_side,90)
|
||||
# nd.strt(length=w_metal,width=w_metal,xs=xs_heater).put( ubend_offset/2,L_wg_side-L_ht_side,90)
|
||||
|
||||
|
||||
# print(xs_via,sz_via_h2m,sp_via_h2m)
|
||||
VIAL = vias.cell.put(ubend_offset/2,L_wg_side-L_ht_side+w_metal/2,-90)
|
||||
VIAR = vias.cell.put(-ubend_offset/2,L_wg_side-L_ht_side+w_metal/2,-90,flip=1)
|
||||
|
||||
nd.Pin(name='ep1',width=w_metal,pin=VIAL.pin['b0']).put()
|
||||
nd.Pin(name='en1',width=w_metal,pin=VIAR.pin['b0']).put()
|
||||
|
||||
""" Placing Isolation trench with the parameter pack <isl> """
|
||||
if (isl!=None):
|
||||
## placing outer
|
||||
L_side = L_ht_side + R_bend + w_heater/2 + isl.sp_isl_xs*2 - w_metal
|
||||
ISL(xs=isl.xs,width=isl.w_idth,length=L_side).cell.put(-ubend_offset/2-w_metal/2-isl.sp_isl_xs,L_wg_side-L_ht_side+w_metal+isl.sp_isl_xs,90)
|
||||
ISL(xs=isl.xs,width=isl.w_idth,length=L_side).cell.put( ubend_offset/2+w_metal/2+isl.sp_isl_xs,L_wg_side-L_ht_side+w_metal+isl.sp_isl_xs,90)
|
||||
|
||||
L_upper = isl.w_idth+2*(ubend_offset/2+w_metal/2+isl.sp_isl_xs)
|
||||
Y_upper = L_wg_side-L_ht_side+w_metal+isl.sp_isl_xs+L_side-isl.w_idth/2
|
||||
|
||||
ISL(xs=isl.xs,width=isl.w_idth,length=L_upper).cell.put( -L_upper/2,Y_upper,0)
|
||||
|
||||
if ((ubend_offset/2-w_metal/2-isl.sp_isl_xs)*2-isl.w_idth>5):
|
||||
L_side = L_ht_side
|
||||
|
||||
ISL(xs=isl.xs,width=isl.w_idth,length=L_side).cell.put(-ubend_offset/2+w_metal/2+(isl.sp_isl_xs),L_wg_side-L_ht_side,90)
|
||||
ISL(xs=isl.xs,width=isl.w_idth,length=L_side).cell.put( ubend_offset/2-w_metal/2-(isl.sp_isl_xs),L_wg_side-L_ht_side,90)
|
||||
|
||||
|
||||
if (show_pins):
|
||||
nd.put_stub(pinsize=2)
|
||||
self.cell = C
|
||||
self.L = L_heater+w_metal*2
|
||||
|
||||
""" NEW CLASS:: 2023.03.21, two stage phase shifters, to replace PS_3wg """
|
||||
class PS_2st:
|
||||
def __init__(self,
|
||||
xs_wg: str = 'strip',
|
||||
w_wg: float = 0.5,
|
||||
w1: float = 0.7,
|
||||
w2: float = 0.9,
|
||||
L1: int = 10,
|
||||
L2: int = 55,
|
||||
L_wg: int = 0,
|
||||
L_tp: int = 1,
|
||||
L12: Any = None,
|
||||
|
||||
L_ht: Any = None,
|
||||
xs_heater: str='heater',
|
||||
xs_metal: str='metal',
|
||||
|
||||
w_heater: float=2.5,
|
||||
w_metal: float = 8,
|
||||
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
|
||||
UPPER_ISL: bool = True,
|
||||
LOWER_ISL: bool = True,
|
||||
R_bend: int=10,
|
||||
show_pins: bool=False) -> None:
|
||||
|
||||
self.xs_wg = xs_wg
|
||||
self.w_wg = w_wg
|
||||
self.w1 = w1
|
||||
self.w2 = w2
|
||||
self.L1 = L1
|
||||
self.L2 = L2
|
||||
self.L_wg = L_wg
|
||||
self.L_tp = L_tp
|
||||
self.L_ht = L_ht
|
||||
self.xs_heater = xs_heater
|
||||
self.xs_metal = xs_metal
|
||||
self.w_heater = w_heater
|
||||
self.w_metal = w_metal
|
||||
self.via_h2m = via_h2m
|
||||
self.isl = isl
|
||||
self.R_bend = R_bend
|
||||
self.show_pins = show_pins
|
||||
self.R_bend = R_bend
|
||||
|
||||
if (L12==None):
|
||||
L12 = L_tp
|
||||
self.L12 = L12
|
||||
self.cell = self.generate_gds()
|
||||
|
||||
def generate_gds(self):
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
|
||||
""" Generating the basic via_h2m """
|
||||
if (self.via_h2m==None):
|
||||
vias = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks
|
||||
|
||||
else:
|
||||
if (hasattr(self.via_h2m,"cell")):
|
||||
vias = self.via_h2m
|
||||
else :
|
||||
vias = Vias(xs=self.via_h2m.xs,
|
||||
area=self.w_metal,
|
||||
sz=self.via_h2m.sz,
|
||||
spacing=self.via_h2m.spacing,
|
||||
xs_l1=self.xs_heater,
|
||||
xs_l2=self.xs_metal) ## placing vias
|
||||
|
||||
|
||||
pic_strip = Route(radius=self.R_bend,width=self.w_wg,xs=self.xs_wg)
|
||||
|
||||
start = nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put(0,0,90)
|
||||
nd.taper(length=self.L_tp,width1=self.w_wg,width2=self.w1,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L1,width=self.w1,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L12,width1=self.w1,width2=self.w2,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L2,width=self.w2,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L_tp,width1=self.w2,width2=self.w_wg,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put()
|
||||
|
||||
pic_strip.bend_route(angle=180).put(flip=1)
|
||||
|
||||
nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L_tp,width1=self.w_wg,width2=self.w2,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L2,width=self.w2,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L12,width1=self.w2,width2=self.w1,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L1,width=self.w1,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L_tp,width1=self.w1,width2=self.w_wg,xs=self.xs_wg).put()
|
||||
end = nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put()
|
||||
|
||||
L_arm = self.L_wg + self.L_tp + self.L1 + self.L12 + self.L2 + self.L_tp + self.L_wg
|
||||
|
||||
if (self.L_ht==None):
|
||||
self.L_ht = (L_arm + self.R_bend*np.pi/2)*2
|
||||
|
||||
if (self.w_heater>0) :
|
||||
# L_wg_side = (L_wg-L_wg_mid)/2-R_bend
|
||||
|
||||
# VIA = Vias(xs=self.via_h2m.xs,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,sp_via_xs=self.via_h2m.sp_via_xs,
|
||||
# xs_l1=self.xs_heater,xs_l2=self.xs_metal,
|
||||
# area=self.w_metal)
|
||||
|
||||
Ly_ht = (self.L_ht - self.R_bend*np.pi)/2
|
||||
nd.strt(length=Ly_ht,width=self.w_heater,xs=self.xs_heater).put(0,L_arm-Ly_ht,90)
|
||||
nd.bend(radius=self.R_bend,angle=180,xs=self.xs_heater,width=self.w_heater).put(flip=1)
|
||||
nd.strt(length=Ly_ht,width=self.w_heater,xs=self.xs_heater).put()
|
||||
|
||||
VIA_L = vias.cell.put(0,L_arm-Ly_ht+self.w_metal/2,-90,flip=1)
|
||||
VIA_R = vias.cell.put(self.R_bend*2,L_arm-Ly_ht+self.w_metal/2,-90)
|
||||
|
||||
# nd.Pin(name='ep1',pin=VIA_L.pin['b0'].move(0,0,-90)).put()
|
||||
# nd.Pin(name='en1',pin=VIA_R.pin['b0'].move(0,0,90)).put()
|
||||
nd.Pin(name='ep1',pin=VIA_L.pin['b0']).put()
|
||||
nd.Pin(name='en1',pin=VIA_R.pin['b0']).put()
|
||||
|
||||
""" Placing Isolation trench with the parameter pack <isl> """
|
||||
if (self.isl!=None):
|
||||
## placing outer
|
||||
L_side = abs(L_arm+self.R_bend+self.w_heater/2+self.isl.width/2+self.isl.sp_isl_metal - VIA_L.pin['b0'].y - self.w_metal/2-self.isl.sp_isl_metal)
|
||||
ISL(xs=self.isl.xs,width=self.isl.width,length=L_side,spacing=self.isl.spacing,Lmax=self.isl.Lmax).cell.put( -self.isl.sp_isl_metal-self.w_heater/2-self.isl.width/2,
|
||||
VIA_L.pin['b0'].y+self.w_metal/2+self.isl.sp_isl_metal,90)
|
||||
|
||||
ISL(xs=self.isl.xs,width=self.isl.width,length=L_side,spacing=self.isl.spacing,Lmax=self.isl.Lmax).cell.put( end.pin['b0'].x+self.isl.sp_isl_metal+self.w_heater/2+self.isl.width/2,
|
||||
VIA_L.pin['b0'].y+self.w_metal/2+self.isl.sp_isl_metal,90)
|
||||
|
||||
L_top = abs(end.pin['b0'].x)+self.isl.width+(self.isl.sp_isl_metal+self.w_heater/2+self.isl.width/2)*2
|
||||
ISL(xs=self.isl.xs,width=self.isl.width,length=L_top,spacing=self.isl.spacing,Lmax=self.isl.Lmax).cell.put( -self.isl.sp_isl_metal-self.w_heater/2-self.isl.width,
|
||||
VIA_L.pin['b0'].y+self.w_metal/2+self.isl.sp_isl_metal + L_side,0)
|
||||
|
||||
|
||||
nd.Pin(name='a1',pin=start.pin['a0']).put()
|
||||
nd.Pin(name='b1',pin=end.pin['b0']).put()
|
||||
|
||||
return C
|
||||
|
||||
class PS_2st_Straight:
|
||||
def __init__(self,
|
||||
xs_wg: str = 'strip',
|
||||
w_wg: float = 0.5,
|
||||
w1: float = 0.7,
|
||||
w2: float = 0.9,
|
||||
L1: int = 10,
|
||||
L2: int = 55,
|
||||
L_wg: int = 0,
|
||||
L_tp: int = 1,
|
||||
L12: Any = None,
|
||||
|
||||
L_ht: Any = None,
|
||||
xs_heater: str='heater',
|
||||
xs_metal: str='metal',
|
||||
|
||||
w_heater: float=2.5,
|
||||
w_metal: float = 8,
|
||||
|
||||
via_h2m: Any = None,
|
||||
isl: Any = None,
|
||||
|
||||
UPPER_ISL: bool = True,
|
||||
LOWER_ISL: bool = True,
|
||||
show_pins: bool=False) -> None:
|
||||
|
||||
self.xs_wg = xs_wg
|
||||
self.w_wg = w_wg
|
||||
self.w1 = w1
|
||||
self.w2 = w2
|
||||
self.L1 = L1
|
||||
self.L2 = L2
|
||||
self.L_wg = L_wg
|
||||
self.L_tp = L_tp
|
||||
self.L_ht = L_ht
|
||||
self.xs_heater = xs_heater
|
||||
self.xs_metal = xs_metal
|
||||
self.w_heater = w_heater
|
||||
self.w_metal = w_metal
|
||||
self.via_h2m = via_h2m
|
||||
self.isl = isl
|
||||
self.show_pins = show_pins
|
||||
|
||||
if (L12==None):
|
||||
L12 = L_tp
|
||||
self.L12 = L12
|
||||
self.cell = self.generate_gds()
|
||||
|
||||
def generate_gds(self):
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
|
||||
""" Generating the basic via_h2m """
|
||||
# if (self.via_h2m==None):
|
||||
# vias = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal).cell ## only putting metal blocks
|
||||
|
||||
# else:
|
||||
# if (hasattr(self.via_h2m,"cell")):
|
||||
# vias = self.via_h2m
|
||||
# else :
|
||||
# vias = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias
|
||||
|
||||
|
||||
|
||||
start = nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put(0,0,0)
|
||||
nd.taper(length=self.L_tp,width1=self.w_wg,width2=self.w1,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L1,width=self.w1,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L12,width1=self.w1,width2=self.w2,xs=self.xs_wg).put()
|
||||
nd.strt(length=self.L2,width=self.w2,xs=self.xs_wg).put()
|
||||
nd.taper(length=self.L_tp,width1=self.w2,width2=self.w_wg,xs=self.xs_wg).put()
|
||||
end = nd.strt(length=self.L_wg,width=self.w_wg,xs=self.xs_wg).put()
|
||||
|
||||
L_arm = self.L_wg + self.L_tp + self.L1 + self.L12 + self.L2 + self.L_tp + self.L_wg
|
||||
self.L_arm = L_arm
|
||||
if (self.L_ht==None):
|
||||
self.L_ht = L_arm
|
||||
|
||||
if (self.w_heater>0) :
|
||||
# L_wg_side = (L_wg-L_wg_mid)/2-R_bend
|
||||
|
||||
""" Generating the basic via_h2m """
|
||||
if (self.via_h2m==None):
|
||||
vias = Vias(xs=None,area=self.w_metal,sz=0,spacing=0,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## only putting metal blocks
|
||||
|
||||
else:
|
||||
if (hasattr(self.via_h2m,"cell")):
|
||||
vias = self.via_h2m
|
||||
else :
|
||||
vias = Vias(xs=self.via_h2m.xs,area=self.w_metal,sz=self.via_h2m.sz,spacing=self.via_h2m.spacing,xs_l1=self.xs_heater,xs_l2=self.xs_metal) ## placing vias
|
||||
|
||||
|
||||
Ly_ht = (self.L_ht )/2
|
||||
nd.strt(length=self.L_ht,width=self.w_heater,xs=self.xs_heater).put(self.L_arm/2 - self.L_ht/2,0,0)
|
||||
|
||||
VIA_L = vias.cell.put(self.L_arm/2 - self.L_ht/2,0,180)
|
||||
VIA_R = vias.cell.put(self.L_arm/2 + self.L_ht/2,0,0)
|
||||
|
||||
nd.Pin(name='ep1',pin=VIA_L.pin['b0']).put()
|
||||
nd.Pin(name='en1',pin=VIA_R.pin['b0']).put()
|
||||
|
||||
""" Placing Isolation trench with the parameter pack <isl> """
|
||||
|
||||
|
||||
nd.Pin(name='a1',pin=start.pin['a0']).put()
|
||||
nd.Pin(name='b1',pin=end.pin['b0']).put()
|
||||
|
||||
return C
|
||||
|
||||
class PSR_1x2:
|
||||
def __init__(self,PSR: Any,MDM: Any,xs: str='strip',w_wg: float=0.45,L_tp: int=15,show_pins: bool=False) -> None:
|
||||
self.w_wg = w_wg
|
||||
|
||||
PSR_cell = __cell_arg__(arg=PSR,arg_name="PSR",func_name="mxpicp::functional::PSR_1x2")
|
||||
MDM_cell = __cell_arg__(arg=MDM,arg_name="MDM",func_name="mxpicp::functional::PSR_1x2")
|
||||
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
|
||||
|
||||
PSR_inst = PSR_cell.put('a1',0,0,0)
|
||||
|
||||
MDM_inst = MDM_cell.put('b1',PSR_inst.pin['b1'].x+L_tp,PSR_inst.pin['b1'].y,PSR_inst.pin['b1'].a)
|
||||
|
||||
# taper_xs2xs(xs_1=MDM_inst.pin['b1'].xs,xs_2=PSR_inst.pin['b1'].xs,w_1=MDM_inst.pin['b1'].width,w_2=PSR_inst.pin['b1'].width,L_taper=L_tp).cell.put(MDM_inst.pin['b1'])
|
||||
nd.taper(length=L_tp,width1=PSR_inst.pin['b1'].width,width2=MDM_inst.pin['b1'].width,xs=xs).put(PSR_inst.pin['b1'])
|
||||
|
||||
nd.Pin(name='a1',pin=PSR_inst.pin['a1']).put()
|
||||
nd.Pin(name='b1',pin=MDM_inst.pin['a1']).put()
|
||||
nd.Pin(name='b2',pin=MDM_inst.pin['a2']).put()
|
||||
|
||||
if (show_pins):
|
||||
nd.put_stub(pinsize=2)
|
||||
self.cell = C
|
||||
self.L = np.abs(self.cell.pin['a1'].x - np.max([self.cell.pin['b1'].x,self.cell.pin['b2'].x]))
|
||||
|
||||
def generate_test_gds(self,gc,gc_IN=None,gc2gc_dX=140,gc2gc_dY=40):
|
||||
with nd.Cell(name=self.cell.cell_name+"_test", instantiate=False) as C:
|
||||
|
||||
gc_cell = __cell_arg__(arg=gc,arg_name="gc",func_name="mxpicp::functional::PSR_1x2::generate_test_gds")
|
||||
|
||||
if (gc_IN==None):
|
||||
gc_IN = gc
|
||||
else :
|
||||
gc_IN = __cell_arg__(arg=gc,arg_name="gc_IN",func_name="mxpicp::functional::PSR_1x2::generate_test_gds")
|
||||
|
||||
|
||||
GC_I = gc_IN.put('g1',-gc2gc_dX/2,0,180)
|
||||
GC_OU = gc.put('g1', gc2gc_dX/2,-gc2gc_dY/2,0)
|
||||
GC_OD = gc.put('g1', gc2gc_dX/2,gc2gc_dY/2,0)
|
||||
|
||||
PSR_test = self.cell.put(-self.L/2,0,0)
|
||||
stripe=Route(radius=10, width=self.w_wg, xs="strip")
|
||||
|
||||
stripe.taper_p2p(pin1=PSR_test.pin['a1'],pin2=GC_I.pin['g1'],arrow=False).put()
|
||||
stripe.sbend_p2p(pin1=PSR_test.pin['b1'],pin2=GC_OU.pin['g1'],arrow=False).put()
|
||||
stripe.sbend_p2p(pin1=PSR_test.pin['b2'],pin2=GC_OD.pin['g1'],arrow=False).put()
|
||||
|
||||
return C
|
||||
|
||||
class Brag_WDM:
|
||||
def __init__(self,Brag: Any,MDM: Any,w_wg: float=0.45,L_tp: int=30,show_pins: bool=False) -> None:
|
||||
self.w_wg = w_wg
|
||||
|
||||
Brag_cell = __cell_arg__(arg=Brag,arg_name="Brag",func_name="mxpicp::functional::Brag_WDM")
|
||||
MDM_cell = __cell_arg__(arg=MDM,arg_name="MDM",func_name="mxpicp::functional::Brag_WDM")
|
||||
|
||||
|
||||
with nd.Cell(instantiate=False) as C:
|
||||
|
||||
|
||||
Brag_inst = Brag_cell.put('a1',0,0,0)
|
||||
|
||||
MDM_inst = MDM_cell.put('b1',Brag_inst.pin['a1'].x-L_tp,Brag_inst.pin['a1'].y,Brag_inst.pin['a1'].a)
|
||||
|
||||
nd.taper(length=L_tp,width1=Brag_inst.pin['b1'].width,width2=MDM_inst.pin['b1'].width,xs='strip').put(Brag_inst.pin['a1'])
|
||||
|
||||
nd.Pin(name='b1',pin=Brag_inst.pin['b1']).put()
|
||||
nd.Pin(name='a1',pin=MDM_inst.pin['a1']).put()
|
||||
nd.Pin(name='b2',pin=MDM_inst.pin['a2']).put()
|
||||
|
||||
if (show_pins):
|
||||
nd.put_stub(pinsize=2)
|
||||
self.cell = C
|
||||
self.L = np.abs(self.cell.pin['a1'].x - np.max([self.cell.pin['b1'].x,self.cell.pin['b2'].x]))
|
||||
|
||||
def generate_test_gds(self,gc,gc2gc_dX=140,gc2gc_dY=40,dX_offset=50):
|
||||
with nd.Cell(name=self.cell.cell_name+"_test", instantiate=False) as C:
|
||||
|
||||
gc_cell = __cell_arg__(arg=gc,arg_name="gc",func_name="mxpicp::functional::Brag_WDM::generate_test_gds")
|
||||
# if (isinstance(gc,nd.Cell)):
|
||||
# gc_cell = gc
|
||||
# elif (hasattr(gc,"cell")):
|
||||
# gc_cell = gc.cell
|
||||
|
||||
GC_I = gc_cell.put('g1',-gc2gc_dX/2,0,180)
|
||||
GC_O1 = gc_cell.put('g1', gc2gc_dX/2,0,0)
|
||||
GC_O2 = gc_cell.put('g1', gc2gc_dX/2+dX_offset,-gc2gc_dY,0)
|
||||
|
||||
INSTR = self.cell.put('a1',-self.L/2,0,0)
|
||||
stripe=Route(radius=10, width=self.w_wg, xs="strip")
|
||||
|
||||
stripe.taper_p2p(pin1=INSTR.pin['a1'],pin2=GC_I.pin['g1'],arrow=False).put()
|
||||
|
||||
stripe.taper(pin=INSTR.pin['b1'],width1=INSTR.pin['b1'].width,width2=GC_O1.pin['g1'].width,length=10,arrow=False).put()
|
||||
stripe.sbend_p2p(pin2=GC_O1.pin['g1'],arrow=False).put()
|
||||
stripe.ubend_p2p(pin1=INSTR.pin['b2'],pin2=GC_O2.pin['g1'],arrow=False).put()
|
||||
|
||||
return C
|
||||
Reference in New Issue
Block a user