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
See also
Examples
""" This example illustrations how you can use the control_points property to guide your waveguide around an obstacle. """ from technologies import silicon_photonics # noqa: F401 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()
from technologies import silicon_photonics # noqa: F401 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()
from technologies import silicon_photonics # noqa: F401 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()
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()
from technologies import silicon_photonics # noqa: F401 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() # Note 1: These two types of control points don't mix: [V(20), (50, 50), H(10)] is not allowed. # Note 2: When using more than one horizontal and/or vertical control points an H must always follow a V, # and vice versa. You can't pass two of the same type right after each other. For instance: # [V(20), V(30), H(10)] is not allowed, [V(20), H(20), V(30), H(10)] is allowed.
from technologies import silicon_photonics # noqa: F401 import ipkiss3.all as i3 from picazzo3.traces.rib_wg.trace import RibWaveguideTemplate from ipkiss3.all import START, END # 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) control_points = [ START + (30, 10), # control point at (30, 10) relative to the start port (50, 50), # control point at (50, 50) relative to (0, 0) END - (30, 10), ] # control point at (-30, -10) relative to the end port wg = i3.ConnectManhattan.connect( port1, port2, name="manhattan_connection", control_points=control_points, bend_radius=5.0 ) lo = wg.get_default_view(i3.LayoutView) lo.visualize() # Similarily it is possible to define relative i3.H and i3.V control points wg = i3.ConnectManhattan.connect( port1, port2, name="manhattan_connection2", control_points=[i3.H(END - 40)], bend_radius=5.0 ) lo = wg.get_default_view(i3.LayoutView) lo.visualize()
When required ConnectManhattan will introduce transitions to create a valid connection.:
from technologies import silicon_photonics # noqa: F401 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)
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:
def __example7_transitioning(self): from technologies import silicon_photonics # noqa: F401 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)
from technologies import silicon_photonics # noqa: F401 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()