Cells Si SOI 500nm¶
array¶
An array of components.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component
|
the component of which to create an array |
'pad'
|
|
columns
|
int
|
the number of components to place in the x-direction |
6
|
rows
|
int
|
the number of components to place in the y-direction |
1
|
add_ports
|
bool
|
add ports to the component |
True
|
size
|
Optional x, y size. Overrides columns and rows. |
None
|
|
centered
|
bool
|
center the array around the origin. |
False
|
row_pitch
|
float
|
the pitch between rows. |
150
|
column_pitch
|
float
|
the pitch between columns. |
150
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.array(component='pad', columns=6, rows=1, add_ports=True, centered=False, column_pitch=150, row_pitch=150)
c.draw_ports()
c.plot()
bend_circular¶
A circular bend, as the foundry 90 degree bend (R = 25 um).
SOI500nm_1550nm_TE_RIB_90_Degree_Bend is a circular arc, so this is the
default bend for routing and the MZI. An Euler bend (bend_euler) with
the same effective radius curves more tightly than the 25 um minimum.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
radius
|
float | None
|
the radius of the bend; defaults to the cross-section radius. |
None
|
angle
|
float
|
the angle of the bend (usually 90 degrees). |
90.0
|
width
|
float | None
|
the width of the waveguide forming the bend. |
None
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_circular(angle=90, cross_section='xs_rc500')
c.draw_ports()
c.plot()
bend_circular_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_circular_rc(angle=90, cross_section='xs_rc500')
c.draw_ports()
c.plot()
bend_circular_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_circular_ro(angle=90, cross_section='xs_ro500')
c.draw_ports()
c.plot()
bend_euler¶
An euler bend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
radius
|
float | None
|
the effective radius of the bend. |
None
|
angle
|
float
|
the angle of the bend (usually 90 degrees). |
90.0
|
p
|
float
|
the fraction of the bend that's represented by a polar bend. |
0.5
|
width
|
float | None
|
the width of the waveguide forming the bend. |
None
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_euler(angle=90, p=0.5, cross_section='xs_rc500')
c.draw_ports()
c.plot()
bend_euler_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_euler_rc(angle=90, p=0.5, cross_section='xs_rc500')
c.draw_ports()
c.plot()
bend_euler_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_euler_ro(angle=90, p=0.5, cross_section='xs_ro500')
c.draw_ports()
c.plot()
bend_s¶
An S-bend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
tuple[float, float]
|
the width and height of the s-bend. |
(20.0, 1.8)
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
allow_min_radius_violation
|
bool
|
if True, allows the s-bend to have a smaller radius than the minimum radius. |
True
|
width
|
float | None
|
waveguide width; defaults to the cross-section width. |
None
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.bend_s(size=(20, 1.8), cross_section='xs_rc500', allow_min_radius_violation=True)
c.draw_ports()
c.plot()
compass¶
Rectangle with ports on each edge (north, south, east, and west).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
Size
|
rectangle size. |
(4.0, 2.0)
|
layer
|
LayerSpec
|
tuple (int, int). |
'PAD'
|
port_type
|
str | None
|
optical, electrical. |
'electrical'
|
port_inclusion
|
float
|
from edge. |
0.0
|
port_orientations
|
Ints | None
|
list of port_orientations to add. None does not add ports. |
(180, 90, 0, -90)
|
auto_rename_ports
|
bool
|
auto rename ports. |
True
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.compass(size=(4, 2), layer='PAD', port_type='electrical', port_inclusion=0, port_orientations=(180, 90, 0, -90), auto_rename_ports=True)
c.draw_ports()
c.plot()
coupler¶
A coupler.
a coupler is a 2x2 splitter
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gap
|
float
|
the gap between the waveguides forming the straight part of the coupler. |
0.236
|
length
|
float
|
the length of the coupler. |
20.0
|
dy
|
float
|
the height of the s-bend. |
4.0
|
dx
|
float
|
the length of the s-bend. |
15.0
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.coupler(gap=0.236, length=20, dy=4, dx=15, cross_section='xs_rc500')
c.draw_ports()
c.plot()
coupler_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.coupler_rc(gap=0.236, length=20, dy=4, dx=15, cross_section='xs_rc500')
c.draw_ports()
c.plot()
coupler_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.coupler_ro(gap=0.236, length=20, dy=4, dx=15, cross_section='xs_ro500')
c.draw_ports()
c.plot()
coupler_straight¶
The straight part of a coupler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
the length of the straight part of the coupler. |
20.0
|
gap
|
float
|
the gap between the waveguides forming the straight part of the coupler. |
0.236
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.coupler_straight(length=20, gap=0.236, cross_section='xs_rc500')
c.draw_ports()
c.plot()
die¶
A die matching the CORNERSTONE SOI500 1550 nm packaging template.
Cell0_SOI500_Full_1550nm_Packaging_Template: 11.47 x 4.9 mm floorplan, 16 grating couplers per side at a 250 um pitch (y = -1850 ... 1900 um) pointing outwards, the outermost pair on each side joined by a loopback, and 31 pads of 150 x 200 um per side at a 300 um pitch (x = -4615 ... 4385 um, y = +-2300 um).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.die(cross_section='xs_rc500')
c.draw_ports()
c.plot()
die_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.die_rc(cross_section='xs_rc500')
c.draw_ports()
c.plot()
die_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.die_ro(cross_section='xs_ro500')
c.draw_ports()
c.plot()
grating_coupler_array¶
An array of grating couplers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pitch
|
float
|
the pitch of the grating couplers |
127.0
|
n
|
int
|
the number of grating couplers |
6
|
centered
|
if True, centers the array around the origin. |
True
|
|
grating_coupler
|
the name of the grating coupler to use in the array. |
None
|
|
port_name
|
port name |
'o1'
|
|
with_loopback
|
if True, adds a loopback between edge GCs. Only works for rotation = 90 for now. |
False
|
|
rotation
|
rotation angle for each reference. |
-90
|
|
straight_to_grating_spacing
|
spacing between the last grating coupler and the loopback. |
10.0
|
|
cross_section
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
|
radius
|
float | None
|
optional radius for routing the loopback. |
None
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_array(pitch=127, n=6, cross_section='xs_rc500', centered=True, port_name='o1', with_loopback=False, rotation=-90, straight_to_grating_spacing=10)
c.draw_ports()
c.plot()
grating_coupler_elliptical¶
A grating coupler with curved but parallel teeth.
grating_line_width is the width of the unetched ridge between two
trenches (GDS 6). The CORNERSTONE SOI pre-DRC deck limits GDS 6 gaps narrower
than 350 nm to 20 um length, and the ridges here are longer arcs, so they are
350 nm wide (as for si220). The optics are not re-optimised for the wider
ridge: the period still follows wavelength with the same neff, so the
centre wavelength and coupling efficiency shift somewhat (most at O-band,
where the ridge fill factor rises from about 43% to 60%); simulate the
grating before relying on its passband.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wavelength
|
float
|
the center wavelength for which the grating is designed. |
1.55
|
grating_line_width
|
float
|
width of the unetched ridge between trenches, in um. Keep it at 0.35 or more to pass the CORNERSTONE deck. |
0.35
|
cross_section
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_elliptical(wavelength=1.55, grating_line_width=0.35, cross_section='xs_rc500')
c.draw_ports()
c.plot()
grating_coupler_elliptical_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_elliptical_rc(wavelength=1.55, grating_line_width=0.35, cross_section='xs_rc500')
c.draw_ports()
c.plot()
grating_coupler_elliptical_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_elliptical_ro(wavelength=1.31, grating_line_width=0.35, cross_section='xs_ro500')
c.draw_ports()
c.plot()
grating_coupler_rectangular¶
A grating coupler with straight and parallel teeth.
Defaults reproduce SOI500nm_1550nm_TE_RIB_Grating_Coupler: a 350 um linear taper from the waveguide to a 10 um wide, 42 um long grating section with 60 teeth, each 0.28 um etched (GDS layer 6, 160 nm deep) at a 0.53 um period and 11 um tall, the first 7.116 um after the taper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
period
|
float
|
the period of the grating. |
0.53
|
n_periods
|
int
|
the number of grating teeth. |
60
|
fill_factor
|
float
|
etched tooth width (GDS layer 6) as a fraction of the period. |
0.5283
|
length_taper
|
float
|
the length of the taper tapering up to the grating. |
350.0
|
width_grating
|
float
|
the width of the waveguide under the grating. |
10.0
|
length_grating
|
float
|
the length of the full-width waveguide after the taper. |
42.0
|
grating_offset
|
float
|
distance from the end of the taper to the first tooth. |
7.116
|
teeth_overhang
|
float
|
how far the teeth extend beyond each side of the waveguide. |
0.5
|
wavelength
|
float
|
the center wavelength for which the grating is designed. |
1.55
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_rectangular(period=0.53, n_periods=60, fill_factor=0.528, length_taper=350, width_grating=10, length_grating=42, grating_offset=7.116, teeth_overhang=0.5, wavelength=1.55, cross_section='xs_rc500')
c.draw_ports()
c.plot()
grating_coupler_rectangular_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_rectangular_rc(period=0.53, n_periods=60, fill_factor=0.528, length_taper=350, width_grating=10, length_grating=42, grating_offset=7.116, teeth_overhang=0.5, wavelength=1.55, cross_section='xs_rc500')
c.draw_ports()
c.plot()
grating_coupler_rectangular_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.grating_coupler_rectangular_ro(period=0.53, n_periods=60, fill_factor=0.528, length_taper=350, width_grating=10, length_grating=42, grating_offset=7.116, teeth_overhang=0.5, wavelength=1.55, cross_section='xs_ro500')
c.draw_ports()
c.plot()
mmi1x2¶
An mmi1x2.
An mmi1x2 is a splitter that splits a single input to two outputs. Defaults match SOI500nm_1550nm_TE_RIB_2x1_MMI without its 10 um port straights: 37.5 x 6 um body, 20 um tapers to 1.6 um.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
float | None
|
the width of the waveguides connecting at the mmi ports. |
None
|
width_taper
|
float
|
the width at the base of the mmi body. |
1.6
|
length_taper
|
float
|
the length of the tapers going towards the mmi body. |
20.0
|
length_mmi
|
float
|
the length of the mmi body. |
37.5
|
width_mmi
|
float
|
the width of the mmi body. |
6.0
|
gap_mmi
|
float
|
the gap between the tapers at the mmi body. |
1.47
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi1x2(width_taper=1.6, length_taper=20, length_mmi=37.5, width_mmi=6, gap_mmi=1.47, cross_section='xs_rc500')
c.draw_ports()
c.plot()
mmi1x2_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi1x2_rc(width_taper=1.6, length_taper=20, length_mmi=37.5, width_mmi=6, gap_mmi=1.47, cross_section='xs_rc500')
c.draw_ports()
c.plot()
mmi1x2_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi1x2_ro(width_taper=1.6, length_taper=20, length_mmi=37.5, width_mmi=6, gap_mmi=1.47, cross_section='xs_ro500')
c.draw_ports()
c.plot()
mmi2x2¶
An mmi2x2.
An mmi2x2 is a 2x2 splitter. Defaults match SOI500nm_1550nm_TE_RIB_2x2_MMI without its 10 um port straights: 50.2 x 6 um body, 20 um tapers to 1.6 um, 0.4 um gap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
float | None
|
the width of the waveguides connecting at the mmi ports. |
None
|
width_taper
|
float
|
the width at the base of the mmi body. |
1.6
|
length_taper
|
float
|
the length of the tapers going towards the mmi body. |
20.0
|
length_mmi
|
float
|
the length of the mmi body. |
50.2
|
width_mmi
|
float
|
the width of the mmi body. |
6.0
|
gap_mmi
|
float
|
the gap between the tapers at the mmi body. |
0.4
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi2x2(width_taper=1.6, length_taper=20, length_mmi=50.2, width_mmi=6, gap_mmi=0.4, cross_section='xs_rc500')
c.draw_ports()
c.plot()
mmi2x2_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi2x2_rc(width_taper=1.6, length_taper=20, length_mmi=50.2, width_mmi=6, gap_mmi=0.4, cross_section='xs_rc500')
c.draw_ports()
c.plot()
mmi2x2_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mmi2x2_ro(width_taper=1.6, length_taper=20, length_mmi=50.2, width_mmi=6, gap_mmi=0.4, cross_section='xs_ro500')
c.draw_ports()
c.plot()
mzi¶
A Mach-Zehnder Interferometer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
delta_length
|
float
|
the difference in length between the upper and lower arms of the mzi. |
10.0
|
bend
|
the name of the default bend of the mzi. |
'bend_circular_rc'
|
|
straight
|
the name of the default straight of the mzi. |
'straight_rc'
|
|
splitter
|
the name of the default splitter of the mzi. |
'mmi1x2_rc'
|
|
combiner
|
the name of the default combiner of the mzi. |
'mmi2x2_rc'
|
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mzi(delta_length=10, bend='bend_circular_rc', straight='straight_rc', splitter='mmi1x2_rc', combiner='mmi2x2_rc', cross_section='xs_rc500')
c.draw_ports()
c.plot()
mzi_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mzi_rc(delta_length=10, bend='bend_circular_rc', straight='straight_rc', splitter='mmi1x2_rc', combiner='mmi2x2_rc', cross_section='xs_rc500')
c.draw_ports()
c.plot()
mzi_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.mzi_ro(delta_length=10, bend='bend_circular_ro', straight='straight_ro', splitter='mmi1x2_ro', combiner='mmi2x2_ro', cross_section='xs_ro500')
c.draw_ports()
c.plot()
pad¶
An electrical pad.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
Size
|
the pad size in um (the packaging template uses 150 x 200 um). |
(100.0, 100.0)
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.pad(size=(100, 100))
c.draw_ports()
c.plot()
rectangle¶
A rectangle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layer
|
LAYER.FLOORPLAN. |
FLOORPLAN
|
|
**kwargs
|
additional arguments. |
{}
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.rectangle(layer='FLOORPLAN')
c.draw_ports()
c.plot()
straight¶
A straight waveguide.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
the length of the waveguide. |
10.0
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
kwargs
|
additional arguments to pass to the straight function. |
{}
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.straight(length=10, cross_section='xs_rc500')
c.draw_ports()
c.plot()
straight_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.straight_rc(length=10, cross_section='xs_rc500')
c.draw_ports()
c.plot()
straight_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.straight_ro(length=10, cross_section='xs_ro500')
c.draw_ports()
c.plot()
taper¶
A taper.
A taper is a transition between two waveguide widths
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
the length of the taper. |
10.0
|
width1
|
float | None
|
the input width of the taper (defaults to the cross-section width). |
None
|
width2
|
float | None
|
the output width of the taper (if not given, use port). |
None
|
port
|
Port | None
|
the port (with certain width) to taper towards (if not given, use width2). |
None
|
cross_section
|
CrossSectionSpec
|
a cross section or its name or a function generating a cross section. |
'xs_rc500'
|
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.taper(length=10, cross_section='xs_rc500')
c.draw_ports()
c.plot()
taper_rc¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.taper_rc(length=10, width1=0.45, cross_section='xs_rc500')
c.draw_ports()
c.plot()
taper_ro¶
:noindex:

from cspdk.si500 import cells, PDK
PDK.activate()
c = cells.taper_ro(length=10, width1=0.4, cross_section='xs_ro500')
c.draw_ports()
c.plot()
wire_corner¶
A wire corner.
A wire corner is a bend for electrical routes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cross_section
|
"metal_routing". |
'metal_routing'
|
|
**kwargs
|
additional arguments. |
{}
|
:noindex:
