D145 — KiCad 10 tuning profiles: KiCad's width rules, and per-layer widths by narrowing¶
Context¶
Doc 18 B1 (M21): KiCad 10 projects can give a net class a tuning profile, with a track width and pair gap per signal layer, and KiCad's
DRC then requires those widths when the project sets tuning_profile_track_geometries to a severity other than ignore. The engine
read none of it, and its router has one width per net (doc 15 §15). The format and KiCad's rule were taken from KiCad 10.0's sources
(common/project/tuning_profiles.cpp, pcbnew/drc/drc_engine.cpp) and its QA projects, and checked against kicad-cli 10.0.6.
Design: doc 05 §58. Records: bench/records/m21-b1/.
Decision¶
read_design_rulesreadstuning_profilesand each class'stuning_profile(model::TuningProfile,DesignRules::profile_of). It adds KiCad's implicit rules (CustomRule::implicit) in KiCad's place, before the custom rules, carrying the severity oftuning_profile_track_geometries,ignoreincluded:- per profiled layer, an exact
track_width, withA.inDiffPair('*')added for a differential profile; - for pairs, an exact
diff_pair_gap.
The rules have KiCad's name ("tuning profile 'NAME'"), so the engine's DRC and KiCad's report the same violation.
- Where KiCad 10.0.6's behaviour differs from its source, the engine follows the behaviour (doc 05 §58):
- The severity of track_width comes from the last matching rule, so an ignored profile rule hides the board minimum.
- hasExactNetclass is evaluated only in implicit rules; in a user's rule KiCad never matches it.
- The coupled-pair clearance at the profile's gap applies to the two halves' tracks only (NetClass::tuning_pair_gap), not to a
track against the partner's pads. KiCad's AB.isCoupledDiffPair() clearance rule is not added.
- Routing, whatever the severity (a profile is the designer's statement of the impedance):
- A single-ended profile's nets route at the widest of its widths. After routing, each track is narrowed to its layer's width,
judged like the other after-route passes.
- A differential profile's pairs route at one layer's width and gap, preferring a layer the class's SMD pads are on, then the
geometry most layers share. A disallow track rule keeps them off layers with another width or gap.
- Width and pair-gap rules do not switch the router to exact checks (they set no clearance).
- --json has tuning_profiles, and the log has a line per profile; a class naming an undefined profile is warned about.
- The delays (per layer, per via, time-domain tuning) are read but not used: they are B2's.
Alternatives¶
- Per-layer width inside the router. About twenty call sites of the router take one width per net (clearance disks, via codes, escape stubs, caches keyed by width); changing all of them is a large, risky change for a gain that narrowing gives for single nets.
- Route at the most common width, and keep other layers clear (also for single-ended nets). Correct, but it gives up layers. On boards whose inner layers are narrower, the nets would lose the inner layers entirely.
- Narrow pairs too. A pair's centrelines stay where they are, so narrowing widens its gap by the width removed; KiCad's exact gap rule would then fail on those layers.
- Apply the profile only when KiCad would check it. Then the router's tracks would differ from the designer's stated impedance just because the check is off; the widths are the design either way.
- Follow KiCad's source rather than its behaviour (evaluate
hasExactNetclasseverywhere, relax the pads to the profile's gap). The judge iskicad-cli: on RoyalBlue that gave three addedclearanceerrors, and the parity corpus would disagree on two cases.
Consequences¶
- Classes without a profile, and projects without profiles, are unchanged: the reader adds nothing and the route job does nothing.
- Pairs with a profile route on fewer layers when the profile's layers disagree.
- Single-ended nets keep the clearance of their widest layer on every layer. That is conservative on the narrower layers.
- Measured (
bench/records/m21-b1, KiCad 10.0.6 with the check aterror): no added KiCad error on two plane-tier boards given profiles. On RoyalBlue, 68 inner tracks are narrowed, and routing with the single-ended profile alone is the same as without profiles (125/147). The USB pair profile costs five connections (120/147). - The parity corpus has four new cases, and all 220 match KiCad.
- No real board with profiles was available; the Kookabus boards are still missing (doc 18 §7).
- Found afterwards (B2, same night; D147): the fixtures' net settings were at schema 4, which KiCad migrates by giving every class an
empty profile, so the "no added KiCad error" above was measured by a KiCad that checked no profile. Rejudged at schema 5, three fixes
followed (Default's profile inherited, the pair width from a single-ended profile, no neck-down on profiled nets). Results with those
fixes: plane_smd 48/49 with no added error; RoyalBlue 102/147 with the single-ended profile and 104/147 with both. Both have no width
error, and the second has 5
diff_pair_gap_out_of_rangeerrors at the USB-C connector. "Narrowing is free" does not hold (doc 05 §58,bench/records/m21-b1/runs/b1-v5). - Docs: 05 §58, 18 §15, 11 (M21 row).