Skip to content

Implement gen_schematic for KiCad 8 and 9#281

Closed
lachlanfysh wants to merge 1 commit intodevbisme:masterfrom
lachlanfysh:feature/kicad8-gen-schematic
Closed

Implement gen_schematic for KiCad 8 and 9#281
lachlanfysh wants to merge 1 commit intodevbisme:masterfrom
lachlanfysh:feature/kicad8-gen-schematic

Conversation

@lachlanfysh
Copy link

@lachlanfysh lachlanfysh commented Feb 11, 2026

Summary

  • Leverages work in PR 270 by cyberhuman as a basis for change.
  • Replaces the stub gen_schematic.py for kicad8 and kicad9 (currently prints "not implemented") with a working hierarchical schematic generator
  • Generates one .kicad_sch per @subcircuit plus a root sheet with hierarchical sheet symbols

What it does

Given a SKiDL circuit with @subcircuit blocks, produces:

root.kicad_sch              ← root sheet with hierarchical sheet symbols
root_power1.kicad_sch       ← one sheet per @subcircuit
root_mcu1.kicad_sch
root_sensors1.kicad_sch
...

Each subcircuit sheet contains:

  • Library symbol definitions extracted from SKiDL Part draw_cmds
  • Symbol instances with correct lib_id, properties, footprints, UUIDs
  • Proper hierarchical instance paths for KiCad's project tree

Key design decisions

  • Uses simp_sexp.Sexp for S-expression output (already a SKiDL dependency)
  • Stable UUIDs via uuid5 — regenerating the same circuit produces the same UUIDs
  • Grid-based placement — components are arranged in a 4-column grid (functional but basic; better placement could follow as a separate enhancement)
  • Same implementation for kicad8 and kicad9 — the .kicad_sch format is identical between versions

Test plan

  • Tested with 363-part hierarchical design (8 @subcircuit blocks)
  • KiCad ERC: 0 errors (453 warnings for intentionally unconnected pins)
  • Verified SVG export via kicad-cli sch export svg
  • Combined with net label injection (PR Add net label injection for generated schematics #280) for readable output
  • Could benefit from unit tests

Context

Addresses #68 (Export to Eeschema Schematic) and #188 (Generate schematics for newer versions of KiCad).

🤖 Generated with Claude Code

Replaces the stub gen_schematic.py (which returned "not implemented")
with a working implementation that generates hierarchical KiCad
schematics from SKiDL circuits.

Features:
- Generates one .kicad_sch per @Subcircuit, plus a root sheet with
  hierarchical sheet symbols linking them
- Extracts library symbol definitions from SKiDL Part draw_cmds data
- Produces correct symbol instances with lib_id, properties, UUIDs
- Handles arbitrary nesting depth via recursive hierarchy traversal
- Generates stable UUIDs using uuid5 for reproducible output
- Auto-exports custom Part fields (manufacturer, MPN, etc.)
- Supports A3 page size with grid-based component placement

Tested with a 363-part circuit across 8 subcircuit sheets, producing
correct netlists verified by KiCad ERC (0 errors).

Applies to both kicad8 and kicad9 tools (same schematic format).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@devbisme
Copy link
Owner

Thanks for doing this! I'll test it out and then do a merge and a new release.

Would this also work for KiCad 6 and 7?

@lachlanfysh
Copy link
Author

lachlanfysh commented Feb 12, 2026 via email

@cyberhuman
Copy link

Hi! Thank you for your work!
I've noticed it's based on my previous draft PR #270. It would be nice if the original authorship was mentioned.

@IUIULC
Copy link

IUIULC commented Feb 13, 2026

Hello, Doctor!We've conducted a preliminary verification of your submitted fix and confirmed that the generated KICAD9 schematic can be opened normally. However, it appears the connection lines and network labels for cross-level schematics were not processed. Is this an issue to be addressed in future enhancements?

@IUIULC
Copy link

IUIULC commented Feb 14, 2026

Currently, does KICAD5's automatic layout and routing logic not yet support KICAD9?

@devbisme
Copy link
Owner

I looked at the code for this PR and it doesn't appear to use the placement or routing information that is used when generating KiCad 5 schematics. I ran an example circuit through it and the components are arranged in a grid with no wiring. It does, however, generate a valid KiCad 9 schematic even if it isn't very pretty.

It says the code for this PR was generated using Claude Code. By coincidence, I also used Claude Code last week to try and add support for generating schematics in KiCad 6. My code used the placement and routing information but the scaling was off as shown in this example:
image
My code doesn't support hierarchy and a few other things that this PR implements. I believe we can get to a workable solution by merging them. I'll give that a try. My code is in the sexp_schematics branch so others are free to try as well.

In case anyone is using Claude Code to do this, here is the prompt I used for my code:

Code for generating a KiCad 5 schematic is in src/skidl/tools/kicad5/gen_schematic.py. KiCad 6 changed the schematic file format to use S-expressions. Write code for generating a KiCad 6 schematic in src/skidl/tools/kicad6/gen_schematic.py.

@lachlanfysh
Copy link
Author

Hey, it is possible this is because I broke up the code changes I made into multiple PRs and that could have produced some functional gaps when only this single PR is committed... I will aim to get back to this in the next ~48hr and do more testing but essentially I have sought to do three things:

  1. Upgrade to Kicad 9 - When I first did this it did draw wires between components but with zero regard for other wires, so it caused a lot of crossing of wires and unintentional net ties - it was a rats nest and looked like my early hand drawn PCBs :)
  2. I then got it to move away from actually connecting via wires and to use net flags - this is in another PR not this one and looking at your comment I'm now realising that they probably don't work in isolation. That other PR may not be perfect as it uses net flags almost exclusively and that doesn't make sense - sometimes actually drawing the wires is better, but I still felt it was a better starting draft schematic for me when done that way.
  3. Per your comment about the placement in a grid - yes that is the behaviour with this PR, but I have another not yet committed change where it does a post processing step to re-arrange in a way that is logical to the circuit (e.g. Power together).. I didn't commit this as it was a secondary script not the original py script and I wanted to do more thinking about whether than was the appropriate architecture vs trying to push it into the single script. It seems to work though and creates a draft that is easier for me to follow and take through to completion, vs the grid which is pretty annoying as a starting place.

