spice2wireviz/README.md
Ryan Malloy 95ed08866c Add verbose flag, WireViz dev dep, and rendered diagram examples
- Gate model/value heuristic output behind --verbose/-v flag (quiet by default)
- Add wireviz>=0.4 as dev dependency for roundtrip render tests
- Generate SVG/PNG diagram renders for inter_module, single_module, hierarchical
- Embed rendered diagrams in README with layout optimization callout
2026-02-13 09:19:18 -07:00

363 lines
9.9 KiB
Markdown

# spice2wireviz
Convert LTspice SPICE netlists to WireViz wiring diagrams.
## What it does
`spice2wireviz` reads SPICE netlist files (`.net`, `.cir`, `.sp`) and LTspice schematics (`.asc`) and generates [WireViz](https://github.com/wireviz/WireViz) YAML that documents the physical wiring: connectors, test points, and inter-module cables.
Two operating modes:
- **Single module** -- External interface of one subcircuit (its connectors, test points, port interface)
- **Inter-module** -- How multiple subcircuits/boards connect to each other
It also produces **Bill of Materials** output as CSV, and includes layout optimization to minimize cable crossings in rendered diagrams.
## Install
```bash
uv tool install spice2wireviz
# or
pip install spice2wireviz
```
For `.asc` file metadata extraction (optional):
```bash
pip install spice2wireviz[asc]
```
## Quick start
```bash
# Inter-module wiring (auto-detected from top-level X instances)
spice2wireviz top_level.net -o wiring.yml
# Single module external interface
spice2wireviz design.net -s amplifier_board -o amp.yml
# Render to SVG/PNG/HTML (requires WireViz installed)
spice2wireviz design.net -o wiring.yml --render --format sph
# Component bill of materials
spice2wireviz design.net --bom
# Wiring bill of materials (cables, wire counts, endpoints)
spice2wireviz top_level.net --bom-wiring
```
## Rendered diagrams
### Inter-module wiring
How multiple boards/modules connect to each other — power supply, amplifier, and I/O board with shared power and signal routing:
![Inter-module wiring diagram](docs/examples/inter_module.png)
### Single-module interface
External interface of one subcircuit — the amplifier board's connectors and test points radiating from a central port header:
![Single-module wiring diagram](docs/examples/single_module.png)
### Hierarchical system
A complex multi-level system with voltage regulator, main board, sensor module, and external connectors:
![Hierarchical wiring diagram](docs/examples/hierarchical.png)
These diagrams are generated automatically by piping `spice2wireviz` output through WireViz (`--render` flag). The layout optimizer minimizes cable crossings — notice how parallel wires between the same module pair are bundled into multi-wire cables.
## Output examples
### Input: SPICE netlist
A multi-board system with power supply, amplifier, and I/O board:
```spice
.subckt power_supply VCC GND
J1 AC_IN AC_GND AC_INLET
.ends power_supply
.subckt amplifier VIN GND VOUT
J1 VIN GND INPUT_CONN
TP1 VOUT
.ends amplifier
.subckt io_board SIG_IN SIG_OUT GND CTRL
J1 SIG_IN SIG_OUT DB9_CONN
J2 CTRL GND CTRL_CONN
.ends io_board
* Top-level instantiation
X1 VCC GND power_supply
X2 VCC GND AUDIO_OUT amplifier
X3 AUDIO_OUT CTRL_SIG GND ENABLE io_board
* Top-level connectors
J_CHASSIS GND EARTH chassis_gnd
TP_VCC VCC
```
### Output: Inter-module WireViz YAML
```bash
spice2wireviz multi_board.net
```
```yaml
metadata:
title: 'Wiring diagram: multi_board'
source: multi_board.net
generator: spice2wireviz 2026.2.14
connectors:
J_CHASSIS:
type: chassis_gnd
pinlabels:
- EARTH
- GND
notes: 'SPICE ref: J_CHASSIS'
TP_VCC:
type: TP
style: simple
pinlabels:
- VCC
notes: 'SPICE ref: TP_VCC'
X1:
type: power_supply
pinlabels:
- VCC
- GND
notes: 'SPICE instance: X1 (power_supply)'
X2:
type: amplifier
pinlabels:
- VIN
- GND
- VOUT
notes: 'SPICE instance: X2 (amplifier)'
X3:
type: io_board
pinlabels:
- GND
- SIG_IN
- SIG_OUT
- CTRL
notes: 'SPICE instance: X3 (io_board)'
cables:
W1:
colors:
- BK
wirelabels:
- GND
W3:
colors:
- RD
wirelabels:
- VCC
W5:
category: bundle
colors:
- BK
- RD
wirelabels:
- GND
- VCC
W8:
wirecount: 1
wirelabels:
- AUDIO_OUT
connections:
- - TP_VCC: 1
- W3: 1
- X1: 1
- - X1: [2, 1]
- W5: [1, 2]
- X2: [2, 1]
- - X2: 3
- W8: 1
- X3: 2
```
Every connector includes a `notes` field tracing back to the original SPICE reference or instance. Ground wires are colored black (`BK`), power wires red (`RD`). Parallel wires between the same module pair are grouped into multi-wire cables (like `W5` above).
### Output: Single-module WireViz YAML
```bash
spice2wireviz simple_board.net -s amplifier_board
```
```yaml
connectors:
amplifier_board:
type: Module Interface
pinlabels:
- VIN
- GND
- VOUT
- SIGNAL_IN
notes: 'SPICE subcircuit: .subckt amplifier_board'
J1:
type: PWR_CONN
pinlabels:
- VIN
- GND
J2:
type: SIG_CONN
pinlabels:
- VOUT
- SIGNAL_IN
TP1:
type: TP
style: simple
pinlabels:
- N001
cables:
W_J1:
category: bundle
colors: ['', BK]
wirelabels: [VIN, GND]
W_J2:
category: bundle
wirecount: 2
wirelabels: [VOUT, SIGNAL_IN]
connections:
- - amplifier_board: [1, 2]
- W_J1: [1, 2]
- J1: [1, 2]
- - amplifier_board: [3, 4]
- W_J2: [1, 2]
- J2: [1, 2]
```
Single-module mode generates a central "module header" connector representing the subcircuit's port interface, with star-topology cables radiating out to each boundary component (J*, TP*, P*).
### Output: Component BOM
```bash
spice2wireviz simple_board.net --bom
```
```csv
Reference,Prefix,Value,Pins,Subcircuit,Attributes
J1,J,PWR_CONN,2,amplifier_board,
J2,J,SIG_CONN,2,amplifier_board,
TP1,TP,,1,amplifier_board,
```
Component BOM lists all boundary components (connectors, test points) with their reference, value, pin count, and which subcircuit they belong to. Works even on `.asc` files without connectivity data.
### Output: Wiring BOM
```bash
spice2wireviz multi_board.net --bom-wiring
```
```csv
Cable,Wirecount,Nets,From,To
W1,1,GND,J_CHASSIS,X1
W3,1,VCC,TP_VCC,X1
W5,2,"GND, VCC",X1,X2
W6,1,GND,X1,X3
W8,1,AUDIO_OUT,X2,X3
```
Wiring BOM lists every cable with wire count, net names, and connected endpoints. Useful for generating cut lists and wire pull schedules.
## Inspection commands
Preview what's in a netlist before generating diagrams:
```bash
# List subcircuit definitions
$ spice2wireviz multi_board.net --list-subcircuits
amplifier: ports=[VIN, GND, VOUT], boundary_components=2
io_board: ports=[SIG_IN, SIG_OUT, GND, CTRL], boundary_components=2
power_supply: ports=[VCC, GND], boundary_components=1
# Dry run (connector/cable/connection counts)
$ spice2wireviz multi_board.net --dry-run
Mode: inter
Connectors: 5
Cables: 5
Connection sets: 5
Connector names: J_CHASSIS, TP_VCC, X1, X2, X3
```
## Filtering
Cherry-pick what appears in the diagram:
```bash
--include-prefixes J,TP # Only these component types (default: J,TP,P,X)
--exclude-prefixes X # Hide subcircuit modules
--exclude-refs X3,J_DEBUG # Hide specific references
--include-nets "SIG_*" # Glob patterns for net names
--exclude-nets "*_DEBUG" # Exclude debug nets
--no-ground # Hide GND connections
--no-power # Hide VCC/VDD connections
--no-group # Don't bundle parallel wires into multi-wire cables
```
## LTspice .asc support
LTspice `.asc` schematic files are supported with tiered netlist resolution:
1. **Companion netlist** (automatic) -- If a `.net`, `.cir`, or `.sp` file exists alongside the `.asc` (same basename), it's used for full connectivity. LTspice generates these automatically when you run a simulation.
2. **LTspice generation** (opt-in) -- Pass `--generate-netlist` to invoke LTspice and produce a `.net` file. Use `--ltspice-exe` to specify the LTspice binary path if it's not auto-detected.
3. **Metadata only** -- Without a netlist, only component refs/values are available. Diagram generation is blocked, but `--list-components` and `--bom` still work.
```bash
# .asc with companion .net in the same directory
spice2wireviz schematic.asc -s amplifier_board -o amp.yml
# No companion .net -- invoke LTspice to generate one
spice2wireviz schematic.asc --generate-netlist -o wiring.yml
# Specify LTspice binary path (Linux/wine, macOS, Windows)
spice2wireviz schematic.asc --generate-netlist --ltspice-exe /path/to/ltspice
# Component BOM from .asc (no .net required)
spice2wireviz schematic.asc --bom
```
## Layout optimization
Both mappers apply layout optimization to minimize cable crossings in rendered diagrams:
- **Inter-module**: Sugiyama-lite layered graph drawing -- external connectors are placed at the left edge, modules are layered by BFS distance, barycenter ordering reduces crossings, and pins are reordered to group connections to the same neighbor.
- **Single-module**: Star topology optimization -- boundary components are ordered by their connection pattern to the module header, header pins are grouped by target component, and pin sequences are parallelized.
This is automatic and requires no configuration.
## How it works
```
.net/.cir/.sp ─────┐
├─→ Parser ─→ ParsedNetlist ─→ Filters ─→ Mapper ─→ WireViz YAML
.asc (+ companion) ┘ │ │
│ └─→ Wiring BOM CSV
└─→ Component BOM CSV
```
The parser extracts subcircuit definitions (`.subckt`), instances (`X*`), and boundary components (`J*`, `TP*`, `P*`) from SPICE netlists. Filters remove unwanted elements. The mapper converts the remaining structure into WireViz connector/cable/connection format. The emitter serializes to deterministic YAML (byte-identical output for identical input) or CSV.
## Development
```bash
uv sync --extra dev --extra asc
uv run pytest # 194 tests
uv run ruff check src/ tests/
```
LTspice integration tests require LTspice installed and are marked:
```bash
uv run pytest -m ltspice # Run only LTspice tests
uv run pytest -m "not ltspice" # Skip LTspice tests (CI default)
```
## Repository
[git.supported.systems/warehack.ing/spice2wireviz](https://git.supported.systems/warehack.ing/spice2wireviz)