pcb-crossing-optimizer 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pcb_crossing_optimizer-0.4.0/PKG-INFO +122 -0
- pcb_crossing_optimizer-0.4.0/README.md +106 -0
- pcb_crossing_optimizer-0.4.0/pyproject.toml +35 -0
- pcb_crossing_optimizer-0.4.0/setup.cfg +4 -0
- pcb_crossing_optimizer-0.4.0/src/crossing_analyzer.py +1333 -0
- pcb_crossing_optimizer-0.4.0/src/pcb_crossing_optimizer.egg-info/PKG-INFO +122 -0
- pcb_crossing_optimizer-0.4.0/src/pcb_crossing_optimizer.egg-info/SOURCES.txt +9 -0
- pcb_crossing_optimizer-0.4.0/src/pcb_crossing_optimizer.egg-info/dependency_links.txt +1 -0
- pcb_crossing_optimizer-0.4.0/src/pcb_crossing_optimizer.egg-info/entry_points.txt +2 -0
- pcb_crossing_optimizer-0.4.0/src/pcb_crossing_optimizer.egg-info/top_level.txt +1 -0
- pcb_crossing_optimizer-0.4.0/tests/test_crossing_analyzer.py +810 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pcb-crossing-optimizer
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Multi-layer crossing minimization for PCB connector pin assignment
|
|
5
|
+
Author: Asher Garland
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ashergarland/pcb-crossing-optimizer
|
|
8
|
+
Project-URL: Repository, https://github.com/ashergarland/pcb-crossing-optimizer
|
|
9
|
+
Keywords: pcb,kicad,eda,skidl,crossing,routing,pin-assignment
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# PCB Crossing Optimizer
|
|
18
|
+
|
|
19
|
+
Multi-layer crossing minimization for PCB connector pin assignment. Detects trace crossings in SKiDL-generated KiCad netlists and computes optimal pin orderings for single-layer routing using Sugiyama-style barycenter sweep.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
pip install pcb-crossing-optimizer
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
After installation, the `pcb-crossing-optimizer` command is available on your PATH.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
The tool has two subcommands: `analyze` (default) and `plan-footprint`.
|
|
32
|
+
|
|
33
|
+
### analyze (default)
|
|
34
|
+
|
|
35
|
+
Analyze crossings between component layers. This is the original behavior and remains the default when no subcommand is given.
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
pcb-crossing-optimizer [analyze] <netlist.net> --layers "L0_refs | L1_refs | L2_refs" --reorderable REF [REF ...] [--exclude REF:PIN ...] [--json] [--quiet]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Analyze the microSD breakout with passives in the middle layer:
|
|
42
|
+
```
|
|
43
|
+
pcb-crossing-optimizer examples/microsd_breakout.net --layers "J1 | R1,R2,C1 | J2" --reorderable J2 --exclude J1:SH
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Simple two-connector case (just use two layers):
|
|
47
|
+
```
|
|
48
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
JSON output for tooling integration:
|
|
52
|
+
```
|
|
53
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2 --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Quiet mode for CI (exit code 0 = no crossings, 1 = crossings remain):
|
|
57
|
+
```
|
|
58
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2 --quiet
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### plan-footprint
|
|
62
|
+
|
|
63
|
+
Compute an optimal pin map for a custom footprint. Given a target component (whose footprint you are designing), fixed anchor components, and optional pin locks, it runs the crossing sweep and produces a complete pin-to-net assignment proposal.
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
pcb-crossing-optimizer plan-footprint <netlist.net> \
|
|
67
|
+
--target J1 \
|
|
68
|
+
--anchors "J2,U1 | R1,R2,R3,C1" \
|
|
69
|
+
--lock 1=NC 2=NC 3=GND_EARLY_A \
|
|
70
|
+
--unmatched end \
|
|
71
|
+
--exclude-nets GND \
|
|
72
|
+
[--json] [--quiet]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Options:
|
|
76
|
+
- `--target REF`: Component whose footprint is being designed
|
|
77
|
+
- `--anchors "..."`: Fixed components organized in layers separated by `|`
|
|
78
|
+
- `--lock PIN=NET`: Lock specific pins to nets (use `PIN=NC` for no-connect)
|
|
79
|
+
- `--unmatched start|end|split`: Where to place pins with no anchor connections (default: `end`)
|
|
80
|
+
- `--exclude-nets NET [NET ...]`: Nets to exclude from analysis (e.g. ground pours)
|
|
81
|
+
|
|
82
|
+
Nets spanning non-adjacent layers (e.g., J1 to J2 through a passive layer)
|
|
83
|
+
are handled automatically via virtual pass-through nodes.
|
|
84
|
+
|
|
85
|
+
## How it works
|
|
86
|
+
|
|
87
|
+
1. Parses a KiCad .net file (S-expression format generated by SKiDL)
|
|
88
|
+
2. Extracts pin-to-net connectivity for specified components
|
|
89
|
+
3. Sugiyama-style barycenter sweep across all layers:
|
|
90
|
+
- Inserts virtual nodes for long edges spanning non-adjacent layers
|
|
91
|
+
- Reorders both pins within reorderable components and components within layers
|
|
92
|
+
- Iterates forward/backward sweeps until convergence
|
|
93
|
+
4. Reports current crossings, recommended reordering, and remaining crossings
|
|
94
|
+
|
|
95
|
+
## Project structure
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
src/crossing_analyzer.py Core logic + CLI
|
|
99
|
+
tests/ pytest tests
|
|
100
|
+
examples/ Sample netlists for testing
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Running tests
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
pip install pytest
|
|
107
|
+
pytest -v
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Roadmap
|
|
111
|
+
|
|
112
|
+
- Passive placement optimizer (assign positions to resistors/caps in routing channel)
|
|
113
|
+
- F.Cu/B.Cu layer assignment for unavoidable crossings
|
|
114
|
+
- Migration to skidl-vscode extension (core/crossing.py + MCP tool + VS Code command)
|
|
115
|
+
|
|
116
|
+
## Python import
|
|
117
|
+
|
|
118
|
+
The PyPI package name is `pcb-crossing-optimizer`, but the importable module is `crossing_analyzer`:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from crossing_analyzer import sweep_optimize, PinColumn, format_multilayer_report
|
|
122
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# PCB Crossing Optimizer
|
|
2
|
+
|
|
3
|
+
Multi-layer crossing minimization for PCB connector pin assignment. Detects trace crossings in SKiDL-generated KiCad netlists and computes optimal pin orderings for single-layer routing using Sugiyama-style barycenter sweep.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pip install pcb-crossing-optimizer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
After installation, the `pcb-crossing-optimizer` command is available on your PATH.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
The tool has two subcommands: `analyze` (default) and `plan-footprint`.
|
|
16
|
+
|
|
17
|
+
### analyze (default)
|
|
18
|
+
|
|
19
|
+
Analyze crossings between component layers. This is the original behavior and remains the default when no subcommand is given.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
pcb-crossing-optimizer [analyze] <netlist.net> --layers "L0_refs | L1_refs | L2_refs" --reorderable REF [REF ...] [--exclude REF:PIN ...] [--json] [--quiet]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Analyze the microSD breakout with passives in the middle layer:
|
|
26
|
+
```
|
|
27
|
+
pcb-crossing-optimizer examples/microsd_breakout.net --layers "J1 | R1,R2,C1 | J2" --reorderable J2 --exclude J1:SH
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Simple two-connector case (just use two layers):
|
|
31
|
+
```
|
|
32
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
JSON output for tooling integration:
|
|
36
|
+
```
|
|
37
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2 --json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Quiet mode for CI (exit code 0 = no crossings, 1 = crossings remain):
|
|
41
|
+
```
|
|
42
|
+
pcb-crossing-optimizer examples/i2c_breakout.net --layers "J1 | J2" --reorderable J2 --quiet
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### plan-footprint
|
|
46
|
+
|
|
47
|
+
Compute an optimal pin map for a custom footprint. Given a target component (whose footprint you are designing), fixed anchor components, and optional pin locks, it runs the crossing sweep and produces a complete pin-to-net assignment proposal.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
pcb-crossing-optimizer plan-footprint <netlist.net> \
|
|
51
|
+
--target J1 \
|
|
52
|
+
--anchors "J2,U1 | R1,R2,R3,C1" \
|
|
53
|
+
--lock 1=NC 2=NC 3=GND_EARLY_A \
|
|
54
|
+
--unmatched end \
|
|
55
|
+
--exclude-nets GND \
|
|
56
|
+
[--json] [--quiet]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
- `--target REF`: Component whose footprint is being designed
|
|
61
|
+
- `--anchors "..."`: Fixed components organized in layers separated by `|`
|
|
62
|
+
- `--lock PIN=NET`: Lock specific pins to nets (use `PIN=NC` for no-connect)
|
|
63
|
+
- `--unmatched start|end|split`: Where to place pins with no anchor connections (default: `end`)
|
|
64
|
+
- `--exclude-nets NET [NET ...]`: Nets to exclude from analysis (e.g. ground pours)
|
|
65
|
+
|
|
66
|
+
Nets spanning non-adjacent layers (e.g., J1 to J2 through a passive layer)
|
|
67
|
+
are handled automatically via virtual pass-through nodes.
|
|
68
|
+
|
|
69
|
+
## How it works
|
|
70
|
+
|
|
71
|
+
1. Parses a KiCad .net file (S-expression format generated by SKiDL)
|
|
72
|
+
2. Extracts pin-to-net connectivity for specified components
|
|
73
|
+
3. Sugiyama-style barycenter sweep across all layers:
|
|
74
|
+
- Inserts virtual nodes for long edges spanning non-adjacent layers
|
|
75
|
+
- Reorders both pins within reorderable components and components within layers
|
|
76
|
+
- Iterates forward/backward sweeps until convergence
|
|
77
|
+
4. Reports current crossings, recommended reordering, and remaining crossings
|
|
78
|
+
|
|
79
|
+
## Project structure
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
src/crossing_analyzer.py Core logic + CLI
|
|
83
|
+
tests/ pytest tests
|
|
84
|
+
examples/ Sample netlists for testing
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Running tests
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
pip install pytest
|
|
91
|
+
pytest -v
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Roadmap
|
|
95
|
+
|
|
96
|
+
- Passive placement optimizer (assign positions to resistors/caps in routing channel)
|
|
97
|
+
- F.Cu/B.Cu layer assignment for unavoidable crossings
|
|
98
|
+
- Migration to skidl-vscode extension (core/crossing.py + MCP tool + VS Code command)
|
|
99
|
+
|
|
100
|
+
## Python import
|
|
101
|
+
|
|
102
|
+
The PyPI package name is `pcb-crossing-optimizer`, but the importable module is `crossing_analyzer`:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from crossing_analyzer import sweep_optimize, PinColumn, format_multilayer_report
|
|
106
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pcb-crossing-optimizer"
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Multi-layer crossing minimization for PCB connector pin assignment"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [{ name = "Asher Garland" }]
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
keywords = ["pcb", "kicad", "eda", "skidl", "crossing", "routing", "pin-assignment"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/ashergarland/pcb-crossing-optimizer"
|
|
23
|
+
Repository = "https://github.com/ashergarland/pcb-crossing-optimizer"
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
pcb-crossing-optimizer = "crossing_analyzer:main"
|
|
27
|
+
|
|
28
|
+
[tool.setuptools]
|
|
29
|
+
py-modules = ["crossing_analyzer"]
|
|
30
|
+
|
|
31
|
+
[tool.setuptools.packages.find]
|
|
32
|
+
where = ["src"]
|
|
33
|
+
|
|
34
|
+
[tool.pytest.ini_options]
|
|
35
|
+
testpaths = ["tests"]
|