Skip to main content
Built-in Elements

<autoroutingphase />

The <autoroutingphase /> element lets you split PCB autorouting into ordered passes. The common use case is to route important connections first so later connections route around them.

Props​

PropTypeDescription
phaseIndexnumberThe routing pass configured by this element. Lower numbered phases run first.
connectionstringPort selector for one connection to route in this phase. With reroute, selects one previously routed connection instead.
connectionsstring[]Port selectors for multiple connections to route in this phase. With reroute, selects previously routed connections instead.
autorouterstring | AutorouterConfigOptional autorouter preset or configuration for this phase. Omit it to use the parent board or subcircuit autorouter.
fanoutRoutingLayersLayerRef[]Layers available to boundary-terminated fanout connections.
fanoutPourNetMapRecord<LayerRef, string | string[]>Maps dedicated plane layers to the power or ground nets that should terminate on them during fanout.
busFanoutDirectionsRecord<string, BusFanoutDirection>Controls the boundary exit direction for each named bus during fanout.
reroutebooleanReroutes traces produced by earlier phases instead of routing newly assigned traces. Requires region, connection, or connections.
region{ shape?: "rect"; minX: number; maxX: number; minY: number; maxY: number }Rectangular PCB region to reconsider in a reroute phase.

Route Specific Connections First​

Use connection for one connection or connections for several. Each value is a port selector for either endpoint of a connection.

This example routes the two horizontal connections in phase 0. The vertical connection has no phase assignment, so it routes afterward and treats the completed horizontal routes as obstacles.

export default () => (
<board width="18mm" height="18mm">
<testpoint name="TP_H1" pcbX={-7} pcbY={2} padDiameter="0.8mm" />
<testpoint name="TP_H2" pcbX={7} pcbY={2} padDiameter="0.8mm" />
<testpoint name="TP_H3" pcbX={-7} pcbY={-2} padDiameter="0.8mm" />
<testpoint name="TP_H4" pcbX={7} pcbY={-2} padDiameter="0.8mm" />
<testpoint name="TP_V1" pcbX={0} pcbY={-7} padDiameter="0.8mm" />
<testpoint name="TP_V2" pcbX={0} pcbY={7} padDiameter="0.8mm" />

<autoroutingphase
phaseIndex={0}
connections={["TP_H1.pin1", "TP_H3.pin1"]}
/>

<trace name="H_TOP" from="TP_H1.pin1" to="TP_H2.pin1" />
<trace name="H_BOTTOM" from="TP_H3.pin1" to="TP_H4.pin1" />
<trace name="V_CENTER" from="TP_V1.pin1" to="TP_V2.pin1" />
</board>
)
PCB Circuit Preview
<autoroutingphase
phaseIndex={0}
connections={["TP_H1.pin1", "TP_H3.pin1"]}
/>

Selectors may use normal port selector syntax, such as "U1.pin1" or ".U1 > .pin1". You do not need to add routingPhaseIndex to a trace when an autorouting phase selects it with connection or connections.

Create Multiple Ordered Phases​

Phases run in ascending phaseIndex order. Connections without a numbered phase run after all numbered phases.

<autoroutingphase phaseIndex={0} connection="CLK_SOURCE.pin1" />
<autoroutingphase
phaseIndex={1}
connections={["USB_DP_SOURCE.pin1", "USB_DM_SOURCE.pin1"]}
/>

Here the clock connection routes first, the USB connections route second, and all remaining connections route last. Earlier routes are included as obstacles in each later pass.

Local dogbone phase​

Use <autoroutingphase autorouter="dogbone" fanoutRoutingLayers={["bottom"]} /> as a board child to add local pad-to-via escapes before default routing. It is implemented in core 0.0.2026+, but the handoff is not reliable for all BGAs: a 36-pin footprinter BGA currently triggers a TopologyMergingSolver overlap error in the subsequent default-routing stage.

The phase escapes the first physical pad in each selected connection, not both ends automatically. The destination layer must differ from the pad layer. For a tested 36-pin example with only connected pads escaped, see component-scoped dogbone fanout.

Assign Traces and Nets Explicitly​

As an alternative to selecting connections on <autoroutingphase />, use routingPhaseIndex on a <trace /> to put that trace into a phase:

