Routing to IO#

Routing electrical#

For routing low speed DC electrical ports you can use sharp corners instead of smooth bends.

You can also define port.orientation = None to ignore the port orientation for low speed DC ports.

For single route between ports you can use route_single_electrical

route_single_electrical#

route_single_electrical has bend = wire_corner with a 90deg bend corner.

from functools import partial

import gdsfactory as gf
from gdsfactory.generic_tech import get_generic_pdk
from gdsfactory.samples.big_device import big_device

gf.config.rich_output()

c = gf.Component()
pt = c << gf.components.pad_array(port_orientation=270, columns=3)
pb = c << gf.components.pad_array(port_orientation=90, columns=3)
pt.dmove((70, 200))
c.plot()

../_images/ef8dd90f6eb3ad268397efca6f9737c3cc3da30ddc004ba20a9eeb7e388947c6.png
c = gf.Component()
pt = c << gf.components.pad_array(port_orientation=270, columns=3)
pb = c << gf.components.pad_array(port_orientation=90, columns=3)
pt.dmove((70, 200))
route = gf.routing.route_single_electrical(c, pt.ports["e11"], pb.ports["e11"])
c.plot()

../_images/766aa69917ab62c879dfc329507b923b1f5f174986f5108f028785a4963bd4ea.png
c = gf.Component()
pt = c << gf.components.pad_array(orientation=None, columns=3)
pb = c << gf.components.pad_array(orientation=None, columns=3)
pt.dmove((70, 200))
route = gf.routing.route_single(
    c, pt.ports["e11"], pb.ports["e11"], cross_section="strip"
)
c.plot()

../_images/76ec1b4c02249dbc814b5e34af60e8ad9b4f5de69ab8d5d65f29ae013f4a336d.png

There is also bend = wire_corner45 for 45deg bend corner with parametrizable “radius”:

c = gf.Component()
pt = c << gf.components.pad_array(port_orientation=270, columns=1)
pb = c << gf.components.pad_array(port_orientation=90, columns=1)
pt.dmove((300, 300))
route = gf.routing.route_single(
    c,
    pt.ports["e11"],
    pb.ports["e11"],
    bend="wire_corner45",
    port_type="electrical",
    taper=None,
    cross_section="metal_routing",
    allow_width_mismatch=True,
)
c.plot()

../_images/3d59c2f595603f77eec1c214982ef18572ca88a51365d9a4974617f4477e25df.png
c = gf.Component()
pt = c << gf.components.pad_array(orientation=270, columns=1)
pb = c << gf.components.pad_array(orientation=90, columns=1)
pt.dmove((300, 300))
route = gf.routing.route_single(
    c,
    pt.ports["e11"],
    pb.ports["e11"],
    bend="wire_corner45",
    radius=100,
    taper=None,
    cross_section="metal_routing",
    port_type="electrical",
    allow_width_mismatch=True,
)
c.plot()
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/components/pad.py:101: UserWarning: orientation is deprecated, use port_orientation
  warnings.warn("orientation is deprecated, use port_orientation")

../_images/b598910960411d4be92fe6d84d0e0b01b819c2dec2bbbfd2f7902b618c79a003.png

route_quad#

c = gf.Component()
pt = c << gf.components.pad_array(orientation=270, columns=3)
pb = c << gf.components.pad_array(orientation=90, columns=3)
pt.dmove((100, 200))
gf.routing.route_quad(c, pt.ports["e11"], pb.ports["e11"], layer=(49, 0))
c.plot()

../_images/40ab8f0b700b8b4e5472ccd1f1fa684efebc2937941d202559022b287ede7677.png

route_single_from_steps#

import gdsfactory as gf

