ipkiss3.all.ConnectManhattan

class ipkiss3.all.ConnectManhattan(connections=None, *args, **kwargs)

A connector that uses i3.RouteManhattan to connect two ports and returns an instance of i3.RoundedWaveguide (optical ports) or i3.ElectricalWire (electrical ports).

This connector is supposed to be used together with i3.place_and_route.

Note

Electrical ports need to have an angle (not None) for the routing algorithm to work.

Parameters:

angle_step: float and number > 0, optional

angle step for rounding

bend_radius: float and number > 0, optional

bend radius for the auto-generated bends

control_points: list, optional

Control the routing by passing either a list of points through which the route has to pass,or a list of i3.H / i3.V instances.

end_straight: float and Real, number and number >= 0, optional

The length of the straight end section of the route

min_spacing: float and Real, number and number >= 0, optional

minimal spacing between parallel sections of the route

min_straight: float and Real, number and number >= 0, optional

The minimum length of any straight sections in the route

rounding_algorithm: optional

Rounding algorithm (ShapeRound, ShapeRoundAdiabaticSpline, …). Takes a shape as input and returns a new (rounded) shape.

start_straight: float and Real, number and number >= 0, optional

The length of the straight start section of the route

trace_template: ( PCell and _TraceTemplate ), optional, *None allowed*

Trace template to use for the waveguide between the two ports, when the ports have a different template, transitions will be added. When this property is left unspecified/None the trace_template of the start_port will be used

Examples

"""
This example illustrations how you can use the control_points property to guide your waveguide around an obstacle.
"""
from technologies import silicon_photonics
from picazzo3.fibcoup.curved import FiberCouplerCurvedGrating
from ipkiss3 import all as i3
import matplotlib.pyplot as plt

# Placing the components in a circuit
gr = FiberCouplerCurvedGrating()
control_points = [(-40, 20), (0, 30), (50, 20)]
circuit = i3.Circuit(
    insts={
        'gr': gr,
        'grb1': gr,
        'grb2': gr
    },
    specs=[
        i3.Place('gr', position=(0, 0)),
        i3.Place('grb1', position=(-100, 0)),
        i3.Place('grb2', position=(+100, 0), angle=180),

        i3.ConnectManhattan(
            'grb1:out', 'grb2:out',
            control_points=control_points,
        )
    ]
)
circuit_layout = circuit.Layout()
circuit_layout.visualize(show=False)
plt.scatter([cp[0] for cp in control_points], [cp[1] for cp in control_points], c='C1', s=80, marker='x')
plt.show()
../../../_images/ipkiss3-all-ConnectManhattan-1.png
from technologies import silicon_photonics
from picazzo3.fibcoup.curved import FiberCouplerCurvedGrating
from ipkiss3 import all as i3
import matplotlib.pyplot as plt

class BondPad(i3.PCell):
    class Layout(i3.LayoutView):
        size = i3.Size2Property(default=(50.0, 50.0), doc="Size of the bondpad")
        metal_layer = i3.LayerProperty(default=i3.TECH.PPLAYER.M1.LINE, doc="Metal used for the bondpad")

        def _generate_elements(self, elems):
            elems += i3.Rectangle(layer=self.metal_layer, box_size=self.size)
            return elems

        def _generate_ports(self, ports):
            ports += i3.ElectricalPort(
                name="m1", position=(0.0, 0.0),
                shape=self.size, process=self.metal_layer.process,
                angle=0  # adding dummy angles so that the connector functions work
            )
            return ports

# Placing the components in a circuit
bp = BondPad()
bp_layout = bp.Layout(size=(50, 50))
gr = FiberCouplerCurvedGrating()

control_points = [(-40, 20), (50, 0), (100, -50)]

wire_template = i3.ElectricalWireTemplate()
wire_template.Layout(width=5.0, layer=bp_layout.metal_layer)

