DSL for reverse engineering using KiCad
quality 4/10 · average
0 net
Tags
# revsch
`revsch` is a Python tool for turning a small reverse-engineering DSL into a KiCad schematic.
The DSL supports two closely related workflows:
- schematic-style capture: declare parts, pins, and named nets explicitly
- probe-first mapping: capture continuity quickly with `X -> Y, Z` traces, batch-generated parts, and sparse pin metadata
The output is a valid `.kicad_sch` file that opens in KiCad and can be refined there by swapping symbols, improving layout, and adding drawing detail.
For standard generic parts, the emitter now prefers official KiCad library symbols. For custom and unknown parts, it falls back to embedded generated symbols so the schematic remains self-contained.
## Install and Run
This project uses `uv`.
```bash
uv run revsch lint examples/basic_minimal.revsch
uv run revsch compile examples/basic_minimal.revsch -o ~/tmp/basic_minimal.kicad_sch
```
Useful commands:
```bash
uv run revsch lint input.revsch
uv run revsch lint --mapping-mode input.revsch
uv run revsch compile input.revsch -o output.kicad_sch
uv run revsch compile --mapping-mode input.revsch -o output.kicad_sch
uv run revsch compile input.revsch -o output.json --output-format json
uv run revsch dump-ir input.revsch
uv run revsch dump-json input.revsch
uv run revsch format input.revsch
```
## DSL Overview
Supported statement types:
- `part REFDES ...`
- `pin REFDES.PIN ...`
- `net NAME = REFDES.PIN, REFDES.PIN`
- `alias ALT = NET`
- `property TARGET KEY = VALUE`
- `note TARGET = VALUE`
- `PREFIX key=value ...`
Used for batch generation, for example `IC name=PLA pincount=16 count=6`
- `A -> B, C, D`
Used for fast probe mapping
Comments start with `#`. Quoted strings are supported.
### `` Batch Part Syntax
`part REFDES ... count=N [start=S]` generates multiple identical parts.
`` is replaced with an index for each generated part.
`start` sets the first index (default `0`).
For example, `part ENC count=2 start=1` creates `ENC1` and `ENC2`.
Subsequent `pin`, `net`, `property`, `note`, and trace statements
using `` in the reference designator expand across all generated parts.
## Schematic-Style Example
```text
part U1 kind=IC value="STM32F103C8" package=LQFP48
pin U1.24 name=VDD type=power_in
pin U1.32 name=PA11 type=bidirectional
pin U1.33 name=PA12 type=bidirectional
part J1 kind=CONN value="USB-C" package=USB_C_16
pin J1.A6 name=D+
pin J1.A7 name=D-
net VCC_3V3 = U1.24
net USB_D+ = U1.33, J1.A6
net USB_D- = U1.32, J1.A7
alias +3V3 = VCC_3V3
```
## Probe-First Mapping Example
This is the fast capture workflow for tracing a board with a continuity probe.
```text
IC name=PLA pincount=16 count=6
C count=10
R count=5
J name=EDGE pincount=44 count=1
J1.1 -> +5V
J1.2 -> C1, R3, IC1.3
C1 -> GND
R3 -> GND
```
Behavior:
- `IC name=PLA pincount=16 count=6` creates `IC1` through `IC6`, each with 16 pins
- `C count=10` creates `C1` through `C10` with two pins each
- `J1.2 -> C1, R3, IC1.3` creates one net containing `J1.2`, one implicit pin from `C1`, one implicit pin from `R3`, and explicit pin `IC1.3`
- bare net names such as `+5V` or `GND` become canonical net names
- if no net name appears in a trace statement, an automatic net name is created
## Sparse Capture
For reverse engineering, most pin metadata can be omitted:
```text
part U1
pin U1.6
pin U1.7
net ROW0 = U1.6
net COL0 = U1.7
```
If a pin has no explicit `name`, the emitter falls back to the pin ID so the generated symbol is still usable.
## Mapping Mode
`--mapping-mode` is intended for probe capture, where many pins are still untraced.
It suppresses warnings that are usually noise during early reverse engineering:
- missing `value`
- missing `package`
- unused pins
- single-member nets
It does not suppress structural errors such as undeclared pins, duplicate parts, or conflicting net assignments.
## No-Connect Handling
Pins explicitly marked as no-connect emit real KiCad `no_connect` markers:
```text
property U1.35 status=nc
```
Pins marked this way do not produce unused-pin warnings.
## Symbol Strategy
The emitter uses two symbol strategies.
Official KiCad library symbols are used for common standard parts:
- resistor -> `Device:R_Small`
- capacitor -> `Device:C_Small`
- inductor / coil -> `Device:L_Small`
- diode -> `Device:D`
- LED -> `Device:LED`
- crystal -> `Device:Crystal`
- 2-pin switch -> `Switch:SW_SPST`
- 3-pin switch -> `Switch:SW_SPDT`
Embedded generated symbols are used for:
- ICs
- connectors that do not map cleanly to a stock symbol
- unknown parts
- anything else without a supported stock mapping
This keeps standard parts recognizable in KiCad while preserving a self-contained fallback for reverse-engineered or custom devices.
## JSON Output
There are two JSON export paths:
- `dump-json`
Exports the parsed DSL statement structure
- `dump-ir`
Exports the normalized internal representation used for validation and emission
- `compile --output-format json`
Writes the parsed DSL statement structure to a file
Example:
```bash
uv run revsch dump-json examples/mapping_probe.revsch
uv run revsch dump-ir examples/mapping_probe.revsch
uv run revsch compile examples/mapping_probe.revsch -o ~/tmp/mapping_probe.json --output-format json
```
`dump-json` and `compile --output-format json` are useful if another tool wants to consume the DSL without reimplementing the parser.
## Examples
See [`examples/README.md`](file:///home/ryanm/workspace/kicad_dsl/examples/README.md) for the full example index.
Included examples:
- [`examples/basic_minimal.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/basic_minimal.revsch)
- [`examples/metadata_and_aliases.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/metadata_and_aliases.revsch)
- [`examples/sparse_reverse_capture.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/sparse_reverse_capture.revsch)
- [`examples/mapping_probe.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/mapping_probe.revsch)
- [`examples/mapping_probe_named_nets.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/mapping_probe_named_nets.revsch)
- [`examples/esp_keyboard.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/esp_keyboard.revsch)
- [`examples/ch579m_key12_v02.revsch`](file:///home/ryanm/workspace/kicad_dsl/examples/ch579m_key12_v02.revsch)
## Status
Current implementation includes:
- parser and semantic validation
- KiCad `.kicad_sch` emission
- deterministic UUID and symbol generation
- mapping-mode warning profile
- source-level and IR-level JSON exports
- pytest coverage for parser, semantics, emitter, and CLI