@devbisme
Copy link
Owner

In my opinion, the algorithms for placement and routing belong in the code files stored in src/skidl/schematics. Then these can be used for generating schematics for any version of KiCad or even SVG.

lachlanfysh pushed a commit to lachlanfysh/skidl that referenced this pull request Feb 17, 2026
Merges work from three separate branches into a single unified
implementation using SKiDL's existing placement/routing infrastructure:

- New shared module: schematics/sexp_schematic.py
  Recursive hierarchy walker (following kicad5 node_to_eeschema pattern),
  coordinate system correction (Y-flip), deterministic UUIDs, lib_symbol
  extraction from draw_cmds, wire/junction/net-label generation, custom
  field export, and hierarchical sheet references.

- kicad6/kicad8 gen_schematic.py: thin wrappers (~227 lines each)
  preprocess_circuit (with deg_to_orient pin normalization) -> SchNode ->
  place -> route -> write_top_schematic. Only difference is version number.

- kicad9 gen_schematic.py: re-exports from kicad8 (identical format).

- bboxes.py (kicad6/8/9): replaced broken 249-line versions with working
  pin-based bbox calculation (~101 lines each).

- inject_labels.py: retained as standalone CLI post-processor utility.

Sources: upstream/sexp_schematics (devbisme), feature/kicad8-gen-schematic
(PR devbisme#281), feature/inject-net-labels (PR devbisme#280). Credit: cyberhuman (PR devbisme#270).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lachlanfysh
Copy link
Author

Superseded by #282 which merges this branch's hierarchy/custom fields work with PR #280 (net labels) and upstream's sexp_schematics branch into a single unified implementation.

@lachlanfysh
Copy link
Author

@cyberhuman Your work on #270 is credited in the new unified PR #282 — both in the source code header of sexp_schematic.py and the PR description. Thanks for getting this started!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants