Controlled Impedance
Zeo computes characteristic impedance (Z₀), differential impedance (Z_diff), and insertion loss for routed traces directly from the board stackup. This is not an external field solver or manual calculator. Impedance is a derived property: change the stackup, layer, width, or gap and the displayed values update everywhere.
Requirements
Impedance is computed from stackup geometry, so the stackup must be real:
- At least one dielectric layer with a relative permittivity (Dk) above 1.0. Without it, impedance displays are blank and the impedance DRC skips silently.
- Layer and dielectric thicknesses defined in Board Setup → Physical Stackup.
Transmission-line models
The model is selected automatically per track from its layer and surroundings:
| Model | When used | Reports |
|---|---|---|
| Microstrip | Single-ended trace on an outer layer (F.Cu/B.Cu) over a reference plane | Z₀ |
| Stripline | Single-ended trace on an inner layer between planes | Z₀ |
| Coupled microstrip | Differential pair on an outer layer | Z_diff |
| Coupled stripline | Differential pair on an inner layer | Z_diff |
| Coplanar (CPW) | Trace with ground copper alongside on the same layer, no back plane | Z₀ (CPW) |
| Grounded coplanar (CPWG) | Coplanar with a reference plane below | Z₀ (CPW) |
Selection logic, in order:
- Differential pair — if the track's net has a coupled partner (from schematic diff-pair naming) with a same-layer segment nearby, the coupled model is used and the edge-to-edge gap is measured from the board. Pair assignment is automatic; there is no manual pairing step.
- Coplanar — if ground copper (zones or ground/power tracks) flanks the trace on both sides within a proximity window, a coplanar model is used. By default the side gap must be within 3× the trace width (capped at 4× the substrate height) and roughly symmetric; the thresholds are tunable in advanced config. Reference copper is identified structurally from power pins and zones, not by net name.
- Single-ended — otherwise microstrip (outer layers) or stripline (inner layers).
Alongside impedance, the calculator reports insertion loss (dB/in) split into conductor loss — with skin effect and surface-roughness correction — and dielectric loss from the stackup's loss tangent.
Signal-integrity parameters
Board-wide analysis parameters live in Board Setup → Board Stackup → Impedance:
| Parameter | Default | Notes |
|---|---|---|
| Reference frequency | 1 GHz | Frequency at which impedance and loss are evaluated. Controls skin depth and dispersion. |
| Dk specified at frequency | 1 GHz | The frequency your stackup's Dk/Df values were measured at (from the laminate datasheet). |
| Conductor resistivity | 1.72 µΩ·cm | Copper at 20 °C. |
| Copper surface roughness | 0 µm | RMS foil roughness; increases conductor loss (Hammerstad–Jensen). 0 = smooth foil. |
Dielectric constants are not treated as frequency-flat: a Djordjevic–Sarkar wideband-Debye model translates the Dk/Df you entered at the measurement frequency to the reference frequency, matching the behavior of commercial SI tools.
Per-net impedance targets are not set here — they are DRC rules; see Impedance DRC.
Where impedance appears
- Track properties dialog — select a track and open its properties to see Z₀ (or Z_diff / Z₀ (CPW)) and total insertion loss. Values update live as you change the layer or width. The fields are read-only: impedance is derived, not set.
- Router overlay — while routing interactively, the status overlay shows
Z₀ = N Ω(orZ_diff = N Ωin differential-pair mode) plus loss, updating as you change layer and width. The differential gap comes from the router's diff-pair settings. - Net Inspector — an Average Impedance column shows each net's impedance averaged over its routed length, model-aware per segment.
- Agent — the same computed values are available to the agent via
pcb_get_netsandpcb_inspect(see From the agent).
Impedance DRC
Set per-net impedance targets with the impedance_target constraint in custom DRC rules (Board Setup → Custom Rules, stored in the project's .kicad_dru). Values are in ohms:
(version 1)
(rule "USB 90R differential"
(condition "A.inDiffPair('*USB_D*')")
(constraint impedance_target (min 81) (max 99)))
(rule "RF feed 50R"
(condition "A.NetClass == 'RF'")
(constraint impedance_target (min 45) (max 55)))
During DRC each routed track is checked against the matching rule: differential pairs against the differential target, all other models against Z₀. Out-of-range tracks report DRCE_IMPEDANCE_OUT_OF_RANGE with the computed and target values. The check is skipped entirely when the stackup defines no dielectric constants.
From the agent
Configure:
pcb_setupconfigures everything impedance depends on:physical_stackup(includingimpedance_controlledand per-dielectricepsilon_r/loss_tangent/ thickness),signal_integrity(reference frequency, Dk measurement frequency, conductor resistivity, surface roughness),tuning_profiles, andcustom_rulesforimpedance_targetrules.generate_net_classescreates differential-pair-aware net classes whose widths and gaps the impedance calculator then evaluates.
Read back computed impedance:
pcb_get_netswithinclude_impedance=trueattaches each routed net's model-aware average impedance (Z_diff for differential pairs, CPW Z₀ for coplanar, otherwise Z₀) and insertion loss.pcb_inspectsection="nets"lists nets with their average impedance;section="net_impedance"withfilter="<net>"returns the per-track breakdown (model, Z₀/Z_diff, loss per segment).
Both report a stackup_has_dk flag — when false, the stackup defines no dielectric constants and no impedance can be computed.