add_route_from_steps is the relative-coordinate sibling of
add_route_from_corners. Instead of giving absolute (x, y) corner
points, you describe each leg of the route as a one-axis step. The
big advantage: the same step recipe works at any placement, so it's
a natural way to write reusable routing patterns.
Each step contributes one corner. The four supported forms are:
| Key | Meaning |
|---|---|
dx |
move by Δx from the previous corner (manhattan east/west) |
dy |
move by Δy from the previous corner (manhattan north/south) |
x |
absolute x in dbu, or a "inst,port" string that resolves to a port's x |
y |
absolute y in dbu, or a "inst,port" string that resolves to a port's y |
Interior steps must use exactly one axis (horizontal or vertical). The first and last steps may combine both axes to set the fan-in/out anchor.
This is optical routing: bends are bend_euler at the PDK
minimum radius (5 µm for cspdk.si220.cband).
Imports
Z-Detour Described as Steps
The same field1 layout, routed with a step recipe that mixes relative and absolute moves and ends by anchoring the y-coordinate to the output port directly.
c = gf.Component()
ref = c << dr.pcells.field1()
start = ref.cell.insts["in"].ports["o2"]
stop = ref.cell.insts["out"].ports["o1"]
stop_pos = dr.types.validate_position(stop)
steps = [
{"dx": 41500}, # head east 41.5 µm from the input
{"dy": 32500}, # turn north 32.5 µm
{"x": 2000}, # turn west, land at absolute x = 2 µm
{"y": stop_pos[1]}, # turn north, land at the y of the output port
]
dr.add_route_from_steps(
c=c,
start=start,
stop=stop,
steps=steps,
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
)
dr.util.show_cell(c)
Next steps
- Prefer absolute corner points? See Corners Routing.
- The bundle version of this routing style is
add_bundle_from_corners(steps=...), demonstrated in Array Routing. - For obstacle-aware routing without writing the shape yourself, see A* Single Route.