optical pins name revised. Pin type added

This commit is contained in:
=
2026-06-07 22:56:33 +08:00
parent a4ac88f002
commit 8462c3397f
262 changed files with 3251 additions and 1134 deletions
+12 -4
View File
@@ -235,8 +235,12 @@ class STD_CROW_V:
# 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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=BUS_d.pin['a1']).put()
nd.Pin(name='opt_a1',pin=BUS_d.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=BUS_d.pin['b1']).put()
nd.Pin(name='opt_b1',pin=BUS_d.pin['opt_b1'],type="optical:").put()
dy = 0
for _idx_ in range(0,len(self.gap_crows)):
@@ -253,8 +257,12 @@ class STD_CROW_V:
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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=BUS_u.pin['a1']).put()
nd.Pin(name='opt_a2',pin=BUS_u.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=BUS_u.pin['b1']).put()
nd.Pin(name='opt_b2',pin=BUS_u.pin['opt_b1'],type="optical:").put()
except Exception as ex:
print("ERROR :: ",ex)
+177 -61
View File
@@ -7,9 +7,9 @@ from ...basic import __xs_exist__
from ...geometry import *
import nazca.interconnects as IC
class Route(IC.Interconnect):
pass
# from ...routing import *
# class Route(IC.Interconnect):
# pass
from ...routing import Route
from .unit import *
@@ -182,8 +182,12 @@ class SOCR():
wg.taper(width1=self.w_cp, width2=self.w_wg, length=4.5, arrow=False).put()
wg_in = wg.strt(width=self.w_wg,length=0.5,arrow=False).put()
## Add pins
nd.Pin(name="a1", width=self.w_wg).put(wg_in.pin['b0'])
nd.Pin(name="b1", width=self.w_wg).put(wg_out.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1", width=self.w_wg).put(wg_in.pin['b0'])
nd.Pin(name="opt_a1", width=self.w_wg,type="optical:").put(wg_in.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1", width=self.w_wg).put(wg_out.pin['b0'])
nd.Pin(name="opt_b1", width=self.w_wg,type="optical:").put(wg_out.pin['b0'])
## Add patch
if self.sharp_patch and (layer_cld_name != "dump"):
# if hasattr(self.tapeout, "LAYER_STRIP_CLD"):
@@ -258,8 +262,12 @@ class SOCR():
pic = self.cell_pic.put(0, 0)
eic = self.cell_eic.put(0, 0)
## Add pins
nd.Pin(name="a1", width=self.w_wg).put(pic.pin['a1'])
nd.Pin(name="b1", width=self.w_wg).put(pic.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1", width=self.w_wg).put(pic.pin['a1'])
nd.Pin(name="opt_a1", width=self.w_wg,type="optical:").put(pic.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1", width=self.w_wg).put(pic.pin['b1'])
nd.Pin(name="opt_b1", width=self.w_wg,type="optical:").put(pic.pin['opt_b1'])
nd.Pin(name="ep1", width=eic.pin['ep1'].width).put(eic.pin['ep1'])
nd.Pin(name="en1", width=eic.pin['en1'].width).put(eic.pin['en1'])
if self.show_pins:
@@ -268,13 +276,21 @@ class SOCR():
def generate_2pi_gds(self, gap=10):
with nd.Cell(name=self.cell.cell_name+"_2pi", instantiate=False) as C:
socr_1 = self.cell.put('a1',0,0,0)
socr_2 = self.cell.put('a1', socr_1.pin['b1'].move(gap,0,0))
## revised in 2026.06.07 by Qin Yue
# legacy: socr_1 = self.cell.put('a1',0,0,0)
socr_1 = self.cell.put('opt_a1',0,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: socr_2 = self.cell.put('a1', socr_1.pin['b1'].move(gap,0,0))
socr_2 = self.cell.put('opt_a1', socr_1.pin['opt_b1'].move(gap,0,0))
stripe = Route(xs='strip', width=self.w_wg, radius=5)
metal1 = Route(xs='metal', width=6, radius=0)
stripe.strt_p2p(
pin1=socr_1.pin['b1'].move(-0.1,0,0),
pin2=socr_2.pin['a1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=socr_1.pin['b1'].move(-0.1,0,0),
pin1=socr_1.pin['opt_b1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_2.pin['a1'].move(-0.1,0,0),
pin2=socr_2.pin['opt_a1'].move(-0.1,0,0),
arrow=False
).put()
metal1.strt_p2p(
@@ -282,8 +298,12 @@ class SOCR():
pin2=socr_2.pin['ep1'],
arrow=False
).put()
nd.Pin(name='a1', width=self.w_wg).put(socr_1.pin['a1'])
nd.Pin(name='b1', width=self.w_wg).put(socr_2.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1', width=self.w_wg).put(socr_1.pin['a1'])
nd.Pin(name='opt_a1', width=self.w_wg,type="optical:").put(socr_1.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1', width=self.w_wg).put(socr_2.pin['b1'])
nd.Pin(name='opt_b1', width=self.w_wg,type="optical:").put(socr_2.pin['opt_b1'])
nd.Pin(name='ep1',pin=socr_1.pin['ep1'].move(0,0,-90)).put()
nd.Pin(name='en1',pin=socr_2.pin['en1'].move(0,0, 90)).put()
return C
@@ -292,68 +312,116 @@ class SOCR():
with nd.Cell(name=self.cell.cell_name+"_test_mzi", instantiate=False) as C:
gc_input = gc.cell.put('g1', 0, 0, 180)
gc_output_mid = gc.cell.put('g1', gc2gc_length+mid_offset, 0, 0)
mmi_input = mmi.cell.put('a1', 20, 0, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: mmi_input = mmi.cell.put('a1', 20, 0, 0)
mmi_input = mmi.cell.put('opt_a1', 20, 0, 0)
stripe = Route(xs='strip', width=gc.w_wg, radius=5)
# Connect input gc with first mmi
stripe.strt_p2p(pin1=gc_input.pin['g1'], pin2=mmi_input.pin['a1'], arrow=False).put()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.strt_p2p(pin1=gc_input.pin['g1'], pin2=mmi_input.pin['a1'], arrow=False).put()
stripe.strt_p2p(pin1=gc_input.pin['g1'], pin2=mmi_input.pin['opt_a1'], arrow=False).put()
# Connect the upper arm
self.length = self.cell.pin['b1'].x - self.cell.pin['a1'].x
## revised in 2026.06.07 by Qin Yue
# legacy: self.length = self.cell.pin['b1'].x - self.cell.pin['a1'].x
self.length = self.cell.pin['opt_b1'].x - self.cell.pin['opt_a1'].x
socr_cell = []
for _index_ in range(num_socr):
cell = self.cell.put('a1', mmi_input.pin['b1'].x+30+(self.length+5)*_index_, 40, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: cell = self.cell.put('a1', mmi_input.pin['b1'].x+30+(self.length+5)*_index_, 40, 0)
cell = self.cell.put('opt_a1', mmi_input.pin['opt_b1'].x+30+(self.length+5)*_index_, 40, 0)
socr_cell.append(cell)
# socr_cell = pd.concat(socr_cell,cell)
if _index_>=1:
stripe.strt_p2p(
pin1=socr_cell[_index_-1].pin['b1'].move(-0.1,0,0),
pin2=socr_cell[_index_].pin['a1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=socr_cell[_index_-1].pin['b1'].move(-0.1,0,0),
pin1=socr_cell[_index_-1].pin['opt_b1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[_index_].pin['a1'].move(-0.1,0,0),
pin2=socr_cell[_index_].pin['opt_a1'].move(-0.1,0,0),
arrow=False
).put()
nd.Pin(name="ep"+str(_index_+1),pin=cell.pin['ep1']).put()
nd.Pin(name="en"+str(_index_+1),pin=cell.pin['en1']).put()
stripe.sbend_p2p(
pin1=mmi_input.pin['b1'],
pin2=socr_cell[0].pin['a1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_input.pin['b1'],
pin1=mmi_input.pin['opt_b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[0].pin['a1'].move(-0.1,0,0),
pin2=socr_cell[0].pin['opt_a1'].move(-0.1,0,0),
Lstart=1,
arrow=False).put()
mmi_output_up = mmi.cell.put('a1', socr_cell[-1].pin['b1'].x+30, socr_cell[-1].pin['b1'].y, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: mmi_output_up = mmi.cell.put('a1', socr_cell[-1].pin['b1'].x+30, socr_cell[-1].pin['b1'].y, 0)
mmi_output_up = mmi.cell.put('opt_a1', socr_cell[-1].pin['opt_b1'].x+30, socr_cell[-1].pin['opt_b1'].y, 0)
stripe.strt_p2p(
pin1=mmi_output_up.pin['a1'],
pin2=socr_cell[-1].pin['b1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_up.pin['a1'],
pin1=mmi_output_up.pin['opt_a1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[-1].pin['b1'].move(-0.1,0,0),
pin2=socr_cell[-1].pin['opt_b1'].move(-0.1,0,0),
arrow=False).put()
gc_output_up = gc.cell.put('g1', gc2gc_length, mmi_output_up.pin['b1'].y, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: gc_output_up = gc.cell.put('g1', gc2gc_length, mmi_output_up.pin['b1'].y, 0)
gc_output_up = gc.cell.put('g1', gc2gc_length, mmi_output_up.pin['opt_b1'].y, 0)
stripe.strt_p2p(
pin1=mmi_output_up.pin['b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_up.pin['b1'],
pin1=mmi_output_up.pin['opt_b1'],
pin2=gc_output_up.pin['g1'],
arrow=False).put()
# Connect the below arm
mmi_output_below = mmi.cell.put('a1', socr_cell[-1].pin['b1'].x+30, -socr_cell[-1].pin['b1'].y, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: mmi_output_below = mmi.cell.put('a1', socr_cell[-1].pin['b1'].x+30, -socr_cell[-1].pin['b1'].y, 0)
mmi_output_below = mmi.cell.put('opt_a1', socr_cell[-1].pin['opt_b1'].x+30, -socr_cell[-1].pin['opt_b1'].y, 0)
stripe.sbend_p2p(
pin1=mmi_input.pin['b2'],
pin2=mmi_output_below.pin['a1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_input.pin['b2'],
pin1=mmi_input.pin['opt_b2'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=mmi_output_below.pin['a1'],
pin2=mmi_output_below.pin['opt_a1'],
Lstart=1,
arrow=False).put()
gc_output_below = gc.cell.put('g1', gc2gc_length, mmi_output_below.pin['b2'].y, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: gc_output_below = gc.cell.put('g1', gc2gc_length, mmi_output_below.pin['b2'].y, 0)
gc_output_below = gc.cell.put('g1', gc2gc_length, mmi_output_below.pin['opt_b2'].y, 0)
stripe.strt_p2p(
pin1=mmi_output_below.pin['b2'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_below.pin['b2'],
pin1=mmi_output_below.pin['opt_b2'],
pin2=gc_output_below.pin['g1'],
arrow=False).put()
# Combine upper and below arm together to do the coherence detection
mmi_output_mid = mmi.cell.put('a1', mmi_output_below.pin['b1'].x+mmi.length+20, gc_output_mid.pin['g1'].y, 180)
## revised in 2026.06.07 by Qin Yue
# legacy: mmi_output_mid = mmi.cell.put('a1', mmi_output_below.pin['b1'].x+mmi.length+20, gc_output_mid.pin['g1'].y, 180)
mmi_output_mid = mmi.cell.put('opt_a1', mmi_output_below.pin['opt_b1'].x+mmi.length+20, gc_output_mid.pin['g1'].y, 180)
stripe.strt_p2p(
pin1=mmi_output_mid.pin['a1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_mid.pin['a1'],
pin1=mmi_output_mid.pin['opt_a1'],
pin2=gc_output_mid.pin['g1'],
arrow=False).put()
stripe.sbend_p2p(
pin1=mmi_output_up.pin['b2'],
pin2=mmi_output_mid.pin['b2'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_up.pin['b2'],
pin1=mmi_output_up.pin['opt_b2'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=mmi_output_mid.pin['b2'],
pin2=mmi_output_mid.pin['opt_b2'],
Lstart=1,
arrow=False).put()
stripe.sbend_p2p(
pin1=mmi_output_below.pin['b1'],
pin2=mmi_output_mid.pin['b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=mmi_output_below.pin['b1'],
pin1=mmi_output_below.pin['opt_b1'],
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=mmi_output_mid.pin['b1'],
pin2=mmi_output_mid.pin['opt_b1'],
Lstart=1,
arrow=False).put()
if show_pins : nd.put_stub()
@@ -367,27 +435,39 @@ class SOCR():
gc_output = gc.cell.put('g1',gc2gc_length, 0, 0)
stripe = Route(xs='strip', width=gc.w_wg, radius=5)
# Add test structure
self.length = self.cell.pin['b1'].x - self.cell.pin['a1'].x
## revised in 2026.06.07 by Qin Yue
# legacy: self.length = self.cell.pin['b1'].x - self.cell.pin['a1'].x
self.length = self.cell.pin['opt_b1'].x - self.cell.pin['opt_a1'].x
socr_cell = []
for _index_ in range(num_socr):
cell = self.cell.put('a1', gc_input.pin['g1'].x+10+(self.length+5)*_index_, 0, 0)
## revised in 2026.06.07 by Qin Yue
# legacy: cell = self.cell.put('a1', gc_input.pin['g1'].x+10+(self.length+5)*_index_, 0, 0)
cell = self.cell.put('opt_a1', gc_input.pin['g1'].x+10+(self.length+5)*_index_, 0, 0)
socr_cell.append(cell)
# socr_cell = pd.concat(socr_cell,[cell])
if _index_>=1:
stripe.strt_p2p(
pin1=socr_cell[_index_-1].pin['b1'].move(-0.1,0,0),
pin2=socr_cell[_index_].pin['a1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin1=socr_cell[_index_-1].pin['b1'].move(-0.1,0,0),
pin1=socr_cell[_index_-1].pin['opt_b1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[_index_].pin['a1'].move(-0.1,0,0),
pin2=socr_cell[_index_].pin['opt_a1'].move(-0.1,0,0),
arrow=False).put()
if num_socr>=1:
stripe.strt_p2p(
pin1=gc_input.pin['g1'],
pin2=socr_cell[0].pin['a1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[0].pin['a1'].move(-0.1,0,0),
pin2=socr_cell[0].pin['opt_a1'].move(-0.1,0,0),
arrow=False).put()
stripe.strt_p2p(
pin1=gc_output.pin['g1'],
pin2=socr_cell[-1].pin['b1'].move(-0.1,0,0),
## revised in 2026.06.07 by Qin Yue
# legacy: pin2=socr_cell[-1].pin['b1'].move(-0.1,0,0),
pin2=socr_cell[-1].pin['opt_b1'].move(-0.1,0,0),
arrow=False).put()
else:
stripe.strt_p2p(
@@ -610,8 +690,12 @@ class SOCR_Adiabatic(SOCR):
nd.Polygon(points=rect_poly, layer=layer_cld_name).put(0,0)
nd.Polygon(points=rect_poly, layer=layer_cld_name).put(0,0,flip=True)
## Add pins
nd.Pin(name="a1", width=self.w_wg).put(wg_in.pin['b0'])
nd.Pin(name="b1", width=self.w_wg).put(wg_out.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="a1", width=self.w_wg).put(wg_in.pin['b0'])
nd.Pin(name="opt_a1", width=self.w_wg,type="optical:").put(wg_in.pin['b0'])
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name="b1", width=self.w_wg).put(wg_out.pin['b0'])
nd.Pin(name="opt_b1", width=self.w_wg,type="optical:").put(wg_out.pin['b0'])
if self.show_pins:
nd.put_stub()
self.cell = C
@@ -994,12 +1078,18 @@ class MRR_AED(AED_ring):
if (self.isl!=None):
if (self.w2_bus>0):
L_isl = np.abs(self.cell_pic.pin['a1'].y - self.cell_pic.pin['a2'].y) - self.isl.sp_isl_wg*2 - self.w_wg
## revised in 2026.06.07 by Qin Yue
# legacy: L_isl = np.abs(self.cell_pic.pin['a1'].y - self.cell_pic.pin['a2'].y) - self.isl.sp_isl_wg*2 - self.w_wg
L_isl = np.abs(self.cell_pic.pin['opt_a1'].y - self.cell_pic.pin['opt_a2'].y) - self.isl.sp_isl_wg*2 - self.w_wg
else:
L_isl = np.abs(self.ORy - self.cell_pic.pin['a1'].y) - self.isl.sp_isl_wg - self.w_wg/2
## revised in 2026.06.07 by Qin Yue
# legacy: L_isl = np.abs(self.ORy - self.cell_pic.pin['a1'].y) - self.isl.sp_isl_wg - self.w_wg/2
L_isl = np.abs(self.ORy - self.cell_pic.pin['opt_a1'].y) - self.isl.sp_isl_wg - self.w_wg/2
y_isl = self.cell_pic.pin['a1'].y + self.isl.sp_isl_wg + self.w_wg/2
## revised in 2026.06.07 by Qin Yue
# legacy: y_isl = self.cell_pic.pin['a1'].y + self.isl.sp_isl_wg + self.w_wg/2
y_isl = self.cell_pic.pin['opt_a1'].y + self.isl.sp_isl_wg + self.w_wg/2
if (L_isl>self.isl.width):
x_isl = self.ORx+self.isl.sp_isl_metal+self.isl.width/2
@@ -2174,13 +2264,25 @@ class STD_ring_AMZI_adddrop:
pic_strip = Route(radius=self.R_bend,width=self.w_wg,xs=self.xs_wg)
nd.Pin(name='a2',pin=cp_D.pin['a1']).put()
nd.Pin(name='a1',pin=cp_L.pin['b1']).put()
nd.Pin(name='b2',pin=cp_R.pin['a1']).put()
nd.Pin(name='b1',pin=cp_U.pin['b1']).put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a2',pin=cp_D.pin['a1']).put()
nd.Pin(name='opt_a2',pin=cp_D.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=cp_L.pin['b1']).put()
nd.Pin(name='opt_a1',pin=cp_L.pin['opt_b1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=cp_R.pin['a1']).put()
nd.Pin(name='opt_b2',pin=cp_R.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=cp_U.pin['b1']).put()
nd.Pin(name='opt_b1',pin=cp_U.pin['opt_b1'],type="optical:").put()
x_BOX = abs(cp_D.pin['a1'].x - cp_R.pin['a1'].x)*np.sqrt(2)
y_BOX = abs(cp_D.pin['a1'].y - cp_R.pin['a1'].y)*np.sqrt(2)
## revised in 2026.06.07 by Qin Yue
# legacy: x_BOX = abs(cp_D.pin['a1'].x - cp_R.pin['a1'].x)*np.sqrt(2)
x_BOX = abs(cp_D.pin['opt_a1'].x - cp_R.pin['opt_a1'].x)*np.sqrt(2)
## revised in 2026.06.07 by Qin Yue
# legacy: y_BOX = abs(cp_D.pin['a1'].y - cp_R.pin['a1'].y)*np.sqrt(2)
y_BOX = abs(cp_D.pin['opt_a1'].y - cp_R.pin['opt_a1'].y)*np.sqrt(2)
if (sharp_patch):
nd.strt(layer="STRIP_CLD",length=x_BOX/2,width=y_BOX).put(0,0,45)
@@ -2202,11 +2304,19 @@ class STD_ring_AMZI_adddrop:
# via = Vias(xs=self.xs_via_h2m,xs_l1=self.xs_metal,xs_l2=self.xs_heater,sz=self.sz_via_h2m,spacing=self.sp_via_h2m,area=self.w_metal).cell
V1_UR = via.put(HT_UR.pin['a1'].x,HT_UR.pin['a1'].y,45)
V2_UR = via.put(HT_UR.pin['b1'].x,HT_UR.pin['b1'].y,45)
## revised in 2026.06.07 by Qin Yue
# legacy: V1_UR = via.put(HT_UR.pin['a1'].x,HT_UR.pin['a1'].y,45)
V1_UR = via.put(HT_UR.pin['opt_a1'].x,HT_UR.pin['opt_a1'].y,45)
## revised in 2026.06.07 by Qin Yue
# legacy: V2_UR = via.put(HT_UR.pin['b1'].x,HT_UR.pin['b1'].y,45)
V2_UR = via.put(HT_UR.pin['opt_b1'].x,HT_UR.pin['opt_b1'].y,45)
V1_DL = via.put(HT_DL.pin['a1'].x,HT_DL.pin['a1'].y,45)
V2_DL = via.put(HT_DL.pin['b1'].x,HT_DL.pin['b1'].y,45)
## revised in 2026.06.07 by Qin Yue
# legacy: V1_DL = via.put(HT_DL.pin['a1'].x,HT_DL.pin['a1'].y,45)
V1_DL = via.put(HT_DL.pin['opt_a1'].x,HT_DL.pin['opt_a1'].y,45)
## revised in 2026.06.07 by Qin Yue
# legacy: V2_DL = via.put(HT_DL.pin['b1'].x,HT_DL.pin['b1'].y,45)
V2_DL = via.put(HT_DL.pin['opt_b1'].x,HT_DL.pin['opt_b1'].y,45)
eic_m = Route(radius=self.w_metal/2,width=self.w_metal,xs=self.xs_metal,PCB=True)
@@ -2216,7 +2326,9 @@ class STD_ring_AMZI_adddrop:
nd.Pin(name='ep1',pin=V1_DL.pin['a0']).put()
""" Generating the heaters for MZI part """
uoffst = np.sqrt(abs(cp_U.pin['a1'].x - cp_L.pin['a1'].x)**2 + abs(cp_U.pin['a1'].y - cp_L.pin['a1'].y)**2)
## revised in 2026.06.07 by Qin Yue
# legacy: uoffst = np.sqrt(abs(cp_U.pin['a1'].x - cp_L.pin['a1'].x)**2 + abs(cp_U.pin['a1'].y - cp_L.pin['a1'].y)**2)
uoffst = np.sqrt(abs(cp_U.pin['opt_a1'].x - cp_L.pin['opt_a1'].x)**2 + abs(cp_U.pin['opt_a1'].y - cp_L.pin['opt_a1'].y)**2)
HT = waveguide(w_heater=self.w_heater,xs_heater=self.xs_heater,
via_h2m=self.via_h2m,
isl = self.isl,
@@ -2228,8 +2340,12 @@ class STD_ring_AMZI_adddrop:
L_wg=self.dL_arm+uoffst+(np.pi-2)*self.R_bend,
L_heater=uoffst+(np.pi-2)*self.R_bend+self.dL_arm/2)
HT_U = HT.cell.put('a1',cp_L.pin['a1'])
HT_D = HT.cell.put('a1',cp_R.pin['b1'])
## revised in 2026.06.07 by Qin Yue
# legacy: HT_U = HT.cell.put('a1',cp_L.pin['a1'])
HT_U = HT.cell.put('opt_a1',cp_L.pin['opt_a1'])
## revised in 2026.06.07 by Qin Yue
# legacy: HT_D = HT.cell.put('a1',cp_R.pin['b1'])
HT_D = HT.cell.put('opt_a1',cp_R.pin['opt_b1'])
nd.Pin(name='ep2',pin=HT_U.pin['ep1'].move(0,0,90)).put()
nd.Pin(name='en2',pin=HT_U.pin['en1'].move(0,0,-90)).put()
+93 -31
View File
@@ -125,8 +125,12 @@ class waveguide:
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)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',width=w_wg).put(-L_wg/2,0,180)
nd.Pin(name='opt_a1',width=w_wg,type="optical:").put(-L_wg/2,0,180)
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',width=w_wg).put( L_wg/2,0,0)
nd.Pin(name='opt_b1',width=w_wg,type="optical:").put( L_wg/2,0,0)
L_heater = np.min([L_wg,L_heater])
### placing heaters
@@ -170,8 +174,12 @@ class waveguide:
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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',width=w_wg,pin=wg_in.pin['a0']).put()
nd.Pin(name='opt_a1',width=w_wg,pin=wg_in.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',width=w_wg,pin=wg_out.pin['b0']).put()
nd.Pin(name='opt_b1',width=w_wg,pin=wg_out.pin['b0'],type="optical:").put()
else:
R_ht = R_bend
L_wg_mid = ubend_offset-R_bend*2
@@ -181,8 +189,12 @@ class waveguide:
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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',width=w_wg,pin=wg_in.pin['a0']).put()
nd.Pin(name='opt_a1',width=w_wg,pin=wg_in.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',width=w_wg,pin=wg_out.pin['b0']).put()
nd.Pin(name='opt_b1',width=w_wg,pin=wg_out.pin['b0'],type="optical:").put()
L_heater = np.max([L_wg_mid+R_bend+w_metal*2,L_heater])
L_heater = np.min([L_wg,L_heater])
@@ -412,8 +424,12 @@ class PS_2st:
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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=start.pin['a0']).put()
nd.Pin(name='opt_a1',pin=start.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=end.pin['b0']).put()
nd.Pin(name='opt_b1',pin=end.pin['b0'],type="optical:").put()
return C
@@ -565,8 +581,12 @@ class PS_2st_Straight:
""" 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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=start.pin['a0']).put()
nd.Pin(name='opt_a1',pin=start.pin['a0'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=end.pin['b0']).put()
nd.Pin(name='opt_b1',pin=end.pin['b0'],type="optical:").put()
return C
@@ -600,21 +620,35 @@ class PSR_1x2:
with nd.Cell(instantiate=False) as C:
PSR_inst = PSR_cell.put('a1',0,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: PSR_inst = PSR_cell.put('a1',0,0,0)
PSR_inst = PSR_cell.put('opt_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)
## revised in 2026.06.07 by Qin Yue
# legacy: MDM_inst = MDM_cell.put('b1',PSR_inst.pin['b1'].x+L_tp,PSR_inst.pin['b1'].y,PSR_inst.pin['b1'].a)
MDM_inst = MDM_cell.put('opt_b1',PSR_inst.pin['opt_b1'].x+L_tp,PSR_inst.pin['opt_b1'].y,PSR_inst.pin['opt_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'])
## revised in 2026.06.07 by Qin Yue
# legacy: 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.taper(length=L_tp,width1=PSR_inst.pin['opt_b1'].width,width2=MDM_inst.pin['opt_b1'].width,xs=xs).put(PSR_inst.pin['opt_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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=PSR_inst.pin['a1']).put()
nd.Pin(name='opt_a1',pin=PSR_inst.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=MDM_inst.pin['a1']).put()
nd.Pin(name='opt_b1',pin=MDM_inst.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=MDM_inst.pin['a2']).put()
nd.Pin(name='opt_b2',pin=MDM_inst.pin['opt_a2'],type="optical:").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]))
## revised in 2026.06.07 by Qin Yue
# legacy: self.L = np.abs(self.cell.pin['a1'].x - np.max([self.cell.pin['b1'].x,self.cell.pin['b2'].x]))
self.L = np.abs(self.cell.pin['opt_a1'].x - np.max([self.cell.pin['opt_b1'].x,self.cell.pin['opt_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:
@@ -634,9 +668,15 @@ class PSR_1x2:
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()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.taper_p2p(pin1=PSR_test.pin['a1'],pin2=GC_I.pin['g1'],arrow=False).put()
stripe.taper_p2p(pin1=PSR_test.pin['opt_a1'],pin2=GC_I.pin['g1'],arrow=False).put()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.sbend_p2p(pin1=PSR_test.pin['b1'],pin2=GC_OU.pin['g1'],arrow=False).put()
stripe.sbend_p2p(pin1=PSR_test.pin['opt_b1'],pin2=GC_OU.pin['g1'],arrow=False).put()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.sbend_p2p(pin1=PSR_test.pin['b2'],pin2=GC_OD.pin['g1'],arrow=False).put()
stripe.sbend_p2p(pin1=PSR_test.pin['opt_b2'],pin2=GC_OD.pin['g1'],arrow=False).put()
return C
@@ -669,20 +709,34 @@ class Brag_WDM:
with nd.Cell(instantiate=False) as C:
Brag_inst = Brag_cell.put('a1',0,0,0)
## revised in 2026.06.07 by Qin Yue
# legacy: Brag_inst = Brag_cell.put('a1',0,0,0)
Brag_inst = Brag_cell.put('opt_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)
## revised in 2026.06.07 by Qin Yue
# legacy: MDM_inst = MDM_cell.put('b1',Brag_inst.pin['a1'].x-L_tp,Brag_inst.pin['a1'].y,Brag_inst.pin['a1'].a)
MDM_inst = MDM_cell.put('opt_b1',Brag_inst.pin['opt_a1'].x-L_tp,Brag_inst.pin['opt_a1'].y,Brag_inst.pin['opt_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'])
## revised in 2026.06.07 by Qin Yue
# legacy: 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.taper(length=L_tp,width1=Brag_inst.pin['opt_b1'].width,width2=MDM_inst.pin['opt_b1'].width,xs='strip').put(Brag_inst.pin['opt_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()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b1',pin=Brag_inst.pin['b1']).put()
nd.Pin(name='opt_b1',pin=Brag_inst.pin['opt_b1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='a1',pin=MDM_inst.pin['a1']).put()
nd.Pin(name='opt_a1',pin=MDM_inst.pin['opt_a1'],type="optical:").put()
## revised in 2026.06.07 by Qin Yue
# legacy: nd.Pin(name='b2',pin=MDM_inst.pin['a2']).put()
nd.Pin(name='opt_b2',pin=MDM_inst.pin['opt_a2'],type="optical:").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]))
## revised in 2026.06.07 by Qin Yue
# legacy: self.L = np.abs(self.cell.pin['a1'].x - np.max([self.cell.pin['b1'].x,self.cell.pin['b2'].x]))
self.L = np.abs(self.cell.pin['opt_a1'].x - np.max([self.cell.pin['opt_b1'].x,self.cell.pin['opt_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:
@@ -697,13 +751,21 @@ class Brag_WDM:
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)
## revised in 2026.06.07 by Qin Yue
# legacy: INSTR = self.cell.put('a1',-self.L/2,0,0)
INSTR = self.cell.put('opt_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()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.taper_p2p(pin1=INSTR.pin['a1'],pin2=GC_I.pin['g1'],arrow=False).put()
stripe.taper_p2p(pin1=INSTR.pin['opt_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()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.taper(pin=INSTR.pin['b1'],width1=INSTR.pin['b1'].width,width2=GC_O1.pin['g1'].width,length=10,arrow=False).put()
stripe.taper(pin=INSTR.pin['opt_b1'],width1=INSTR.pin['opt_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()
## revised in 2026.06.07 by Qin Yue
# legacy: stripe.ubend_p2p(pin1=INSTR.pin['b2'],pin2=GC_O2.pin['g1'],arrow=False).put()
stripe.ubend_p2p(pin1=INSTR.pin['opt_b2'],pin2=GC_O2.pin['g1'],arrow=False).put()
return C