Connector Reference

Connectors generate a cell to connect ports with a predefined algorithm, packaging the knowledge to do that into one place (a python class).

There exist two types of connectors:

  • Single connectors, which connect 2 ports to each other. The input is a specification of a start and an end port, and optional parameters. The output is a cell object (usually a Waveguide object).

  • Bundle connectors, which connect series of ports to each other by means of fanouts at the start and end and an array of waveguides in between. The input is a specification of the start and end ports, how to fan out, and optional parameters. The output is a cell object (usually a TraceBundle object).

Connectors are mainly used to connect the instances within your circuit using i3.Circuit or i3.place_and_route. In that case connectors provide routing specifications. Both a single combination of a start/end port, or a list of them can be provided. The example below illustrates this by creating two routes with the same bend_radius:

import si_fab.all as pdk
import ipkiss3.all as i3

wg_stub = i3.Waveguide()
cell = i3.Circuit(
    insts={'wg1': wg_stub, 'wg2': wg_stub, 'wg3': wg_stub},
        i3.Place('wg1', (0, 0), angle=45),
        i3.Place('wg2', (50, 0), angle=45),
        i3.Place('wg3', (75, 75), angle=-45),

        i3.ConnectBend([('wg1:out', 'wg2:in'), ('wg2:out', 'wg3:in')], bend_radius=10)
    exposed_ports={'wg1:in': 'in', 'wg3:out': 'out'}
lv = cell.get_default_view(i3.LayoutView)

Connectors can also be used to quickly create a waveguide, outside the context of i3.Circuit and i3.place_and_route. The basic example below illustrates this:

import si_fab.all as pdk
import ipkiss3.all as i3

input_port = i3.OpticalPort(name="in", position=(5.0, 0.0))
output_port = i3.OpticalPort(name="out", position=(25.0, 5.0), angle_deg=180.0)

# connect the ports
wg = i3.ConnectBend.connect(start_port=input_port, end_port=output_port, bend_radius=10.0)

wg_layout = wg.get_default_view(i3.LayoutView)

In this example:

  • i3.ConnectBend is a connector type that packages the knowledge to connect 2 ports with a bend waveguide.

  • connect is a method of i3.ConnectBend that creates a connection between the two ports with a bend radius of 10um.

  • We call the connect function, which returns a PCell object, in this case a RoundedWaveguide.


all ports used in a connector must have a unique name assigned to them.

A few more notes:

  • Connectors are a layer of functionality on top of routing:
    • The routing functions generate Route objects, which are shapes that describe the waypoints.

    • Connectors generate a pcell (after calling the connect method) and use one or multiple routing functions.

  • A Connector does not have to return a (single) i3.Waveguide object: it could also be a chain of waveguides or a very different object (as long as it returns a Cell).

Creating a connector

The first step is to create a class that inherits from the i3.Connector base class. This provides the key features every connector needs.

The second step is implementing the _connect method, where you define how to connect the start port to the end port. Its input arguments are the start port, end port and name of the connection (optional). Any other properties required to create the connection (e.g. the bending radius) are defined using standard IPKISS API, with the help of DefinitionProperty.

The code below demonstrates how to create a basic connector:

import ipkiss3.all as i3

class MyConnector(i3.Connector):
    trace_template = i3.TraceTemplateProperty(doc="Trace template for the connection")
    bend_radius = i3.PositiveNumberProperty(doc="Bending radius of the route")

    def _default_bend_radius(self):
        return 5.0

    def _connect(self, start_port, end_port, name=None):
        # Algorithm that returns a pcell connecting start_port to end_port

        # Access the DefinitionProperties defined above using `self`.
        trace_template = self.trace_template
        bend_radius = self.bend_radius
        return pcell

The only requirements for the _connect method is that the start and end port have the same domain (electrical, optical, …) and that the return value is an instance of i3.PCell. These requirements are automatically checked by the Connector base class.

As you can see, the Connectors are a generic framework that can be tailored to your specific use-case.

Connector algorithms

These are primarily used as specs in i3.place_and_route or i3.Circuit. See the placement and routing documentation for more information.

Scalar connectors


Base class for connectors.


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


A connector that uses i3.RouteManhattan to connect two ports and returns a waveguide with a different trace template in the straight sections.


Connector for creating an as simple as possible bend between two optical ports based on the given rounding parameters.


Connect two ports 'logically', meaning that there is no physical connection but there is a Net.


A connector that uses i3.RouteManhattan to connect two electrical ports.

Bundle connectors


Connects multiple ports together using a bundle of waveguides separated by a fixed distance.

Fanouts for Bundle connectors


Create S-bend-like routes that fanout all the start ports to evenly spaced outputs.


Create L-bend-like routes that fanout all the start ports to evenly spaced outputs.