Skip to content

drandyhaas/KiCadRoutingTools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

724 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KiCadRoutingTools

KiCad Routing Tools

A fast Rust-accelerated A* autorouter for KiCad PCB files. Available as both a KiCad Plugin with full GUI and a Command-Line Interface for scripting and automation.

Routed PCB example Routed PCB example 2

Features

  • Grid-based A* pathfinding with Rust acceleration (~10x faster than Python)
  • Octilinear routing - Horizontal, vertical, and 45-degree diagonal moves
  • Multi-layer routing with automatic via insertion
  • Differential pair routing with pose-based A* and Dubins path heuristic for orientation-aware centerline routing
  • Rip-up and reroute - When routing fails, automatically rips up blocking routes and retries with progressive N+1 strategy (tries 1 blocker, then 2, up to configurable max). Re-analyzes blocking tracks after each failure for better recovery. Also triggers rip-up when quick probes detect blocking early, before attempting full routes.
  • Ripped route corridor avoidance - When a net is ripped up, soft penalties are applied to its former corridor. This encourages the current route to avoid that area, increasing the chance the ripped net can be successfully re-routed later.
  • Blocking analysis - Shows which previously-routed nets are blocking when routes fail
  • Stub layer switching - Optimization that moves stubs to different layers to avoid vias when source/target are on different layers. Works for both differential pairs and single-ended nets. Finds compatible swap pairs (two nets that can exchange layers to help each other) or moves stubs solo when safe. Tries multiple swap options (source/source, target/target, source/target, target/source) to find valid combinations. Validates that stub endpoints won't be too close to other stubs on the destination layer.
  • Batch routing with incremental obstacle caching (~7x speedup)
  • Net ordering strategies - MPS (crossing conflicts with diff pairs treated as units, shorter routes first using BGA-aware distance; uses segment intersection with MST for non-BGA boards), inside-out (BGA), or original order
  • MPS layer swap - When MPS detects crossing conflicts (nets in Round 2+), attempts layer swaps to eliminate same-layer crossings. Tries swapping both the conflicting Round 2 unit and Round 1 unit. Re-runs MPS after swaps to verify conflict resolution
  • BGA exclusion zones - Auto-detected from footprints, prevents vias under BGAs
  • Stub proximity avoidance - Penalizes routes near unrouted stubs, with direction-aware costs (moving away from stubs costs less)
  • BGA proximity avoidance - Penalizes routes near BGA edges, with direction-aware costs (moving away from BGA zones costs less)
  • Track proximity avoidance - Penalizes routes near previously routed tracks on the same layer, encouraging spread-out routing
  • Vertical track alignment - Attracts tracks on different layers to stack vertically (on top of each other), consolidating routing corridors and leaving more room for through-hole vias
  • Adaptive setback angles - Evaluates 9 setback angles (0°, ±max/4, ±max/2, ±3max/4, ±max) and selects the one that maximizes separation from neighboring stub endpoints, improving routing success when stubs are tightly spaced. Uses 0° when clearance to the nearest stub is sufficient (≥2× spacing), only angling away when stubs are too close
  • U-turn prevention - Prevents differential pair routes from making U-turns (>180° cumulative turn)
  • GND via placement - Automatically places GND vias adjacent to differential pair signal vias for return current paths. The Rust router checks clearance and determines optimal placement (ahead or behind signal vias)
  • Automatic polarity swap - Detects when differential pair P/N polarity differs between source and target pads and automatically swaps target pad net assignments to match. Use --no-fix-polarity to disable
  • Target swap optimization - For swappable nets (e.g., memory lanes), uses Hungarian algorithm to find optimal source-to-target assignments that minimize crossings. Works for both differential pairs and single-ended nets
  • Schematic synchronization - When --schematic-dir is specified, updates KiCad schematic files with any pad swaps (target swaps or polarity swaps) to keep schematics in sync with PCB. Handles multi-unit symbols correctly by updating all schematic files containing the lib_symbol. Disabled by default
  • Chip boundary crossing detection - Uses chip boundary "unrolling" to accurately detect route crossings for MPS ordering and target swap optimization
  • Turn cost penalty - Penalizes direction changes during routing to encourage straighter paths with fewer wiggles
  • Bus routing - Automatically detects groups of nets with clustered endpoints (buses) and routes them together. Uses direction-based attraction so each net follows its neighbor's path in parallel, creating clean parallel traces. Routes from the middle of the bus outward, alternating sides. Enable with --bus flag. Configurable detection radius, attraction radius, and attraction bonus
  • Length matching - Adds trombone-style meanders to match route lengths within groups (e.g., DDR4 byte lanes). Auto-groups DQ/DQS nets by byte lane. Per-bump clearance checking with automatic amplitude reduction to avoid conflicts with other traces. Supports multi-layer routes with vias. Calculates via barrel length from board stackup for accurate length matching that matches KiCad's measurements. Includes stub via barrel lengths (BGA pad vias) using actual stub-layer-to-pad-layer distance
  • Time matching - Alternative to length matching that matches propagation delay instead of physical length. Accounts for different signal speeds on outer layers (microstrip, faster) vs inner layers (stripline, slower) using effective dielectric constants from the board stackup. Use --time-matching to enable. Tolerance specified in picoseconds
  • Multi-point routing - Routes nets with 3+ pads using an MST-based 3-phase approach: (1) compute MST between all pads and route the longest edge, (2) apply length matching, (3) route remaining MST edges in length order (longest first). This ensures length-matched routes are clean 2-point paths while connecting all pads optimally
  • Impedance-controlled routing - Specify target impedance (e.g., 50Ω single-ended, 100Ω differential) and track widths are automatically calculated per layer from the board stackup. Uses IPC-2141 formulas for microstrip (outer layers) and stripline (inner layers). Widths adjust automatically when switching layers via vias to maintain target impedance
  • Power net routing - Route power nets (GND, VCC, etc.) with wider tracks than signal nets. Specify patterns and corresponding widths (e.g., --power-nets "*GND*" "*VCC*" --power-nets-widths 0.4 0.5). First matching pattern determines width for each net. Obstacle clearances automatically adjust for wider power traces. Power net widths are never smaller than the base track width
  • Net class support - The KiCad plugin reads net class parameters (track width, via size, clearance) from the board and uses them automatically. Nets can be organized by net class in separate tabs for easier selection. When routing nets from different classes, obstacle clearances properly account for the larger clearance requirements (e.g., routing "Wide" class nets with 0.4mm clearance near "Default" class pads)
  • AI-powered power net analysis - Use the /analyze-power-nets skill to identify power nets and recommend track widths. The skill uses WebSearch to look up component datasheets, classifies components by their role (power source, current sink, pass-through, shunt), traces current paths, and generates ready-to-use --power-nets configurations. See Power Net Analysis for details
  • Power/ground plane via connections - Automatically places vias to connect SMD pads to inner-layer copper planes. Supports multiple nets in one run (e.g., GND and VCC planes). Smart via placement tries pad center first, then spirals outward with A* routing to pads. Optional blocker rip-up removes interfering nets to maximize via placement, with automatic re-routing of ripped nets
  • Multi-net plane layers - Multiple power nets can share a single copper layer using Voronoi partitioning. Each net's vias get their own non-overlapping zone polygon. MST-based routing connects all vias of each net, with routes sampled as additional Voronoi seeds to ensure connected zones. Retries with net reordering when edges fail to route. Displays plane resistance and max current capacity (IPC-2152) for each polygon
  • Disconnected plane region repair - After power planes are created, regions may be effectively split due to vias and traces from other nets cutting through the plane. The route_disconnected_planes.py script detects disconnected regions and routes wide, short tracks between them to ensure electrical continuity
  • GND return via placement - Automatically places GND vias near signal vias for return current paths. Searches from minimum viable distance outward (24 angles, fine step), placing GND vias as close as possible while respecting track clearances. Through-hole GND pads count as existing return paths. Use --add-gnd-vias with route_planes.py
  • AI-powered high-speed net analysis - Use the /find-high-speed-nets skill to identify which nets carry high-speed signals. Looks up component datasheets via WebSearch to find max interface frequencies and rise times, traces signals through series passives, and recommends --gnd-via-distance values based on the fastest signals on the board. See the GND return via distance guidance in the planes documentation

