add_route_from_corners builds a route that passes through a list of
explicit corner points, given in absolute coordinates (database
units — typically 1 nm). Reach for it when you want full control over
the route shape — for example, to keep a waveguide inside a routing
channel, match a specific floorplan, or reproduce a hand-drawn path.
This is optical routing: bends are bend_euler at the PDK
minimum radius (5 µm for cspdk.si220.cband), so the curvature is
continuous at each joint and the mode mismatch stays inside the loss
budget.
Imports
Z-Detour Through Four Corners
We route from in.o2 to out.o1 through four corners. The detour
goes east, then up, then back west, then down to the destination —
the kind of shape you'd write when the floorplan needs the route to
backtrack around an obstacle or stay inside a defined channel.
dr.types.validate_position(port) extracts (x, y) in dbu from a
port handle, which is what add_route_from_corners expects for
start / stop / corners.
c = gf.Component()
ref = c << dr.pcells.field1()
start = dr.types.validate_position(ref.cell.insts["in"].ports["o2"])
stop = dr.types.validate_position(ref.cell.insts["out"].ports["o1"])
# Corners are absolute (x, y) points in dbu. Field1 is 50×50 µm
# (50 000 dbu on a 1 nm grid).
corners = [
(44000, start[1]), # head east at the input y
(44000, 35000), # turn north
(1000, 35000), # turn west
(1000, stop[1]), # turn south to the output y
]
dr.add_route_from_corners(
c=c,
start=start,
stop=stop,
corners=corners,
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
)
dr.util.show_cell(c)
Next steps
- If you'd rather describe the route as a sequence of relative moves (reusable across placements), see Steps Routing.
- The bundle (N-wire) version of this routing style is [
add_bundle_from_corners][doroutes.add_bundle_from_corners], demonstrated in Array Routing. - Don't want to spell the corners out yourself? Let A* find them in A* Single Route.