circuit = i3.Circuit(
    insts={
        'gr': gr,
        'gr2': gr,
        'b1': bp,
        'b2': bp
    },
    specs=[
        i3.Place('gr', position=(0, 0)),
        i3.Place('gr2', position=(100, 0)),
        i3.Place('b1', position=(-75, 0)),
        i3.Place('b2', position=(+150, 0)),
        i3.ConnectManhattan(
            'b1:m1', 'b2:m1', control_points=control_points, rounding_algorithm=None,
            trace_template=wire_template
        )
    ]
)

circuit_layout = circuit.Layout()
circuit_layout.visualize(show=False)
plt.scatter([cp[0] for cp in control_points], [cp[1] for cp in control_points], c='C1', s=80, marker='x')
plt.show()
../../../_images/ipkiss3-all-ConnectManhattan-2.png
from technologies import silicon_photonics
import ipkiss3.all as i3
from picazzo3.traces.rib_wg.trace import RibWaveguideTemplate

# Instantiate trace templates to use for the ports
tt1 = RibWaveguideTemplate()
tt1.Layout(core_width=0.5)

# Define some ports
port1 = i3.OpticalPort(position=(0.0, 0.0), angle=0.0, trace_template=tt1)
port2 = i3.OpticalPort(position=(100.0, 100.0), angle=180.0, trace_template=tt1)
# Ports with non-manhattan angles:
port3 = i3.OpticalPort(position=(0.0, 0.0), angle=-20.0, trace_template=tt1)
port4 = i3.OpticalPort(position=(50.0, 70.0), angle=100.0, trace_template=tt1)