Quick Start

1. Get the Code

# Clone with git
git clone https://github.com/drandyhaas/KiCadRoutingTools.git
cd KiCadRoutingTools

Or download the ZIP and extract it.

2. Install Rust

If you don't have Rust installed, install it from rustup.rs:

# macOS / Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Windows: Download and run rustup-init.exe from https://rustup.rs/

After installation, restart your terminal or run source ~/.cargo/env.

3. Build the Rust Router

python build_router.py

4. Choose Your Interface

Option A: KiCad Plugin (Recommended for interactive use)

# Install the plugin
python install_plugin.py

# Then in KiCad: Tools → External Plugins → KiCadRoutingTools

Option B: Claude Code (AI-assisted routing)

Use Claude Code to analyze your PCB and generate a routing plan:

> /plan-pcb-routing kicad_files/my_board.kicad_pcb

Claude will:

  • Analyze your board structure and identify components needing fanout (BGA/QFN/PGA)
  • Detect differential pairs and DDR signals requiring length matching
  • Identify power/ground nets and recommend plane vs trace routing
  • Assess signal speeds and recommend GND return via placement
  • Generate a step-by-step routing plan with explanations
  • Run the commands and verify results

Other useful skills:

> /find-high-speed-nets kicad_files/my_board.kicad_pcb   # Identify high-speed nets via datasheet lookup
> /analyze-power-nets kicad_files/my_board.kicad_pcb     # Identify power nets and track widths

Option C: Manual Command Line (For scripting and automation)

# Route all nets
python route.py my_board.kicad_pcb

# Route differential pairs
python route_diff.py my_board.kicad_pcb --nets "*lvds*"

# Create power planes
python route_planes.py my_board.kicad_pcb --nets GND --plane-layers B.Cu

KiCad Plugin

The plugin provides a full graphical interface for all routing features, running directly within KiCad 9+.

KiCad Plugin GUI

Installation

# Install the plugin (copies to KiCad plugins directory)
python install_plugin.py

# For development: create symlink instead of copying
python install_plugin.py --symlink

# Remove the plugin
python install_plugin.py --uninstall

The installer automatically detects your KiCad installation directory:

  • macOS: ~/Documents/KiCad/9.0/3rdparty/plugins/
  • Linux: ~/.local/share/kicad/9.0/3rdparty/plugins/
  • Windows: ~/Documents/KiCad/9.0/3rdparty/plugins/

Usage

  1. Open KiCad 9.0 or later
  2. Open a PCB in Pcbnew
  3. Go to Tools → External Plugins → KiCadRoutingTools
  4. Configure routing parameters and select nets to route
  5. Click Route to run the router

Plugin Tabs

Basic Tab:

  • Net selection with filtering and component filtering
  • Option to separate nets by net class (organizes into tabs per class)
  • Track width, clearance, via size/drill from net class or manual override
  • Layer selection with per-layer cost multipliers
  • Options: stub layer swaps, copper text moving, teardrops, power net widths, no-BGA zones

Advanced Tab:

  • Swappable nets configuration for target swap optimization
  • Routing parameters: iterations, heuristic weight, rip-up, probe iterations
  • MPS ordering options, direction control, length matching
  • Proximity settings: BGA, stub, track, via proximity costs
  • Debug options

Differential Tab:

  • Differential pair selection with filtering
  • Pair gap, turning radius, setback angle configuration
  • Options: polarity fix, GND vias, intra-pair length matching

Fanout Tab:

  • BGA fanout with exit margin, escape direction, differential pair support
  • QFN fanout with extension length configuration
  • Net selection for fanout operations

Planes Tab:

  • Net-to-layer assignment for power/ground planes
  • Create planes with via connections to SMD pads
  • Repair disconnected plane regions
  • GND return via placement near signal vias
  • Via size/drill, track width, clearance configuration

Log Tab:

  • Real-time routing output display
  • Color-coded messages (errors, warnings, success)

About Tab:

  • Version information and credits

General Features:

  • Settings persistence (parameters and selections preserved between sessions)
  • Cancel button to stop routing operations mid-progress
  • Results applied directly to the open PCB in KiCad

Command-Line Interface

Net Pattern Syntax

All --nets options support fnmatch-style wildcards and exclusion patterns:

Pattern Description
* All nets
*DATA* Nets containing "DATA"
/* Nets starting with "/" (hierarchical)
Net-(U1-*) Nets matching "Net-(U1-...)"
!GND Exclude net named "GND"
!*VCC* Exclude nets containing "VCC"
"*" "!GND" "!VCC" All nets except GND and VCC

Notes:

  • Exclusion patterns (starting with !) remove matching nets from the result
  • Order matters: include patterns add nets, exclude patterns remove them
  • Nets starting with "unconnected-" are automatically excluded
  • Use quotes around patterns with special characters

Route Nets

# Route all nets (default) - outputs to input_routed.kicad_pcb
python route.py kicad_files/input.kicad_pcb

# Route all nets, overwrite input file
python route.py kicad_files/input.kicad_pcb --overwrite

# Route all nets to a specific output file
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb

# Route specific nets (using --nets option)
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "Net-(U2A-DATA_0)" "Net-(U2A-DATA_1)"

# Route with wildcard patterns
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "Net-(U2A-DATA_*)"

# Route all nets on a component (auto-excludes GND/VCC/VDD/unconnected)
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --component U1

# Route specific patterns on a component (no auto-exclusion)
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "/DDAT*" --component U1

# Route ALL nets on a component including power (use "*" pattern)
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "*" --component U1

# Route all nets except GND and VCC (exclusion patterns with ! prefix)
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "*" "!GND" "!VCC"

# Route differential pairs (use route_diff.py)
python route_diff.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "*lvds*" --no-bga-zones

# Route with wider tracks for power nets
python route.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets "Net*" \
  --power-nets "*GND*" "*VCC*" "+3.3V" --power-nets-widths 0.4 0.5 0.3 --track-width 0.2

# Typical workflow: create GND plane first, then route all signals
python route_planes.py kicad_files/flat_hierarchy.kicad_pcb --nets GND --plane-layers B.Cu
python route.py kicad_files/flat_hierarchy_routed.kicad_pcb --overwrite

3. Create Power/Ground Planes

# Create GND zone on B.Cu with via connections to all GND pads (outputs to input_routed.kicad_pcb)
python route_planes.py kicad_files/input.kicad_pcb --nets GND --plane-layers B.Cu

# Create GND zone, overwrite input file
python route_planes.py kicad_files/input.kicad_pcb --overwrite --nets GND --plane-layers B.Cu

# Create GND zone to specific output file
python route_planes.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb --nets GND --plane-layers B.Cu

# Create multiple planes at once (each net paired with corresponding plane layer)
python route_planes.py kicad_files/input.kicad_pcb --nets GND +3.3V --plane-layers In1.Cu In2.Cu

# Create VCC plane with larger vias
python route_planes.py kicad_files/input.kicad_pcb --nets VCC --plane-layers In2.Cu --via-size 0.5 --via-drill 0.4

# Rip up blocking nets and automatically re-route them
python route_planes.py kicad_files/input.kicad_pcb --nets GND +3.3V --plane-layers In1.Cu In2.Cu --rip-blocker-nets --reroute-ripped-nets

# Multiple nets sharing same layer via Voronoi partitioning (use | separator)
python route_planes.py kicad_files/input.kicad_pcb --nets GND "VA19|VA11" --plane-layers In4.Cu In5.Cu

# Dry run to see what would be placed
python route_planes.py kicad_files/input.kicad_pcb --nets GND --plane-layers B.Cu --dry-run

3b. Repair Disconnected Plane Regions

After creating power planes, regions may become split by vias and traces from other nets. Use route_disconnected_planes.py to reconnect them:

# Auto-detect all zones in PCB and repair disconnected regions (outputs to input_routed.kicad_pcb)
python route_disconnected_planes.py kicad_files/input.kicad_pcb

# Auto-detect all zones, overwrite input
python route_disconnected_planes.py kicad_files/input.kicad_pcb --overwrite

# Auto-detect all zones to specific output file
python route_disconnected_planes.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb

# Specific nets and layers
python route_disconnected_planes.py kicad_files/input.kicad_pcb --nets GND --plane-layers B.Cu

# Customize track width and clearance
python route_disconnected_planes.py kicad_files/input.kicad_pcb kicad_files/output.kicad_pcb \
    --track-width 0.5 --clearance 0.2

4. Verify Results

# Check for DRC violations (default clearance: 0.2mm)
python check_drc.py kicad_files/output.kicad_pcb

# Check connectivity (detects unrouted nets, broken routes, and T-junctions)
python check_connected.py kicad_files/output.kicad_pcb

# Check connectivity for specific nets
python check_connected.py kicad_files/output.kicad_pcb --nets "*DATA*"

# Check connectivity for all nets on a component
python check_connected.py kicad_files/output.kicad_pcb --component U1

# Only check routed nets (skip unrouted net detection)
python check_connected.py kicad_files/output.kicad_pcb --routed-only

# Check for orphan stubs (traces ending without proper connection)
python check_orphan_stubs.py kicad_files/output.kicad_pcb

5. Power Net Analysis

Use the /analyze-power-nets skill to identify power nets and get track width recommendations:

# Ask Claude to analyze your board with datasheet lookup
/analyze-power-nets kicad_files/my_board.kicad_pcb

The skill:

  1. Auto-classifies obvious components (resistors, capacitors, inductors, etc.)
  2. Uses WebSearch to look up datasheets for unknown components (ICs, connectors, transistors)
  3. Classifies each component's role (power source, current sink, pass-through, shunt)
  4. Traces power paths from sinks to sources
  5. Generates ready-to-use --power-nets configurations

See Power Net Analysis for detailed documentation.

6. High-Speed Net Analysis

Use the /find-high-speed-nets skill to identify high-speed nets and get GND return via recommendations:

# Ask Claude to analyze signal speeds with datasheet lookup
/find-high-speed-nets kicad_files/my_board.kicad_pcb

The skill:

  1. Pre-classifies nets by name patterns (DDR, USB, SPI, CLK, etc.)
  2. Pre-classifies components by footprint (FPGA, DDR, PHY, etc.)
  3. Uses WebSearch to look up datasheets for ICs and extract max clock rates and rise times
  4. Traces high-speed signals through series passives (termination resistors, AC coupling caps)
  5. Generates a speed classification (ultra-high/high/medium/low) with recommended --gnd-via-distance

The /plan-pcb-routing skill includes a lightweight version of this analysis (net name and footprint pattern matching only, no datasheet lookup) and automatically includes a GND return via step when GND planes are present. Run /find-high-speed-nets first for more accurate recommendations based on actual component specifications.

7. Integration Tests

# Run full integration test (fanout + routing + checks)
python tests/test_fanout_and_route.py --all

# Quick mode for faster testing
python tests/test_fanout_and_route.py --all --quick

See tests/README.md for detailed documentation of all test scripts.

Documentation

Document Description
Routing Architecture Module structure, obstacle maps, A* algorithm
Configuration Command-line options, GridRouteConfig parameters
Differential Pairs P/N pairing, polarity swaps, via handling
Net Ordering MPS algorithm, inside-out ordering, strategy comparison
Power/Ground Planes Copper zones with automatic via placement
Utilities DRC checker, connectivity checker, fanout generators, layer switcher
BGA Fanout BGA escape routing generator
QFN Fanout QFN/QFP escape routing generator
Rust Router Building and using the Rust A* module
Visualizer Real-time A* visualization with PyGame
Power Net Analysis Power net detection, AI analysis, track width guidelines
High-Speed Net Analysis Signal speed classification, GND return via recommendations
Integration Tests Test scripts and performance benchmarks

Project Structure

KiCadRoutingTools/
├── route.py                  # Main CLI - single-ended routing
├── route_diff.py             # Main CLI - differential pair routing
├── route_planes.py           # Main CLI - power/ground plane via connections
├── route_disconnected_planes.py  # CLI - repair disconnected plane regions
├── plane_io.py               # Plane I/O utilities (zone extraction, output writing)
├── plane_obstacle_builder.py # Obstacle map building for plane via placement
├── plane_blocker_detection.py # Blocker detection and rip-up for plane vias
├── plane_zone_geometry.py    # Voronoi zone computation for multi-net layers
├── plane_resistance.py       # Plane resistance and current capacity calculations
├── plane_region_connector.py # Detect and route between disconnected plane regions
├── routing_config.py         # GridRouteConfig, GridCoord, DiffPair classes
├── routing_defaults.py       # Default routing parameter values
├── routing_exceptions.py     # Routing exception classes
├── routing_state.py          # RoutingState class - tracks routing progress
├── routing_context.py        # Helper functions for obstacle building
├── routing_common.py         # Shared utilities for route.py and route_diff.py
├── routing_utils.py          # Shared utilities (pos_key, etc.)
├── obstacle_map.py           # Obstacle map building functions
├── obstacle_cache.py         # Net obstacle caching for incremental builds
├── obstacle_costs.py         # Stub/track proximity cost calculations
├── bresenham_utils.py        # Bresenham line-walking utilities for grid operations
│
├── diff_pair_loop.py         # Differential pair routing loop
├── single_ended_loop.py      # Single-ended routing loop
├── reroute_loop.py           # Reroute queue processing
├── phase3_routing.py         # Phase 3 multi-point tap routing
├── diff_pair_routing.py      # Diff pair A* routing implementation
├── single_ended_routing.py   # Single-ended A* routing implementation
│
├── net_ordering.py           # MPS, inside-out, and original ordering
├── net_queries.py            # Net queries (diff pairs, MPS, endpoints)
├── connectivity.py           # Stub endpoints, connected groups
├── layer_swap_optimization.py # Upfront layer swap optimization
├── layer_swap_fallback.py    # Fallback layer swap on failure
├── stub_layer_switching.py   # Stub layer swap utilities
├── mps_layer_swap.py         # MPS-aware layer swap for crossing conflicts
├── polarity_swap.py          # P/N polarity swap handling
├── target_swap.py            # Target assignment optimization
├── rip_up_reroute.py         # Rip-up and reroute logic
├── blocking_analysis.py      # Analyze blocking nets
├── length_matching.py        # Length matching with trombone meanders
│
├── kicad_parser.py           # KiCad .kicad_pcb file parser
├── kicad_writer.py           # KiCad S-expression generator
├── output_writer.py          # Route output and swap application
├── pcb_modification.py       # Add/remove routes from PCB data
├── schematic_updater.py      # Update .kicad_sch files with pad swaps
├── chip_boundary.py          # Chip boundary detection
├── geometry_utils.py         # Shared geometry calculations
├── impedance.py              # Impedance calculation (microstrip/stripline formulas)
├── memory_debug.py           # Memory usage statistics
│
├── check_drc.py              # DRC violation checker
├── check_connected.py        # Connectivity checker (with T-junction detection)
├── check_orphan_stubs.py     # Orphan stub detector
├── bga_fanout.py             # BGA fanout CLI wrapper
├── bga_fanout/               # BGA fanout package
│   ├── __init__.py           # Main fanout logic and public API
│   ├── types.py              # Track, BGAGrid, FanoutRoute, Channel, DiffPairPads
│   ├── escape.py             # Escape channel finding and assignment
│   ├── reroute.py            # Collision resolution and rerouting
│   ├── layer_balance.py      # Layer rebalancing for even distribution
│   ├── layer_assignment.py   # Layer assignment for collision avoidance
│   ├── tracks.py             # Track generation and collision detection
│   ├── geometry.py           # 45° stub and jog calculations
│   ├── collision.py          # Low-level collision detection utilities
│   ├── grid.py               # BGA grid analysis
│   ├── diff_pair.py          # Differential pair detection
│   └── constants.py          # Configuration constants
├── qfn_fanout.py             # QFN/QFP fanout CLI wrapper
├── qfn_fanout/               # QFN/QFP fanout package
│   ├── __init__.py           # Main fanout logic and public API
│   ├── layout.py             # Layout analysis functions
│   ├── geometry.py           # Stub position calculations
│   └── types.py              # QFNLayout, PadInfo, FanoutStub
├── list_nets.py              # List nets on a component
├── build_router.py           # Rust module build script (--clean to remove artifacts)
├── startup_checks.py         # Startup checks (Python deps, Rust library version)
│
├── tests/                    # Integration tests
│   ├── test_fanout_and_route.py  # Full integration test (fanout + route)
│   ├── test_kit_route.py         # Pad-to-pad routing test (no fanout)
│   ├── test_flat_hierarchy.py    # 2-layer board with GND plane test
│   ├── test_interf_u.py          # 2-layer board with non-rectangular outline test
│   ├── test_sonde_u.py           # Wide track routing test
│   └── run_utils.py              # Shared test utilities
│
├── rust_router/              # Rust A* implementation
├── pygame_visualizer/        # Real-time visualization
├── kicad_routing_plugin/     # KiCad ActionPlugin
│   ├── action_plugin.py      # ActionPlugin entry point
│   ├── swig_gui.py           # Main routing dialog (Basic/Advanced tabs)
│   ├── differential_gui.py   # Differential pair routing tab
│   ├── fanout_gui.py         # BGA/QFN fanout tab and net selection panel
│   ├── planes_gui.py         # Power/ground planes tab
│   ├── about_tab.py          # About tab with version info
│   ├── gui_utils.py          # Shared GUI utilities
│   └── settings_persistence.py  # Save/restore dialog settings between sessions
├── install_plugin.py         # Plugin installer script
├── docs/                     # Documentation
└── .claude/skills/           # Claude Code skills
    ├── analyze-power-nets/   # AI-powered power net analysis skill
    ├── find-high-speed-nets/ # AI-powered high-speed net identification skill
    └── plan-pcb-routing/     # AI-powered routing plan generation skill

Module Overview

Core Routing

Module Purpose
route.py CLI for single-ended routing
route_diff.py CLI for differential pair routing
route_planes.py CLI for power/ground plane via connections
route_disconnected_planes.py CLI for repairing disconnected plane regions
routing_config.py Configuration dataclasses (GridRouteConfig, GridCoord, DiffPair)
routing_state.py RoutingState class tracking progress, results, and PCB modifications
routing_context.py Helper functions for building obstacles and recording success
routing_common.py Shared utilities for route.py and route_diff.py (BGA zones, net resolution, length matching)
routing_utils.py Shared utilities (build_layer_map, iter_pad_blocked_cells)
obstacle_map.py Obstacle map building from PCB data
obstacle_cache.py Net obstacle caching for incremental obstacle map builds
obstacle_costs.py Stub and track proximity cost calculations
bresenham_utils.py Bresenham line-walking utilities for grid-based segment operations
geometry_utils.py Shared geometry calculations (point-to-segment distance, segment intersection, UnionFind)
routing_constants.py Shared constants (default layer stack, power net patterns, tolerances)
terminal_colors.py ANSI color codes for terminal output

Routing Loops

Module Purpose
diff_pair_loop.py Main loop for routing differential pairs
single_ended_loop.py Main loop for routing single-ended nets
reroute_loop.py Processes reroute queue for failed routes
phase3_routing.py Phase 3 multi-point tap routing (connects remaining pads after length matching)
diff_pair_routing.py Differential pair A* with centerline + offset and GND vias
single_ended_routing.py Single-ended net A* routing

Net Analysis

Module Purpose
net_ordering.py MPS, inside-out, and original net ordering strategies
net_queries.py Net queries (diff pair detection, MPS ordering, power net detection, chip pad positions)
connectivity.py Stub endpoints, connected groups, multi-point net detection

Key functions in net_queries.py:

  • identify_power_nets(pcb, patterns, widths) - Pattern-based power net detection for --power-nets CLI option
  • compute_mps_net_ordering(pcb, net_ids) - MPS algorithm for optimal net ordering
  • find_differential_pairs(pcb, patterns) - Detect P/N pairs from net names

Key functions in analyze_power_paths.py (used by /analyze-power-nets skill):

  • analyze_pcb(filepath) - Load PCB and extract components for analysis
  • get_components_needing_analysis(components) - Get components requiring AI classification
  • classify_component(components, ref, role, current_ma, notes) - Set component classification
  • trace_power_paths(pcb, components) - Trace current from sinks to sources
  • get_power_net_recommendations(pcb, components, paths) - Get recommended track widths

Optimization

Module Purpose
layer_swap_optimization.py Upfront layer swap optimization before routing
layer_swap_fallback.py Try layer swap when route fails
stub_layer_switching.py Low-level stub layer swap utilities
mps_layer_swap.py MPS-aware layer swap for crossing conflicts
polarity_swap.py P/N polarity swap for differential pairs
target_swap.py Hungarian algorithm for optimal target assignment
rip_up_reroute.py Rip-up blocking routes and retry
blocking_analysis.py Analyze which nets are blocking
length_matching.py Length matching with trombone-style meanders

I/O and Utilities

Module Purpose
kicad_parser.py KiCad .kicad_pcb file parser (extracts stackup, footprint values, pintypes)
kicad_writer.py KiCad S-expression generator
output_writer.py Write routed output with swaps and debug geometry
pcb_modification.py Add/remove routes from PCB data structure
schematic_updater.py Update .kicad_sch files with pad swaps from routing
impedance.py Impedance calculations (microstrip/stripline, width from target Z)
memory_debug.py Memory usage statistics and debugging

Performance

Integration test results (tests/test_fanout_and_route.py):

Stage Nets Time Iterations
FTDI single-ended 47/47 8.6s 319K
LVDS diff pairs (batch 1) 28/28 29.7s 10.2M
LVDS diff pairs (batch 2) 28/28 28.0s 12.0M
DDR diff pairs 5/5 0.3s 25K
DDR single-ended 51/51 6.2s 565K

Rust acceleration provides ~10x speedup vs pure Python.

Common Options

Single-Ended Routing (route.py)

python route.py kicad_files/input.kicad_pcb [output.kicad_pcb] [OPTIONS]

# Output options (default: input_routed.kicad_pcb)
--overwrite, -O         # Overwrite input file instead of creating _routed copy

# Net selection (default: "*" = all nets)
--nets "pattern" ...    # Net names or wildcard patterns to route
                        # Supports exclusion: --nets "*" "!GND" "!VCC" = all except GND/VCC
--component U1          # Route all nets on U1 (auto-excludes GND/VCC/VDD/unconnected unless --nets given)

# Geometry
--track-width 0.3       # Track width (mm), ignored if --impedance specified
--impedance 50          # Target single-ended impedance (ohms), calculates width per layer from stackup
--clearance 0.25        # Track clearance (mm)
--via-size 0.5          # Via diameter (mm)
--via-drill 0.3         # Via drill (mm)

# Power net routing (wider tracks for power/ground)
--power-nets "*GND*" "*VCC*"  # Glob patterns for power nets
--power-nets-widths 0.4 0.5   # Widths in mm for each pattern (must match --power-nets length)

# Algorithm
--grid-step 0.1         # Grid resolution (mm)
--via-cost 50           # Via penalty (grid steps)
--max-iterations 200000      # A* iteration limit
--max-probe-iterations 5000  # Quick probe per direction to detect stuck routes
--heuristic-weight 1.9       # A* greediness (>1 = faster)
--proximity-heuristic-factor 0.02  # Proximity cost estimate (only applied when endpoints in zones, diff pairs use 1/10th)
--turn-cost 1000             # Penalty for direction changes (straighter paths)
--direction-preference-cost 50   # Penalty for non-preferred layer direction (0=disabled)
                                 # Alternates H/V: F.Cu=horizontal, In1.Cu=vertical, etc.
--max-ripup 3                # Max blockers to rip up at once (1-N progressive)
--routing-clearance-margin 1.0   # Multiplier on track-via clearance (1.0 = min DRC, default)
--hole-to-hole-clearance 0.2 # Minimum drill hole edge-to-edge clearance (mm)
--board-edge-clearance 0.0   # Clearance from board edge (0 = use track clearance)

# Strategy
--ordering mps          # mps | inside_out | original
--layers F.Cu B.Cu      # Routing layers (default: 2-layer)
--layer-costs 1.0 3.0   # Per-layer cost multipliers (1.0-1000)
                        # Default: 4+ layers = all 1.0; 2 layers = F.Cu=1.0, B.Cu=3.0
                        # Order matches --layers. Use to prefer certain layers (e.g., keep signals on F.Cu)
--no-bga-zones          # Allow routing through all BGA areas
--no-bga-zones U1 U3    # Allow routing through specific BGAs only (or all if none given)

# Proximity penalties
--stub-proximity-radius 2.0  # Radius around stubs to penalize (mm)
--stub-proximity-cost 0.2    # Cost penalty near stubs (mm equivalent)
--bga-proximity-radius 7.0  # Radius around BGA edges to penalize (mm)
--bga-proximity-cost 0.2     # Cost penalty near BGA edges (mm equivalent)
--track-proximity-distance 2.0  # Radius around routed tracks (mm, same layer)
--track-proximity-cost 0.0   # Cost penalty near tracks (0 = disabled)
--vertical-attraction-radius 1.0  # Radius for cross-layer track attraction (mm)
--vertical-attraction-cost 0.0    # Cost bonus for cross-layer alignment (0 = disabled)
--ripped-route-avoidance-radius 1.0  # Radius around ripped route corridors (mm)
--ripped-route-avoidance-cost 0.1    # Cost penalty for routing through ripped corridors (0 = disabled)

# Bus routing (parallel groups of nets)
# Detects groups of nets with clustered endpoints and routes them together.
# Routes middle net first (guide track), then alternates outward with attraction
# to keep traces parallel. Use --verbose to see routing order and attraction relationships.
--bus                           # Enable bus detection and parallel routing
--bus-detection-radius 5.0      # Max endpoint distance to form bus group (mm)
--bus-attraction-radius 5.0     # Attraction radius from neighbor track (mm)
--bus-attraction-bonus 5000     # Cost bonus for staying parallel to neighbor
--bus-min-nets 2                # Minimum nets to form a bus group

# Layer optimization
--no-stub-layer-swap    # Disable stub layer switching

# Target swap optimization
--swappable-nets "*rx*"  # Glob patterns for nets that can have targets swapped
--schematic-dir /path/to/kicad  # Optional: sync pad swaps to .kicad_sch files (disabled by default)
                                # Updates lib_symbols in ALL files containing the symbol
--crossing-penalty 1000  # Penalty for crossing assignments (default: 1000)
--no-crossing-layer-check  # Count crossings regardless of layer (default: same-layer only)
--mps-reverse-rounds     # Route most-conflicting MPS groups first (instead of least)
--mps-layer-swap         # Try layer swaps to resolve MPS crossing conflicts
--mps-segment-intersection  # Force segment intersection method for MPS (auto when no BGAs)

# Length matching (for DDR4 DQ/DQS signals)
--length-match-group auto       # Auto-group DDR4 nets by byte lane (DQ0-7+DQS0, DQ8-15+DQS1, etc)
--length-match-group "pattern1" "pattern2"  # Manual grouping by net patterns
--length-match-tolerance 0.1    # Acceptable length variance within group (mm)
--meander-amplitude 1.0         # Height of meanders perpendicular to trace (mm)

# Time matching (alternative to length matching)
--time-matching                 # Match propagation time instead of length (accounts for layer dielectric)
--time-match-tolerance 1.0      # Acceptable time variance within group (ps)

# Debug
--verbose               # Print detailed diagnostic output
--debug-lines           # Output debug geometry on User layers
--skip-routing          # Skip routing, only do swaps and write debug info
--debug-memory          # Print memory usage statistics during routing
--add-teardrops         # Add teardrop settings to all pads in output file
--stats                 # Print A* search statistics (cells expanded, heuristic efficiency, etc.)

Differential Pair Routing (route_diff.py)

python route_diff.py kicad_files/input.kicad_pcb [output.kicad_pcb] [OPTIONS]

# Output options (default: input_routed.kicad_pcb)
--overwrite, -O         # Overwrite input file instead of creating _routed copy

# Net selection (default: "*" = all nets)
# All nets specified with --nets are treated as differential pairs (P/N naming convention)

# Diff pair specific options
--impedance 100         # Target differential impedance (ohms), calculates width per layer from stackup
--diff-pair-gap 0.101   # P-N gap (mm), also used as spacing for impedance calculation
--diff-pair-centerline-setback  # Setback distance (default: 2x P-N spacing)
--min-turning-radius 0.2      # Min turn radius (mm)
--max-turn-angle 180          # Max cumulative turn (degrees, prevents U-turns)
--max-setback-angle 45        # Max angle for setback search (degrees)
--direction backward    # Route from target to source
--no-gnd-vias           # Disable GND via placement (enabled by default)
--diff-chamfer-extra 1.5      # Chamfer multiplier for diff pair meanders (>1 avoids P/N crossings)
--diff-pair-intra-match       # Match P/N lengths within each diff pair (meander shorter track)

# Layer optimization
--no-stub-layer-swap    # Disable stub layer switching
--can-swap-to-top-layer # Allow swapping stubs to F.Cu (off by default)

# Target/polarity swap with schematic sync
--swappable-nets "*rx*"  # Glob patterns for nets that can have targets swapped
--schematic-dir /path/to/kicad  # Optional: sync pad swaps to .kicad_sch files (disabled by default)
                                # Syncs target swaps (P1_P<->P2_P, P1_N<->P2_N) and polarity swaps (P<->N)
                                # Updates ALL schematic files containing the lib_symbol

# All other options from route.py also apply (geometry, strategy, proximity, length matching, etc.)

Power/Ground Plane Via Connections (route_planes.py)

python route_planes.py kicad_files/input.kicad_pcb [output.kicad_pcb] --nets GND --plane-layers B.Cu [OPTIONS]

# Output options (default: input_routed.kicad_pcb)
--overwrite, -O         # Overwrite input file instead of creating _routed copy

# Required (can specify multiple nets/plane layers)
--nets, -n GND VCC          # Net name(s) for planes (e.g., GND VCC +3.3V)
                            # Use | to share a layer: "VA19|VA11" creates Voronoi-partitioned zones
--plane-layers, -p In1.Cu In2.Cu  # Plane layer(s), one per net (or one per net group)

# Via/trace geometry
--via-size 0.5          # Via outer diameter (mm)
--via-drill 0.3         # Via drill size (mm)
--track-width 0.3       # Track width for via-to-pad connections (mm)
--clearance 0.25        # Clearance (mm)

# Zone options
--zone-clearance 0.2    # Zone clearance from other copper (mm)
--min-thickness 0.1     # Minimum zone copper thickness (mm)

# Algorithm
--grid-step 0.1         # Grid resolution (mm)
--max-search-radius 10.0  # Max radius to search for valid via position (mm)
--max-via-reuse-radius 1.0  # Max radius to prefer reusing existing via (mm)
--close-via-radius 0.5      # Radius to check for nearby vias before placing new one (default: 2.5 * via-size)
--hole-to-hole-clearance 0.2  # Minimum drill hole clearance (mm)
--layers, -l F.Cu In1.Cu In2.Cu B.Cu  # All copper layers for routing and via span
--layer-costs 1.0 1.0 1.0 1.0  # Per-layer cost multipliers (1.0-1000)
                               # Default: 4+ layers = all 1.0; 2 layers = F.Cu=1.0, B.Cu=3.0
--board-edge-clearance 0.5  # Zone clearance from board edge (mm)

# Multi-net plane layers (Voronoi partitioning)
--plane-proximity-radius 2.0  # Proximity radius for routing around other nets' vias (mm)
--plane-proximity-cost 5.0    # Proximity cost for routing around other nets' vias
--plane-track-via-clearance 0.8  # Clearance from MST track center to other nets' via centers (mm)
--voronoi-seed-interval 2.0   # Sample interval for seed points along connection routes (mm)
--plane-max-iterations 200000 # Max A* iterations for plane connection routing

# Blocker rip-up
--rip-blocker-nets      # Rip up nets blocking via placement
--max-rip-nets 3        # Max blocker nets to rip up per pad (default: 3)
--reroute-ripped-nets   # Automatically re-route ripped nets after via placement
--power-nets "*GND*" "*VCC*"  # Glob patterns for power nets (wider tracks when rerouting)
--power-nets-widths 0.4 0.5   # Track widths for each power-net pattern

# Debug
--dry-run               # Analyze without writing output
--verbose, -v           # Print detailed debug messages
--debug-lines           # Draw MST routes on User.1, User.2, etc. per net
--add-teardrops         # Add teardrop settings to all pads in output file

# GND return via placement (for signal integrity)
--add-gnd-vias          # Add GND vias near signal vias for return current paths
--gnd-via-net GND       # Net name for GND vias (default: GND)
--gnd-via-distance 2.0  # Max distance from signal via to place GND via (mm, default: 2.0)

Features:

  • Multi-net support - Process multiple nets in one run (e.g., GND and VCC planes)
  • Voronoi partitioning - Multiple nets can share a single plane layer using | separator (e.g., "VA19|VA11"). Each net's vias get non-overlapping zone polygons. MST edges are routed between all vias using A* pathfinding, with routes sampled as Voronoi seeds to ensure connected zones. Retries with failed nets first (up to 5 iterations)
  • Automatic pad classification - Identifies SMD pads needing vias vs through-hole/zone-layer pads
  • Smart via placement - Places vias at pad center when possible, spirals outward when blocked
  • A* trace routing - Routes traces from offset vias to pads, avoiding all copper layers
  • Via reuse with fallback - Prefers nearby vias within reuse radius, falls back to farther vias if placement fails
  • Blocker rip-up - When via placement/routing fails, identifies blocking nets and temporarily removes them, then retries
  • Automatic re-routing - Optionally re-routes ripped nets after all plane vias are placed
  • Zone creation - Creates copper pour zone. If an existing zone for the same net/layer is present, it is replaced with new parameters (clearance, min_thickness)
  • Resistance analysis - Calculates and displays approximate plane resistance and maximum current capacity (IPC-2152) for each polygon. For multi-net layers, uses the longest MST route path length; for single-net layers, uses the bounding box diagonal. Samples polygon width perpendicular to the current path to estimate effective cross-section. Assumes 1 oz copper and 10°C temperature rise

See Power/Ground Planes for detailed documentation.

Disconnected Plane Region Repair (route_disconnected_planes.py)

After creating power planes, regions may become split by vias and traces from other nets cutting through. This script detects disconnected regions within each plane zone and routes wide, short tracks between them.

python route_disconnected_planes.py kicad_files/input.kicad_pcb [output.kicad_pcb] [OPTIONS]

# Output options (default: input_routed.kicad_pcb)
--overwrite, -O         # Overwrite input file instead of creating _routed copy

# Zone selection (auto-detects all zones if not specified)
--nets, -n GND +3.3V        # Net name(s) to process
--plane-layers, -p B.Cu In1.Cu  # Plane layer(s) to process
--layers, -l F.Cu In1.Cu In2.Cu B.Cu  # Layers available for routing (default: all copper)

# Track width
--max-track-width 2.0       # Maximum track width for connections (mm)
--min-track-width 0.2       # Minimum track width for connections (mm)
--track-width 0.3           # Default track width for routing config (mm)

# Clearance
--clearance 0.25            # Trace-to-trace clearance (mm)
--zone-clearance 0.2        # Zone fill clearance around obstacles (mm)
--track-via-clearance 0.8   # Clearance from tracks to other nets' vias (mm)
--board-edge-clearance 0.5  # Clearance from board edge (mm)
--hole-to-hole-clearance 0.3  # Minimum clearance between drill holes (mm)

# Via options
--via-size 0.5              # Via outer diameter (mm)
--via-drill 0.3             # Via drill diameter (mm)

# Grid
--grid-step 0.1             # Routing grid step (mm)
--analysis-grid-step 0.5    # Grid step for connectivity analysis (coarser = faster)

# Routing
--max-iterations 200000     # Maximum A* iterations per route attempt

# Debug
--dry-run                   # Analyze without writing output
--verbose, -v               # Print detailed debug messages
--debug-lines               # Add debug lines on User.4 layer showing route paths

Features:

  • Auto-detection - Automatically finds all zones in PCB if nets/layers not specified
  • Per-net processing - Zones with the same net on multiple layers are processed together, reducing redundant routes since vias connect all layers
  • Flood-fill region detection - Uses grid-based flood fill to identify disconnected regions across all zone layers
  • Cross-layer connectivity - Uses vias and through-hole pads to properly track connectivity across multiple zone layers
  • MST-based connections - Connects regions using minimum spanning tree for optimal routing
  • Multi-point routing - Uses ALL anchors (vias/pads) in each region as potential connection points, trying both directions (A->B and B->A) since A* can find different paths depending on direction
  • Wide track routing - Tries track widths from max (2.0mm) down to min (0.2mm), using the widest width that fits without rebuilding obstacle maps
  • Smart via placement - Only adds new vias at layer transitions if no via already exists at that position
  • Hole-to-hole clearance - Respects drill hole clearances when placing new vias
  • Multi-layer routing - Can route through any copper layer to connect regions

Requirements

  • Python 3.7+
  • numpy (pip3 install numpy)
  • scipy (pip3 install scipy) - used for optimal target assignment and Voronoi partitioning
  • shapely (pip3 install shapely) - used for polygon union in multi-net plane layers
  • Rust toolchain (for building the router module)
  • pygame-ce (optional, for visualizer: pip3 install pygame-ce)

Limitations

  • No push-and-shove (routes around obstacles, doesn't move them)
  • No layer swaps of stubs for multipoint nets (3+ pads)
  • No blind or buried vias
  • No user-defined keepout zones
  • No coarse grid assignment before detailed routing to plan overall topology
  • No via cost or other parameter learning/tuning
  • No design rules by region/area support

License

MIT License

About

A set of Python/Rust tools to aid routing in KiCad

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •