Bundle From Corners
add_bundle_manual is the bundle (multi-wire) counterpart of
add_route_manual. It performs a
fan-in at each end so the N wires converge onto a single bundle
line, then routes that bundle through user-specified corners or
steps.
Reach for it when:
- the floorplan dictates an exact route shape (a routing channel, fence regions, hand-drawn paths),
- the same routing recipe needs to apply to many similarly-shaped
layouts (use
steps=for placement-independent recipes), or - A* routing is overkill for a route you already know the shape of.
This is optical routing: bends are bend_euler at the PDK
minimum radius (5 µm for gdsfactory.gpdk).
Imports
import gdsfactory as gf
from gdsfactory.gpdk import PDK
import gdsfactoryplus as gfp
dr = gfp.routing.doroutes
PDK.activate()
A 5-Port Test Frame
dr.pcells.fanout_frame2(transition="ew") puts 5 east-facing inputs
on the left edge and 5 west-facing outputs on the right edge of a
100 × 200 µm frame — the same layout used in the A* bundle routing
tutorial, so you can compare the algorithmic and corner-based
approaches side by side.
c = gf.Component()
ref = c << dr.pcells.fanout_frame2(transition="ew", add_frame=True)
c.add_ports(ref)
dr.util.show_cell(c)
Bundle Through Explicit Corners
Pass corners=[(x1, y1), (x2, y2), ...] to route the bundle through a
sequence of absolute coordinate points (in microns).
The bundle's fan-in anchors at the port centroid by default — for
this 5-port frame that's (1, 100) on the input side, so the bundle
exits the input fan-in at roughly (13, 100) heading east. Each
corner you list must be axis-aligned with the previous (manhattan
routing), so corners describe a sequence of 90° turns from the bundle
exit to the bundle stop on the other side.
The 4-corner Z-shape below detours the bundle through y=30: south
at x=50, east at y=30, north at x=80 back to the output bundle
line.
c = gf.Component()
ref = c << dr.pcells.fanout_frame2(transition="ew", add_frame=True)
c.add_ports(ref)
# Bundle exits at (~13, 100, east) and stops at (~87, 75, east).
# 4-corner Z: south, east, south, then back up to the output centroid y=75.
result = dr.add_bundle_manual(
component=c,
ports1=[p for p in c.ports if str(p.name).startswith("in")],
ports2=[p for p in c.ports if str(p.name).startswith("out")],
corners=[
(50, 100), # turn south at (50, 100) µm
(50, 30), # turn east at (50, 30)
(80, 30), # turn north at (80, 30)
(80, 75), # back to output centroid y=75; final east leg is implicit
],
spacing=1.0,
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
)
dr.util.show_cell(c)