c = gf.Component()
pt = c << gf.components.pad_array(orientation=270, columns=3)
pb = c << gf.components.pad_array(orientation=90, columns=3)
pt.dmove((100, 200))
route = gf.routing.route_single_from_steps(
    c,
    pb.ports["e11"],
    pt.ports["e11"],
    steps=[
        {"y": 200},
    ],
    cross_section="metal_routing",
    bend=gf.components.wire_corner,
    port_type="electrical",
    allow_width_mismatch=True,
)
c.plot()
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/pdk.py:388: UserWarning: {'radius': None} are ignored for cross_section 'xs_0efa6a61'
  warnings.warn(
/home/runner/work/gdsfactory/gdsfactory/gdsfactory/pdk.py:388: UserWarning: {'width': 10.0} are ignored for cross_section 'xs_0efa6a61'
  warnings.warn(

../_images/d3ea3a0b283c134101f2809a240754ca537560a3bc686b37c4ac4168dbf0b072.png
c = gf.Component()
pt = c << gf.components.pad_array(orientation=None, columns=3)
pb = c << gf.components.pad_array(orientation=None, columns=3)
pt.dmove((100, 200))
route = gf.routing.route_single_from_steps(
    c,
    pb.ports["e11"],
    pt.ports["e11"],
    steps=[
        {"y": 200},
    ],
    cross_section="metal_routing",
    bend=gf.components.wire_corner,
    port_type="electrical",
    allow_width_mismatch=True,
)
c.plot()

../_images/eb159a8c53990bdb748ff1e4b9eb9429ad12e44b109050d16145e54726d026ec.png

route_bundle_electrical#

For routing groups of ports you can use route_bundle that returns a bundle of routes using a bundle router (also known as bus or river router)

c = gf.Component()
pt = c << gf.components.pad_array(orientation=270, columns=3)
pb = c << gf.components.pad_array(orientation=90, columns=3)
pt.dmove((100, 200))

routes = gf.routing.route_bundle_electrical(
    c, pt.ports, pb.ports, end_straight_length=60, separation=30
)
c.plot()

../_images/d4126406a3948b2502719c3824ffda6c1c0ba55338bb3da00f4d797768e73296.png

Routing to pads#

You can also route to electrical pads.

c = gf.components.straight_heater_metal(length=100.0)
cc = gf.routing.add_pads_bot(component=c, port_names=("l_e4", "r_e4"), fanout_length=80)
cc.plot()

../_images/1d31cbd0379a3aa259941aecd49acb0b4c718b0c68f92467ba4504912bd07a7a.png
c = gf.components.straight_heater_metal(length=100.0)
cc = gf.routing.add_pads_bot(component=c, port_names=("l_e4", "r_e4"), fanout_length=80)
cc.plot()

../_images/1d31cbd0379a3aa259941aecd49acb0b4c718b0c68f92467ba4504912bd07a7a.png
c = gf.components.straight_heater_metal(length=110)
cc = gf.routing.add_pads_top(component=c, port_names=("l_e2", "r_e2"), fanout_length=80)
cc.plot()

../_images/01be073a8556d504eb69dffb661bb518f6b256031938821ae90f5a7897b3cccd.png
c = gf.c.nxn(
    xsize=600,
    ysize=200,
    north=2,
    south=3,
    wg_width=10,
    layer="M3",
    port_type="electrical",
)
cc = gf.routing.add_pads_top(component=c)
cc.plot()

../_images/60da1612fc7db9aa3c60015f99c927379eec30497db06cf428daa062c148a7ad.png
n = west = north = south = east = 10
spacing = 20
c = gf.components.nxn(
    xsize=n * spacing,
    ysize=n * spacing,
    west=west,
    east=east,
    north=north,
    south=south,
    port_type="electrical",
    wg_width=10,
)
c.plot()

../_images/0046a4445456be27ee9683537cfb68d22fdd143ec5427b49e1f93b05cdb81640.png
cc = gf.routing.add_pads_top(component=c, fanout_length=300)
cc.plot()

../_images/73535d7405437e79d7242502c70464f30fdbc8e23995c0135cafdbe87f436ae6.png

Routing to optical terminations#

Route to Fiber Array#

You can route to a fiber array.

from gdsfactory.samples.big_device import big_device

component = big_device(nports=10)
c = gf.routing.add_fiber_array(component=component, radius=10.0, fanout_length=60.0)
c.plot()

../_images/d4e155cb97291db3be29069b10876569cea7fef0da3f6dc970cf19e633cf502d.png

You can also mix and match TE and TM grating couplers. Notice that the TM polarization grating coupler is bigger.

import gdsfactory as gf

c = gf.components.mzi_phase_shifter()
gcte = gf.components.grating_coupler_te

cc = gf.routing.add_fiber_array(
    component=c,
    optical_routing_type=2,
    grating_coupler=gf.components.grating_coupler_te,
    radius=20,
)
cc.plot()

../_images/899d384e8d65b161f3a8e7c624bd13b1d31988aeba4a5897e25c8444bdd28135.png

Route to edge couplers#

You can also route Edge couplers to a fiber array or to both sides of the chip.

For routing to both sides you can follow different strategies:

  1. Place the edge couplers and route your components to the edge couplers.

  2. Extend your component ports to each side.

  3. Anything you imagine …