Use when taking a power-supply or analog-circuit idea all the way from LTspice simulation to a verifiable KiCad project (schematic + PCB + footprints + ERC/DRC). Covers ADI/LTC µModule demo-board adaptation, ASC → KiCad conversion, BGA functional-pad footprints, 4-layer stackup conversion, input protection hardening, datasheet-driven pin verification, kicad-cli-driven verification, and the structural ASC ↔ KiCad netlist cross-check. Companion to any project-specific LTspice skill — use that one for simulation, this one for everything between sim and a clean DRC pass. Out of scope: gerber generation as an acceptance artifact, certification/compliance, mechanical/thermal proof, custom IC design.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ltspice-to-kicad-workflow:ltspice-to-kicad-workflowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
End-to-end recipe for going from a circuit idea through LTspice validation
End-to-end recipe for going from a circuit idea through LTspice validation
to a KiCad project that loads cleanly, passes ERC and DRC under kicad-cli,
and is honest about what is verified vs. inferred. Distilled from a 48V →
5V → 1V/10A two-stage µModule design (LTM8064 + LTM4658) and the bugs
that surfaced along the way.
Trigger this skill when the user:
.asc (or wants to create one) for an analog / power
circuit and intends to fabricate a board..asc topology..kicad_pcb.If the user is only doing simulation work (no PCB), hand off to whatever LTspice-only skill they already have. If they want gerbers, certification, or thermal/mechanical analysis, those are out of scope.
1. Idea / specs → V_in, V_out, I_load, transient targets
2. Part selection → ADI / LTC µModule catalog, demo-board match
3. LTspice schematic → copy demo values; add load; .tran startup
4. Sim validation → vbus_avg, vcore_avg, iload_avg within tol
5. KiCad generation → symbols, footprints, sch, pcb, netlist
6. Hardening pass → cap V ratings, input protection, layer count,
real footprints
7. kicad-cli verification → erc, drc (--refill-zones --save-board),
jumper-strip drc gate, netlist re-export
8. Structural cross-check → netlist_comparison.py (ASC ↔ KiCad nets)
9. Document deferred work → README + drc.rpt / erc.rpt match reality
Each stage below lists the artefacts to produce, the gotchas to avoid, and the verification check that gates moving to the next stage.
Pin down before touching tools:
For high-current rails write down the load resistance you'll simulate
with (V_out / I_load, e.g. 1V / 10A = 0.1 Ω) — this is the Rload that
must be deleted from the PCB later.
For ADI/LTC µModules:
Conventions that pay off downstream:
C8064_OUT1, R4658_FB_TOP. This carries through as the KiCad
ASC_REF property and makes the netlist cross-check trivial.V1 for the input — it becomes the
input connector J1 on the PCB.Rload, value 0.1). It is for sim only..save, .tran startup, and at least three .meas lines:
.meas TRAN vbus_avg AVG V(BUS5) FROM=0.7m TO=1m
.meas TRAN vcore_avg AVG V(OUT1V) FROM=0.7m TO=1m
.meas TRAN iload_avg AVG I(Rload) FROM=0.7m TO=1m
V=6.3 Rser=5m) are the
values that will get carried over to the PCB BOM. They are usually
too tight — the demo board uses 6.3V rated parts on 5V rails because
the demo isn't a product. Note these for the hardening pass.Two passes:
.tran 1m startup, just confirm convergence and no
model errors.vbus_avg, vcore_avg,
iload_avg against spec; ±2% is typical.Save the validation .asc separately (don't overwrite the source) so
the "this design simulates to spec" evidence is traceable.
The artefacts you need:
*.kicad_pro, *.kicad_sch, *.kicad_pcb (project, schematic, board)<lib>.kicad_sym with symbol definitions for each unique part<lib>.pretty/<footprint>.kicad_mod for any custom footprints (the
µModule BGAs typically)sym-lib-table, fp-lib-table listing the local libs + any KiCad
standard libs the project uses (Capacitor_SMD, Resistor_SMD,
Diode_SMD, Fuse, TestPoint, TerminalBlock_Phoenix)Decisions to make up front:
duplicate_pad_numbers_are_jumpers yes
on the footprint. Review-grade only — the result is NOT fabricable.
The jumper flag asserts the component itself bridges same-numbered
pads, so DRC passes with no physical copper between them (the rev A
reference board hid 94 unconnected pads this way — every GND return,
the 10A output, both feedback balls). The Stage 7 jumper-strip gate
exposes this.Six checks. Walk them every time.
Aim for ≥2× the DC working voltage on MLCC, more if you care about de-rating under DC bias. Bulk caps need transient margin too.
Common mistakes inherited from demo boards:
Rload (the load resistor) must come out of:
schematic.net exportKeep it in the ASC if you want re-runnable simulation evidence.
For 48V inputs add (at minimum):
| Part | Footprint | Net wiring |
|---|---|---|
| F1 | Fuse:Fuse_1206_3216Metric | series J1 → F1 → IN48 |
| D1 | Diode_SMD:D_SMB (SMBJ58A) | K=IN48, A=GND |
| C8 | Capacitor_SMD:CP_Elec_10x10 | + = IN48, − = GND, 22µF/100V |
A new net IN48_RAW sits between J1 and F1; everything else stays on
IN48. Update the symbol library if you didn't have a Fuse or D_TVS
symbol — examples in references/protection_symbols.kicad_sym.
In the PCB (layers …) block, add inner layers between F.Cu and B.Cu.
Use this exact form (signal type, IDs in the free even-number range):
(layers
(0 "F.Cu" signal)
(4 "In1.Cu" signal)
(6 "In2.Cu" signal)
(2 "B.Cu" signal)
; … user layers unchanged
)
Do not use power as the layer type — KiCad 10's PCB loader rejects
it with a generic "Failed to load board" error.
For each via, the (layers …) field is start-layer end-layer, NOT a
list of every layer touched. A through-via stays (layers "F.Cu" "B.Cu")
even on a 4-layer board; the copper rings on inner layers are implicit.
Writing (layers "F.Cu" "In1.Cu" "In2.Cu" "B.Cu") makes the file
unloadable.
Add these zones (declare polygons, skip (filled_polygon …) — let
kicad-cli pcb drc --refill-zones --save-board compute them):
In1.Cu / GND / full-board rectangleIn2.Cu / GND / full-board rectangle (priority 0 — gets overridden by
power islands)In2.Cu / IN48 / island enclosing input components, priority 1In2.Cu / BUS5 / island enclosing stage 1 output, priority 2In2.Cu / OUT1V / island enclosing stage 2 output, priority 3Replace any "functional pads" / "review" footprint with the datasheet-accurate one:
duplicate_pad_ numbers_are_jumpers merges them with the same-name balls. Removing
them silently breaks ~17 same-net connections per part.If you renamed a net (e.g. IN48 → IN48_RAW for the section ahead of the fuse), update all four places:
label "IN48_RAW" on the J1-side wire)(net "…") field on J1.1schematic.net)This is the difference between "looks right" and "actually loads".
$cli = 'C:\Program Files\KiCad\10.0\bin\kicad-cli.exe'
$proj = '<path to project>'
# Hard checks
& $cli sch erc --severity-error --output "$proj\erc.rpt" "$proj\*.kicad_sch"
& $cli pcb drc --refill-zones --save-board --severity-error `
--output "$proj\drc.rpt" "$proj\*.kicad_pcb"
# Regenerate the netlist
& $cli sch export netlist --output "$proj\schematic.net" "$proj\*.kicad_sch"
# Optional: broader inspection
& $cli pcb drc --schematic-parity --severity-all `
--output "$proj\drc_full.rpt" "$proj\*.kicad_pcb"
Expectation after the hardening pass: 0 ERC errors, 0 DRC errors,
0 unconnected pads — and 0 unconnected items in the jumper-strip run
below, if it applies. Schematic-parity warnings about stale Value /
ASC_REF strings on inline PCB footprints are cosmetic; the user can
clear them with Tools → Update PCB from Schematic in the GUI. Treat
net_conflict parity warnings as real until each one is individually
read — they can hide pad-number swaps (see pitfalls table).
duplicate_pad_numbers_are_jumpers)Normal DRC is blind to missing copper on these footprints: the jumper flag asserts the component bridges same-numbered pads even when the "bridge" pads lie outside the package body. Test the physical copper by stripping the flag from a copy of the board:
$strip = "$proj\drc_strip_check.kicad_pcb"
$text = Get-Content "$proj\<project>.kicad_pcb" -Raw
$text = $text -replace '(?m)^[ \t]*\(duplicate_pad_numbers_are_jumpers yes\)[ \t]*\r?\n', ''
# UTF-8 WITHOUT BOM — Set-Content writes a BOM and KiCad then fails
# with "Failed to load board"
[System.IO.File]::WriteAllText($strip, $text, [System.Text.UTF8Encoding]::new($false))
& $cli pcb drc --refill-zones --output "$proj\drc_strip.rpt" $strip
Remove-Item $strip # or it gets swept up by later *.kicad_pcb wildcards
The unconnected-items count in drc_strip.rpt is the physical-copper
truth. The rev A reference board passed normal DRC clean and showed
94 unconnected pads here (all GND returns, the 10A output, both
feedback balls). Anything non-zero means the board relies on virtual
bridging and is not fabricable — go back to Stage 5 and build scheme 2
footprints. On a scheme-2 board the flag doesn't exist and this gate is
a no-op.
If pcb drc fails with "Failed to load board" and no line number,
work backward through the recent edits — most often the via (layers …)
mistake from 6d, or a layer type other than signal / user. Bisect
by reverting commits or by progressively removing recent additions.
Behavioral sim says "the values work." Structural check says "the KiCad net topology matches the ASC." Both are needed because either can silently break without the other noticing.
validation/netlist_comparison.py (template in
references/netlist_comparison.py):
SYMATTR InstName lines to enumerate the ASC's components.schematic.net for component refs and net
membership.EXPECTED_ASC_TO_KICAD map (ASC name → KiCad ref) and
EXPECTED_NETS table (key nets → expected member refs) to do the
comparison.KICAD_ONLY_REFS set for KiCad-only additions (J1
replacing V1, J2/J3 monitors, TP1–TP9, F1/D1/C8 protection).Do not try to parse LTspice net connectivity geometrically — the ASC format requires symbol library pin offsets that aren't reliably shipped with the project. The hardcoded expected-net table is the honest approach.
If something can't be auto-checked here, write it down. README sections that pay off:
kicad-cli invocations, the numerical
results, and the date / KiCad version.| Symptom | Cause | Fix |
|---|---|---|
kicad-cli pcb drc → "Failed to load board" | Via (layers …) lists all 4 layers instead of start/end | Revert to (layers "F.Cu" "B.Cu") for through-vias |
| Same error after layer-type change | Used power or mixed instead of signal / user in (layers …) | Use only signal or user |
| 17+ unconnected pads after BGA footprint "cleanup" | Removed perimeter fan-out rectangles | Restore them; they're bridging copper, not visual decor |
| DRC reports clearance violations on existing pads after refill | Stale filled_polygon from before the recent additions | Run pcb drc --refill-zones --save-board once |
| "Via dangling" warnings on new vias inside an inner-layer zone | Zone fill hasn't anchored to the via | Cosmetic; F.Cu zone of same net provides the load-bearing path |
| 259 schematic-parity warnings on Value / ASC_REF mismatches | PCB inline footprint properties stale vs. schematic | Tools → Update PCB from Schematic in the GUI |
Netlist comparison flags IN48_RAW missing | Forgot to update one of: schematic label, PCB pad net, schematic.net, expected-table | Update all four |
ERC reports 100+ endpoint_off_grid warnings | Generator emitted pins on a non-100mil grid | Filter with --severity-error; the warnings are cosmetic |
Schematic-parity net_conflict warnings dismissed as net-name noise | Real pad-number swaps buried in the noise (rev A: J1/J2/J3 power and GND pads swapped vs. schematic pins, under 199 net-name-prefix warnings) | Sync net-name forms (/NET vs NET) first, then re-read every remaining net_conflict individually |
project_root/
├─ <project>.kicad_pro
├─ <project>.kicad_sch
├─ <project>.kicad_pcb
├─ <project>.kicad_prl
├─ <lib>.kicad_sym
├─ <lib>.pretty/
│ ├─ <bga1>.kicad_mod
│ └─ <bga2>.kicad_mod
├─ sym-lib-table
├─ fp-lib-table
├─ schematic.net ; KiCad-exported, do not hand-edit if possible
├─ erc.rpt ; from kicad-cli sch erc --severity-error
├─ drc.rpt ; from kicad-cli pcb drc --refill-zones --save-board
├─ README.md ; verification log, limitations, deferred work
└─ validation/
├─ <project>_validation.asc ; extended .tran for measurements
├─ ltspice_validation_summary.md ; sim numbers + cross-check approach
└─ netlist_comparison.py ; ASC ↔ KiCad structural diff
references/netlist_comparison.py — template for stage 8references/protection_symbols.kicad_sym — Fuse + D_TVS symbol snippetsreferences/four_layer_zones.kicad_pcb_snippet — In1.Cu / In2.Cu zone declarationskicad-cli subcommand surfaceWhen this skill finishes, the user should have:
kicad-cli.erc.rpt and drc.rpt documenting 0 errors and 0 unconnected pads
(plus drc_strip.rpt if any footprint carries the jumper flag).validation/ directory whose Python script passes against the
project's own ASC.Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub swangneu/ltspice-to-kicad-workflow --plugin ltspice-to-kicad-workflow