<autoroutingphase phaseIndex={0} />
<trace from="U1.pin1" to="U2.pin1" routingPhaseIndex={0} />

You can also assign a <net /> to a phase. Traces connected to that net inherit the net's routing phase unless the trace sets its own routingPhaseIndex.

<autoroutingphase phaseIndex={0} />
<net name="GND" routingPhaseIndex={0} />
<trace from="C1.pin1" to="net.GND" />

If a trace has its own routingPhaseIndex, it overrides the phase inherited from a connected net.

Configure Each Phase​

Set autorouter on a phase to use a different autorouter configuration for that pass. If you omit it, the phase uses the parent board or subcircuit autorouter.

<autoroutingphase
phaseIndex={0}
connection="J1.pin1"
autorouter={{
algorithmFn: createMyAutorouter,
}}
/>

For custom phase autorouters with algorithmFn, see Create or Use a Custom Autorouter. For package-level fanout followed by a global DDR channel route, see Routing DDR.

Terminate Power Connections on Copper Planes​

Use autorouter="fanout" with fanoutPourNetMap when source-only power connections (traces with one component endpoint and one net endpoint) from a dense package should terminate on dedicated copper planes. The map associates each plane layer with the net poured on that layer.

<board width="30mm" height="20mm" layers={4}>
<autoroutingphase
autorouter="fanout"
fanoutRoutingLayers={["top", "bottom"]}
fanoutPourNetMap={{
inner1: "GND",
inner2: "V3_3",
}}
/>

<net name="GND" isGroundNet />
<net name="V3_3" isPowerNet />
<chip name="U1" footprint="qfn32" />
<trace name="U1_GND" from=".U1 > .pin1" to="net.GND" />
<trace name="U1_V3_3" from=".U1 > .pin2" to="net.V3_3" />
<copperpour connectsTo="net.GND" layer="inner1" />
<copperpour connectsTo="net.V3_3" layer="inner2" />
</board>

Only source-only traces whose net names match fanoutPourNetMap receive plane terminations. fanoutRoutingLayers controls the layers available to the other fanout connections; keep those signal-routing layers separate from dedicated planes.

automaticPoursEnabled is not a substitute for this mapping. It generates implicit copper after routing but does not tell the autorouter that a package pin should terminate on a plane. See <board /> and <copperpour />.

Reroute Existing Traces​

The reroute API is for changing routes produced by an earlier pass. Most phased-routing use cases do not need it.

Reroute a Region​

Add a later phase with reroute and a rectangular region. The phase uses the routes from previous phases, extracts connections that cross the region, and replaces the route inside that rectangle.

The custom autorouter in this example returns a squiggly line so the rerouted right half of each trace is easy to see.

import { createSquigglyAutorouter } from "./demo-autorouter"

export default () => (
<board width="18mm" height="12mm">
<testpoint name="T1" pcbX={-7} pcbY={3} padDiameter="0.8mm" />
<testpoint name="T2" pcbX={7} pcbY={3} padDiameter="0.8mm" />
<testpoint name="M1" pcbX={-7} pcbY={0} padDiameter="0.8mm" />
<testpoint name="M2" pcbX={7} pcbY={0} padDiameter="0.8mm" />
<testpoint name="B1" pcbX={-7} pcbY={-3} padDiameter="0.8mm" />
<testpoint name="B2" pcbX={7} pcbY={-3} padDiameter="0.8mm" />

<autoroutingphase
reroute
region={{
shape: "rect",
minX: 0,
maxX: 8,
minY: -5,
maxY: 5,
}}
autorouter={{
algorithmFn: createSquigglyAutorouter,
}}
/>

<trace from="T1.pin1" to="T2.pin1" />
<trace from="M1.pin1" to="M2.pin1" />
<trace from="B1.pin1" to="B2.pin1" />
</board>
)
PCB Circuit Preview

The reroute phase does not need traces assigned to it. Only routes crossing the rectangle from x=0 to x=8 and y=-5 to y=5 are reconsidered.

Reroute Selected Connections​

Combine reroute with connection or connections to reroute specific connections instead of a region. Previously routed traces remain in place and are treated as obstacles.

import { createSquigglyAutorouter } from "./demo-autorouter"

