1431 lines
58 KiB
Python
1431 lines
58 KiB
Python
from typing import Any, Optional
|
|
from turtle import ht
|
|
import nazca as nd
|
|
import numpy as np
|
|
import nazca.interconnects as IC
|
|
|
|
from ...geometry 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:
|
|
"""
|
|
STD CROW V primitive component.
|
|
|
|
This component builds the STD CROW V layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
ring : Any
|
|
Ring cell or component used by this composite.
|
|
bus : Any
|
|
Bus waveguide cell or component used by this composite.
|
|
w_bus : float or list
|
|
Width parameter in microns.
|
|
w_ring : float or list
|
|
Width parameter in microns.
|
|
sz_ring : float or list
|
|
Value for the sz_ring parameter.
|
|
sz_bus : float or list
|
|
Value for the sz_bus parameter.
|
|
name : str, optional
|
|
Unique identifier for the device cell. Default is None.
|
|
gap_crows : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
gap_cp : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.45, 0.45].
|
|
w_heater : float or list, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
ISL_LEFT : bool, optional
|
|
Value for the ISL_LEFT parameter. Default is True.
|
|
ISL_RIGHT : bool, optional
|
|
Value for the ISL_RIGHT parameter. Default is True.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
"""
|
|
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:
|
|
|
|
""" """
|
|
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) :
|
|
"""
|
|
CROW Eul Ring primitive component.
|
|
|
|
This component builds the CROW Eul Ring layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
name : str
|
|
Unique identifier for the device cell.
|
|
R0 : int, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R1 : int, optional
|
|
Radius parameter in microns. Default is 3.
|
|
w0 : float, optional
|
|
Width parameter in microns. Default is 0.38.
|
|
w1 : float, optional
|
|
Width parameter in microns. Default is 0.65.
|
|
w_bus : float, optional
|
|
Width parameter in microns. Default is 0.35.
|
|
R_att : int, optional
|
|
Radius parameter in microns. Default is 15.
|
|
R_att_min : int, optional
|
|
Radius parameter in microns. Default is 3.
|
|
A_att : int, optional
|
|
Angle parameter in degrees. Default is 30.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
dLx : float, optional
|
|
Value for the dLx parameter. Default is 0.
|
|
dLy : float, optional
|
|
Value for the dLy parameter. Default is 0.
|
|
xs_wg : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
gap_crows : list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
gap_cp : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_heater : float, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
ISL_LEFT : bool, optional
|
|
Value for the ISL_LEFT parameter. Default is True.
|
|
ISL_RIGHT : bool, optional
|
|
Value for the ISL_RIGHT parameter. Default is True.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
R_cp : Any, optional
|
|
Radius parameter in microns. Default is None.
|
|
bus_order : float, optional
|
|
Value for the bus_order parameter. Default is 1.0.
|
|
width_type : str, optional
|
|
Width parameter in microns. Default is 'crow_customize'.
|
|
A_cp : int, optional
|
|
Angle parameter in degrees. Default is 0.
|
|
"""
|
|
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) :
|
|
"""
|
|
CROW Eul RCK primitive component.
|
|
|
|
This component builds the CROW Eul RCK layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
R0 : int, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R1 : int, optional
|
|
Radius parameter in microns. Default is 3.
|
|
R2 : int, optional
|
|
Radius parameter in microns. Default is 20.
|
|
w0 : float, optional
|
|
Width parameter in microns. Default is 0.38.
|
|
w1 : float, optional
|
|
Width parameter in microns. Default is 0.65.
|
|
w_bus : float, optional
|
|
Width parameter in microns. Default is 0.35.
|
|
R_att : int, optional
|
|
Radius parameter in microns. Default is 15.
|
|
R_att_min : int, optional
|
|
Radius parameter in microns. Default is 3.
|
|
A_att : int, optional
|
|
Angle parameter in degrees. Default is 30.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
dAc : float, optional
|
|
Value for the dAc parameter. Default is 0.
|
|
dLx : float, optional
|
|
Value for the dLx parameter. Default is 0.
|
|
dLy : float, optional
|
|
Value for the dLy parameter. Default is 0.
|
|
xs_wg : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
gap_crows : list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
gap_cp : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_heater : float, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
ISL_LEFT : bool, optional
|
|
Value for the ISL_LEFT parameter. Default is True.
|
|
ISL_RIGHT : bool, optional
|
|
Value for the ISL_RIGHT parameter. Default is True.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
"""
|
|
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):
|
|
"""
|
|
CROW Circular ring primitive component.
|
|
|
|
This component builds the CROW Circular ring layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
r_ring : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
w_ring : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
xs_ring : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
w1_bus : float, optional
|
|
Value for the w1_bus parameter. Default is 0.45.
|
|
A1_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
w2_bus : float, optional
|
|
Value for the w2_bus parameter. Default is 0.45.
|
|
A2_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
gap1 : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
gap2 : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
Euler_trasition : bool, optional
|
|
Value for the Euler_trasition parameter. Default is True.
|
|
R1_cp : Any, optional
|
|
Radius parameter in microns. Default is None.
|
|
R2_cp : Any, optional
|
|
Radius parameter in microns. Default is None.
|
|
R1_att : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R2_att : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R1_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
R2_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
A1_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
A2_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
gap_crows : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
w_heater : float or list, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
ISL_LEFT : bool, optional
|
|
Value for the ISL_LEFT parameter. Default is True.
|
|
ISL_RIGHT : bool, optional
|
|
Value for the ISL_RIGHT parameter. Default is True.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
"""
|
|
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):
|
|
"""
|
|
CROW STD Allpass primitive component.
|
|
|
|
This component builds the CROW STD Allpass layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
r_ring : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
w_ring : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
xs_ring : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
w_bus : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
A_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
gap_bus : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
Euler_trasition : bool, optional
|
|
Value for the Euler_trasition parameter. Default is True.
|
|
R_att : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
A_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
gap_crows : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
w_heater : float or list, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
"""
|
|
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):
|
|
"""
|
|
CROW STD Adddrop primitive component.
|
|
|
|
This component builds the CROW STD Adddrop layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
r_ring : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
w_ring : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
xs_ring : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
w_bus : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
A_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
gap_bus : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
Euler_trasition : bool, optional
|
|
Value for the Euler_trasition parameter. Default is True.
|
|
R_att : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
R_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
A_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
gap_crows : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
w_heater : float or list, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
"""
|
|
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):
|
|
"""
|
|
CROW AED primitive component.
|
|
|
|
This component builds the CROW AED layout cell.
|
|
|
|
Parameters
|
|
----------
|
|
r_outer : float, optional
|
|
Radius parameter in microns. Default is 10.
|
|
wa : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
wb : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
xs_ring : str, optional
|
|
Layer or cross-section name used by the device. Default is 'strip'.
|
|
w1_bus : float, optional
|
|
Value for the w1_bus parameter. Default is 0.45.
|
|
A1_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
w2_bus : float, optional
|
|
Value for the w2_bus parameter. Default is 0.45.
|
|
A2_cp : int, optional
|
|
Angle parameter in degrees. Default is 10.
|
|
gap1 : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
gap2 : float, optional
|
|
Spacing or gap parameter in microns. Default is 0.45.
|
|
w_wg : float, optional
|
|
Width parameter in microns. Default is 0.45.
|
|
Euler_trasition : bool, optional
|
|
Value for the Euler_trasition parameter. Default is True.
|
|
R1_cp : float, optional
|
|
Radius parameter in microns. Default is None.
|
|
R2_cp : float, optional
|
|
Radius parameter in microns. Default is None.
|
|
R1_att : float, optional
|
|
Radius parameter in microns. Default is 15.
|
|
R2_att : float, optional
|
|
Radius parameter in microns. Default is 15.
|
|
R1_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
R2_att_min : float, optional
|
|
Radius parameter in microns. Default is 5.
|
|
L_tilt : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
A1_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
A2_att : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
Ltp_bus : int, optional
|
|
Length parameter in microns. Default is 0.
|
|
dL_p2p : Optional[float], optional
|
|
Value for the dL_p2p parameter. Default is None.
|
|
gap_crows : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.4].
|
|
gap_cp : float or list, optional
|
|
Spacing or gap parameter in microns. Default is [0.45, 0.45].
|
|
w_heater : float or list, optional
|
|
Width parameter in microns. Default is 0.
|
|
xs_heater : str, optional
|
|
Layer or cross-section name used by the device. Default is 'heater'.
|
|
connected : bool, optional
|
|
Value for the connected parameter. Default is True.
|
|
w_metal : float, optional
|
|
Width parameter in microns. Default is 8.
|
|
xs_metal : str, optional
|
|
Layer or cross-section name used by the device. Default is 'metal'.
|
|
via_h2m : Any, optional
|
|
Via definition used between heater and metal layers. Default is None.
|
|
isl : Any, optional
|
|
Isolation-trench definition used by the electrical layout. Default is None.
|
|
ISL_LEFT : bool, optional
|
|
Value for the ISL_LEFT parameter. Default is True.
|
|
ISL_RIGHT : bool, optional
|
|
Value for the ISL_RIGHT parameter. Default is True.
|
|
show_pins : bool, optional
|
|
Whether to draw pin markers in the generated layout. Default is False.
|
|
sharp_patch : bool, optional
|
|
Whether to add geometry patches for sharp corners or cladding continuity. Default is True.
|
|
ht_shift : int, optional
|
|
Value for the ht_shift parameter. Default is 0.
|
|
A_ht : int, optional
|
|
Angle parameter in degrees. Default is 45.
|
|
"""
|
|
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)
|
|
|
|
|
|
|