Bundle routing with customizable fanouts

This sample illustrates how to use customizable fanouts in i3.ConnectManhattanBundle, which lets you connect multiple start and end ports together in a convenient way.

Define instances and placements in Circuit

import si_fab.all as pdk
from ipkiss3 import all as i3
import matplotlib.pyplot as plt

pitch = 5
bend_radius = 10
grating = pdk.FC_TE_1550()
splitter = pdk.MMI1x2Optimized1550()
num_io = 16

insts = {}
for cnt in range(num_io):
    insts[f"gc_{cnt}"] = grating
    insts[f"mmi_{cnt}"] = splitter

x_offset = 1000
y_offset = 300

gc_placement = [i3.Place(f"gc_{cnt}:out", (cnt * 40, 0), angle=-90) for cnt in range(num_io)]
mmi_placement = [i3.Place(f"mmi_{cnt}", (x_offset, -y_offset - 20 * cnt), angle=0) for cnt in range(num_io)]

specs = gc_placement + mmi_placement

# Circuit definition using insts and specs defined above
i3.Circuit(
    insts=insts,
    specs=specs,
).get_default_view(i3.LayoutView).visualize()
plot customizable fanouts
<Figure size 640x480 with 1 Axes>

Connect the outputs of splitter array to the output grating couplers

In i3.ConnectManhattanBundle,we have to specify start and end fanouts. The following bundle specification uses i3.ManhattanFanout, which, as the name suggests,creates Manhattan routes.

We should first define the direction of the output waveguides for ManhattanFanout. The direction can be EAST, WEST, NORTH and SOUTH. The default direction is EAST

bundle = [
    i3.ConnectManhattanBundle(
        connections=[(f"mmi_{num_io - 1 - n}:in1", f"gc_{n}:out") for n in range(num_io)],
        start_fanout=i3.ManhattanFanout(output_direction=i3.NORTH),
        end_fanout=i3.ManhattanFanout(),  # `out_direction` will be the default direction(EAST)
        pitch=pitch,
        bend_radius=bend_radius,
    )
]

# Circuit definition with outputs connected
i3.Circuit(
    insts=insts,
    specs=specs + bundle,
).get_default_view(i3.LayoutView).visualize()
plot customizable fanouts
<Figure size 640x480 with 1 Axes>

The next example shows how different types of fanout can be combined:

bundle = [
    i3.ConnectManhattanBundle(
        connections=[(f"mmi_{num_io - 1 - n}:in1", f"gc_{n}:out") for n in range(num_io)],
        start_fanout=i3.SBendFanout(),
        end_fanout=i3.ManhattanFanout(),
        pitch=pitch,
        bend_radius=bend_radius,
    )
]

# Circuit definition with outputs connected
i3.Circuit(
    insts=insts,
    specs=specs + bundle,
).get_default_view(i3.LayoutView).visualize()


# We can also change the `end_position` of the fanout which determines the starting position of Manhattan routing.

position_start = (900, -400)
position_end = (650, -200)

bundle = [
    i3.ConnectManhattanBundle(
        connections=[(f"mmi_{num_io - 1 - n}:in1", f"gc_{n}:out") for n in range(num_io)],
        start_fanout=i3.SBendFanout(end_position=position_start),  # default `reference` will be center of the ports
        end_fanout=i3.ManhattanFanout(output_direction=i3.EAST, reference="gc_0:out", end_position=position_end),
        pitch=pitch,
        bend_radius=bend_radius,
    )
]

# Circuit definition with outputs connected
i3.Circuit(insts=insts, specs=specs + bundle).get_default_view(i3.LayoutView).visualize(show=False)

plt.scatter(
    position_start[0], position_start[1], marker="x", color="r", s=80, zorder=50
)  # end_position for the reference of the start_fanout
plt.scatter(
    position_end[0], position_end[1], marker="x", color="r", s=80, zorder=50
)  # end_position for the reference of the end_fanout
plt.show()
  • plot customizable fanouts
  • plot customizable fanouts