export default () => (
<board width="18mm" height="12mm">
<testpoint name="T1" pcbX={-7} pcbY={3} padDiameter="0.8mm" />
<testpoint name="T2" pcbX={7} pcbY={3} padDiameter="0.8mm" />
<testpoint name="M1" pcbX={-7} pcbY={0} padDiameter="0.8mm" />
<testpoint name="M2" pcbX={7} pcbY={0} padDiameter="0.8mm" />
<testpoint name="B1" pcbX={-7} pcbY={-3} padDiameter="0.8mm" />
<testpoint name="B2" pcbX={7} pcbY={-3} padDiameter="0.8mm" />

<autoroutingphase phaseIndex={0} />
<autoroutingphase
phaseIndex={1}
reroute
connection="M1.pin1"
autorouter={{
algorithmFn: createSquigglyAutorouter,
}}
/>

<trace from="T1.pin1" to="T2.pin1" routingPhaseIndex={0} />
<trace from="M1.pin1" to="M2.pin1" routingPhaseIndex={0} />
<trace from="B1.pin1" to="B2.pin1" routingPhaseIndex={0} />
</board>
)
PCB Circuit Preview
<autoroutingphase
phaseIndex={1}
reroute
connection="M1.pin1"
/>

Use connections to target more than one previously routed connection:

<autoroutingphase
phaseIndex={1}
reroute
connections={["M1.pin1", "B1.pin1"]}
/>

Route bus lanes without layer changes​

Use autorouter="bus_lanes" on <autoroutingphase /> to route selected bus connections on a fixed layer. Select connections by a port at either endpoint; connections chooses existing connections and does not create electrical traces. Use <trace /> or component connections to declare connectivity.

const footprint = "bga36_grid6x6_p1mm_w6mm_h6mm_pad0.5mm_circularpads"
const pinPairs = [[5, 2], [10, 9], [17, 14], [22, 21], [29, 26], [34, 33]]
const lanes = pinPairs.map(([sourcePin, targetPin], i) => ({
name: "DATA" + i,
from: "U1.pin" + sourcePin,
to: "U2.pin" + targetPin,
}))

export default () => (
<board width={24} height={14} minTraceWidth={0.15}>
<chip name="U1" footprint={footprint} pcbX={-6} />
<chip name="U2" footprint={footprint} pcbX={6} />
{lanes.map(({ name, from, to }) => (
<trace key={name} name={name} from={from} to={to} />
))}
<autoroutingphase
name="DATA_LANES"
autorouter="bus_lanes"
connections={lanes.map(({ from }) => from)}
/>
<bus
name="DATA"
connections={lanes.map(({ name }) => name)}
maxLengthSkew="0.05mm"
pcbTraceWidth="0.15mm"
/>
</board>
)
PCB Circuit Preview

Six pads spread across multiple rows and interior columns on each 36-pin BGA form the bus; the other 30 pads on each chip remain unconnected. Routes weave between unused pads and add meanders to match lengths within 0.05 mm. All stay on the top layer because their pads can route directly. With the integrated bus-lanes pipeline, unrouted component pads receive local dogbones when needed to reach a permitted signal layer. The interconnect itself never adds vias. The <bus /> props supply the width and length-skew tolerance. The object form autorouter={{ preset: "bus_lanes" }} is also supported.

For controller-to-RAM routing, either start at the package pads or supply two non-overlapping fanouts with space between their exits. Corresponding exits must share a routing layer, and their winding order must permit a crossing-free connection. The bus-lanes phase preserves the exact fanout copper and routes the gaps between exits. Later global routing receives the completed bus traces as fixed copper; unassigned connections route afterward.

Local dogbones are automatic only for unrouted component-pad endpoints that need to reach the signal layer. Existing fanout exits are used directly and are never dogboned again. Incompatible exit layers or an unsatisfiable planar route produce a routing error, with no fallback to a multilayer router. Fix the fanout layers, winding order, placement, or available routing space before retrying.

Length matching includes the planar lengths of prior fanout traces and the new bus routes. Via depth and package delay are not included. Declare coupled pairs with <differentialpair />, using maxLengthSkew and pcbTraceGap for pair constraints. Check final connectivity, clearances, and end-to-end skew; a successful solve is not complete DDR timing verification.

See AM3352-to-DDR3 routing for the complete TSX, routed layer previews, power escapes, and required core integration. Hosted evaluators may not yet include these integrated features.