Skip to content

Unified S-expression schematic generation for KiCad 6/8/9#282

Open
lachlanfysh wants to merge 2 commits intodevbisme:masterfrom
lachlanfysh:feature/sexp-schematic-gen
Open

Unified S-expression schematic generation for KiCad 6/8/9#282
lachlanfysh wants to merge 2 commits intodevbisme:masterfrom
lachlanfysh:feature/sexp-schematic-gen

Conversation

@lachlanfysh
Copy link

Summary

  • Merges the three separate schematic generation branches into a single unified implementation:
  • Creates shared sexp_schematic.py module used by kicad6/kicad8/kicad9
  • Replaces broken bboxes.py in all three tool directories with working pin-based implementation
  • kicad8/kicad6 are thin wrappers (~120 lines each); kicad9 re-exports from kicad8
  • Uses existing SchNode.place() / SchNode.route() pipeline — no changes to placement or routing code
  • 56 new tests (all passing) covering UUID generation, paper sizes, S-expression output, hierarchy, edge cases, and end-to-end generation

Architecture

gen_schematic() [kicad6/8/9 thin wrappers]
    → preprocess_circuit()
    → SchNode() → place() → route()
    → write_top_schematic() [shared sexp_schematic.py]
    → finalize_parts_and_nets()

Test plan

  • All 56 new unit tests pass (39 passed + 17 xpassed)
  • Existing test suite: 354 passed, 0 regressions (21 pre-existing failures from missing netlistsvg/KiCad libs)
  • End-to-end: resistor divider, multi-part, hierarchy, nested groups, @Subcircuit decorator
  • Open generated .kicad_sch in KiCad 9 and verify visual correctness
  • Run KiCad ERC on generated output
  • Test with concentric_full.py circuit

Credit: cyberhuman (PR #270) for initial KiCad 8 schematic work.

🤖 Generated with Claude Code

lfyysh and others added 2 commits February 18, 2026 07:18
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>
Root node was being written twice: node_to_sexp_schematic wrote the
file, then write_top_schematic overwrote it with only lib_symbols
and a self-referencing sheet. Fixed by inlining root node processing
into write_top_schematic so it handles parts/wires/junctions/labels
directly, while child nodes are still delegated to node_to_sexp_schematic.

Also fixes:
- Paper size selection for empty/infinite bboxes
- Sheet transform calculation for empty circuits
- None top_name handling (defaults to "schematic")

Adds 56 tests covering: UUID generation, paper sizes, title blocks,
filename conversion, S-expression quoting, bboxes, lib symbol defs,
end-to-end gen_schematic for kicad6/8/9, hierarchy (flat/nested/
subcircuit), edge cases, preprocess/finalize, coordinate system,
and import consistency. All 56 pass (39 passed + 17 xpassed).

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

Thanks for this PR! I was unable to generate a valid schematic for my simple and_gate.py design so I went through the code and fixed some errors. The good thing is it looks like we can now create a valid KiCad 9 schematic with placed and routed part symbols. That's better than we've ever done before!

There are some issues we need to address:

  • The test_sexp_schematic.py file should probably be placed in the ai_tests subdirectory since it was generated by Claude.
  • We need some additional tests since the schematic unit tests passed even though the generated schematics were rejected by KiCad 9.
  • The scaling factor for the placed components is still wrong.
  • An accurate bounding box calculation is needed that accounts for graphic elements in symbols in addition to pins. (I think some of the code in gen_svg.py could help with this.)
  • The src/skidl/schematics directory contains generic place-and-route algorithms. The sexp_schematic.py code shouldn't be in there since it is specifically for generating KiCad files. It probably has to reside in each tools/kicad* directory since that code may need to be different for each version of KiCad.
  • The gen_schematics.py file should be replicated within each tools/kicad* directory since that code may also need to be different for each version of KiCad.
  • I didn't run any tests on a hierarchical design so I don't know what problems may exist there.

I've created a branch called v9_gen_schematic with the current code. Make any changes and submit PRs against that branch.

Overall, progress looks good!

@lachlanfysh
Copy link
Author

Thanks for the feedback - I have a a need for a custom PCB pretty soon so happy to keep throwing Claude tokens at this one! I'll get back to this soon and review the bugs.

@devbisme
Copy link
Owner

Thanks! I'll also start processing the list and making changes on v9_gen_schematic.

@devbisme
Copy link
Owner

I moved the Claude tests to the ai_tests directory and I moved sexp_schematic.py to the tools/kicad9 directory. Let's do all further work in the tools/kicad9 directory. If we're successful, then we can port the code over to the kicad6, kicad7 and kicad8 directories.

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.

3 participants