Design-rule checking (DRC)—self-contained, multi-threaded engine#

” Self-contained DRC engine for PyEDB.

This module provides a high-performance, multi-threaded design-rule checker that runs inside an open PyEDB session and validates 50+ industry-standard rules (geometry, spacing, manufacturing, high-speed, test).

Features#

  • Impedance checks via improved analytical formulas (Wheeler, Cohn, Hammerstad-Jensen).

  • Copper-balance by layer or by arbitrary zone polygons.

  • Back-drill stub / depth verification.

  • R-tree spatial index for fast geometry queries.

Examples#

>>> import pyedb
>>> from pyedb.workflows.drc.drc import Drc, Rules
>>> edb = pyedb.Edb(edbpath="my_board.aedb")
>>> rules = Rules.parse_file("rules.json")  # or Rules.parse_obj(python_dict)
>>> drc = Drc(edb)
>>> violations = drc.check(rules)
>>> drc.to_ipc356a("fab_review.ipc")

The pyedb.workflows.drc sub-package exposes a lightweight, high-accuracy design-rule checker (DRC) that runs inside an open PyEDB session. It validates more than 50 industry-standard rules (geometry, spacing, manufacturing, high-speed, test) and exports an IPC-D-356A netlist annotated with violations for CAM hand-off.

Features#

  • Impedance checks via improved analytical formulas (Wheeler, Cohn, Hammerstad–Jensen).

  • Copper-balance by layer or by arbitrary zone polygons.

  • Back-drill stub/depth verification.

  • R-tree spatial index for fast geometry queries.

  • Thread-safe, multi-threaded rule execution (automatic core detection).

  • Fluent, type-safe API to build rule decks programmatically.

  • JSON/YAML round-trip serialization (via Pydantic).

Quick start#

import pyedb
from pyedb.workflows.drc.drc import Drc, Rules

edb = pyedb.Edb("my_board.aedb")
rules = (
    Rules()
    .add_min_line_width("pwr", "15 mil")
    .add_min_clearance("clk2data", "4 mil", "CLK*", "DATA*")
    .add_min_annular_ring("via5", "5 mil")
    .add_diff_pair_length_match("usb", tolerance="0.1 mm", pairs=[("USB_P", "USB_N")])
    .add_copper_balance("top_bal", max_percent=10, layers=["TOP"])
)

drc = Drc(edb)
violations = drc.check(rules)
drc.to_ipc356a("fab_review.ipc")

API reference#

Rules container#

Rules

Centralised, serialisable container for all design-rule categories supported by the PyEDB DRC engine.

Rules.from_dict

Alias for model_validate.

Rules.to_dict

Alias for model_dump.

Rules.add_min_line_width

Append a minimum-line-width rule.

Rules.add_min_clearance

Append a minimum-clearance rule between two nets (wild-cards allowed).

Rules.add_min_annular_ring

Append a minimum-annular-ring rule for drilled holes.

Rules.add_diff_pair_length_match

Append a length-matching rule for differential pairs.

Rules.add_back_drill_stub_length

Append a maximum-allowed back-drill stub-length rule.

Rules.add_copper_balance

Append a copper-density balance rule.

Rule models#

MinLineWidth

Minimum-line-width rule.

MinClearance

Minimum clearance between two nets.

MinAnnularRing

Minimum annular ring for drilled holes.

DiffPair

Differential-pair definition.

DiffPairLengthMatch

Length-matching rule for differential pairs.

BackDrillStubLength

Maximum allowed back-drill stub length.

CopperBalance

Copper-density balance rule.

DRC Engine#

Drc

Lightweight, high-accuracy DRC engine that runs inside an open PyEDB session.

Drc.check

Run all rules and return a list of violations.

Drc.to_ipc356a

Write a complete IPC-D-356A netlist plus DRC comments for fab review.

Implementation notes#

Thread safety#

All heavy geometry checks are embarrassingly parallel. The engine snapshots EDB data into plain Python objects before entering the worker pool, so the R-tree index is never accessed concurrently.

Extending the engine#

Add a new rule in three steps:

  1. Create a Pydantic model inheriting from Pydantic.BaseModel.

  2. Append the model to the Rules container and expose a fluent helper.

  3. Implement _rule_<field_name> inside Drc; accept the rule instance and append violations to self.violations.

Examples#

Load a rule deck from JSON#

import json
from pyedb.workflows.drc.drc import Rules

with open("my_rules.json") as f:
    rules = Rules.from_dict(json.load(f))

Export violations to CSV#

import csv

drc = Drc(edb)
drc.check(rules)

with open("violations.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=drc.violations[0].keys())
    writer.writeheader()
    writer.writerows(drc.violations)