# Create the connection
wg = i3.ConnectManhattan.connect(port1, port2, name='manhattan_connection', bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()

wg = i3.ConnectManhattan.connect(port3, port4, name='manhattan_connection2', bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()
../../../_images/ipkiss3-all-ConnectManhattan-3_00.png
../../../_images/ipkiss3-all-ConnectManhattan-3_01.png
import ipkiss3.all as i3

input_port = i3.OpticalPort(name="in", position=(0.0, 0.0), angle=0.0)
output_port = i3.OpticalPort(name="out", position=(-40.0, 40.0), angle=180.0)
bend_radius = 7.0

ra = i3.ShapeRound
wg = i3.ConnectManhattan.connect(start_port=input_port, end_port=output_port,
                                 bend_radius=bend_radius, rounding_algorithm=ra)
wg.get_default_view(i3.LayoutView).visualize()

ra = i3.SplineRoundingAlgorithm(adiabatic_angles=(15, 15))
wg = i3.ConnectManhattan.connect(start_port=input_port, end_port=output_port,
                                 bend_radius=bend_radius, rounding_algorithm=ra)
wg.get_default_view(i3.LayoutView).visualize()
../../../_images/ipkiss3-all-ConnectManhattan-4_00.png
../../../_images/ipkiss3-all-ConnectManhattan-4_01.png
from technologies import silicon_photonics
import ipkiss3.all as i3
from picazzo3.traces.rib_wg.trace import RibWaveguideTemplate

# Instantiate trace templates to use for the ports
tt1 = RibWaveguideTemplate()
tt1.Layout(core_width=0.5)

# Define some ports
port1 = i3.OpticalPort(position=(0.0, 0.0), angle=0.0, trace_template=tt1)
port2 = i3.OpticalPort(position=(100.0, 100.0), angle=180.0, trace_template=tt1)
# Ports with non-manhattan angles:
port3 = i3.OpticalPort(position=(0.0, 0.0), angle=-20.0, trace_template=tt1)
port4 = i3.OpticalPort(position=(50.0, 70.0), angle=100.0, trace_template=tt1)

# Create the connection with control_points.
# The route will go through point (50, 50):
wg = i3.ConnectManhattan.connect(port1, port2, name='manhattan_connection', control_points=[(50, 50)], bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()

# Another option for control_points is to describe the horizontal and vertical parts of the route.
# You can do this in the following way:
# [V(40)] describes that the route should be vertical at x = 40.
wg = i3.ConnectManhattan.connect(port1, port2, name='manhattan_connection2', control_points=[i3.V(40)], bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()

# [V(100), H(100)] determines that the route should be vertical at x = 100 and then horizontal at y = 100.
wg = i3.ConnectManhattan.connect(port3, port4, name='manhattan_connection3', control_points=[i3.V(100), i3.H(100)], bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()
../../../_images/ipkiss3-all-ConnectManhattan-5_00.png
../../../_images/ipkiss3-all-ConnectManhattan-5_01.png
../../../_images/ipkiss3-all-ConnectManhattan-5_02.png

When required ConnectManhattan will introduce transitions to create a valid connection.:

from technologies import silicon_photonics
import ipkiss3.all as i3
from picazzo3.traces.rib_wg.trace import RibWaveguideTemplate
from picazzo3.traces.wire_wg.trace import WireWaveguideTemplate

# Instantiate trace templates to use for the ports
tt_start = RibWaveguideTemplate()
tt_start.Layout(core_width=0.5)

tt_end = WireWaveguideTemplate()
tt_end.Layout(core_width=0.5)

start_port = i3.OpticalPort(position=(0.0, 0.0), angle=0.0, trace_template=tt_start)
end_port = i3.OpticalPort(position=(40.0, 40.0), angle=180.0, trace_template=tt_end)

# The connecting waveguide will use the trace_template specified
# on the start_port and introduce a transition at the end
# to connect properly with the end_port.
wg = i3.ConnectManhattan.connect(start_port, end_port, bend_radius=10.0)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize(annotate=True)
../../../_images/ipkiss3-all-ConnectManhattan-6.png

By default ConnectManhattan will use the trace_template from the start_port for the connecting waveguide, but this can be changed using the trace_template property:

from technologies import silicon_photonics
import ipkiss3.all as i3
from picazzo3.traces.rib_wg.trace import RibWaveguideTemplate
from picazzo3.traces.wire_wg.trace import WireWaveguideTemplate

# Instantiate trace templates to use for the ports
tt_start = RibWaveguideTemplate()
tt_start.Layout(core_width=0.5)

tt_end = WireWaveguideTemplate()
tt_end.Layout(core_width=0.5)

start_port = i3.OpticalPort(position=(0.0, 0.0), angle=0.0, trace_template=tt_start)
end_port = i3.OpticalPort(position=(40.0, 40.0), angle=180.0, trace_template=tt_end)

# use the trace_template of the end_port
# this will add the transition at the start port rather
# then at the end port.
wg = i3.ConnectManhattan.connect(start_port, end_port, bend_radius=10.0, trace_template=tt_end)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize(annotate=True)
../../../_images/ipkiss3-all-ConnectManhattan-7.png
from technologies import silicon_photonics
import ipkiss3.all as i3

# Define some trace templates
tt = i3.ElectricalWireTemplate()
tt.Layout(width=3.0)

tt2 = i3.ElectricalWireTemplate()
tt2.Layout(width=1.0)

# Define some ports
port1 = i3.ElectricalPort(position=(0.0, 0.0), angle=0.0, trace_template=tt)
port2 = i3.ElectricalPort(position=(50.0, 50.0), angle=180.0)

port3 = i3.ElectricalPort(position=(0.0, 0.0), angle=-90.0)
port4 = i3.ElectricalPort(position=(30.0, 20.0), angle=90.0)

# Make a manhattan connector
connector = i3.ConnectManhattan
# Create the connection
wg = connector.connect(port1, port2, name='manhattan_electrical', control_points=[(20, 20)])
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()

wg = connector.connect(port3, port4, name='manhattan_electrical2', trace_template=tt2)
lo = wg.get_default_view(i3.LayoutView)
lo.visualize()
../../../_images/ipkiss3-all-ConnectManhattan-8_00.png
../../../_images/ipkiss3-all-ConnectManhattan-8_01.png