# SPDL-PCB-EDA-01: Invariant-Governed PCB Schematic Capture, Autonomous Routing Topologies, Electronic Design Automation (EDA), and DFM Proof Gates **Specification Document ID:** `SPDL-PCB-EDA-SPEC-2026-v1.0` **Classification:** Open Epistemic Standard / Cyber-Physical Hardware Synthesis **Principal Architect:** Asse van Nix | Systems Perspective Framework & Proof-Driven Architecture Group --- ### 1. Conceptual Framework & Purpose SPDL-PCB-EDA-01 establishes a formal, machine-verifiable grammar for defining electrical schematics, layer stackups, component placements, trace routing constraints, and Design for Manufacturability (DFM) requirements. This contract abstracts away manual schematic capture into a deterministic, single-line tagged SPDL manifest. A stochastic MLLM reads this contract and synthesizes functional PCB layout code (either as native S-expressions for KiCad 8/9 or direct Gerber/IPC-D-356 vectors via pure Zig), which is then rigorously evaluated against headless fabrication proof gates. ``` THE PCB AGENTIC SYNTHESIS LOOP ┌─────────────────────────────────────────────────────────────────────────────┐ │ 1. INGESTION: Agent ingests SPDL Circuit Contract (Nets, Parts, DFM Rules) │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────────────────────▼──────────────────────────────────────┐ │ 2. SYNTHESIS: MLLM generates S-Expression / Layout Topology │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────────────────────▼──────────────────────────────────────┐ │ 3. ORACLE GATE: Zig 0.16 Harness spawns `kicad-cli` / `mr-pcb` │ │ • Headless ERC: Electrical Rule Check (Zero unrouted nets, no float pins)│ │ • Headless DRC: Design Rule Check (Fab clearance, annular ring, drill) │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────┴──────────────────┐ [DRC / ERC Pass] [DRC Violations Detected] ▼ ▼ ┌──────────────────────────────────────┐ ┌──────────────────────────────────────┐ │ 4. EXPORT ARTIFACTS │ │ DIRECTIONAL SLACK TELEMETRY │ │ • Gerber RS-274X / Excellon Drills │ │ Format failure coordinates as SPDL; │ │ • IPC-D-356 Netlist Verification │ │ Attempt <= 2: Automated re-route │ │ • JLCPCB / PCBWay SMT BOM & CPL CSV │ │ Attempt > 2: HALT for Human (A-7) │ └──────────────────────────────────────┘ └──────────────────────────────────────┘ ``` --- ### 2. SPDL-PCB Grammatical Entity Registry Every `.spdl` circuit manifest is a newline-delimited stream of tagged records conforming to the ISO/IEC 14977 EBNF standard: | Tag | Keyword | Functional Purpose | | :---: | :--- | :--- | | **`(C)`** | `@CIRCUIT_CONTRACT` | Board identity, layer count, board thickness, copper weight, host fabricator profile. | | **`(L)`** | `@LAYER_STACK` | Layer designation, dielectric constant ($\epsilon_r$), thickness, and electrical function. | | **`(P)`** | `@PART_NODE` | Electronic component: Reference designator, package/footprint, LCSC part ID, value. | | **`(N)`** | `@NET_CONNECTION` | Net identity, interconnected pin nodes, electrical class (Power, Ground, High-Speed, RF). | | **`(B)`** | `@BOUNDARY_OUTLINE`| Physical PCB polygon boundary, corner radius, mounting hole cutouts (`Edge.Cuts`). | | **`(R)`** | `@ROUTING_RULE` | Track width, minimum clearance, via geometry, differential pair target impedance ($Z_0$). | | **`(Z)`** | `@ZONE_CONTAINMENT`| Ground/Power plane polygon, net association, thermal relief spokes, pour priority. | | **`(D)`** | `@DFM_INVARIANT` | Factory manufacturing constraints (minimum drill, minimum trace, annular ring limit). | | **`(G)`** | `@PROOF_GATE` | Automated ERC/DRC pass/fail assertion executed by the Zig harness. | --- ### 3. Formal EBNF Grammar Specification ```ebnf PcbManifest = { Line } ; Line = [ Whitespace ] , ( Comment | PcbRecord ) , Newline ; Whitespace = { " " | "\t" } ; Newline = "\n" | "\r\n" ; Comment = "#" , { AnyChar - Newline } ; PcbRecord = CircuitRecord | LayerRecord | PartRecord | NetRecord | BoundaryRecord | RoutingRecord | ZoneRecord | DfmRecord | ProofGateRecord ; CircuitRecord = "(C) @CIRCUIT_CONTRACT id:\"" , Identifier , "\" " , "layers:" , Integer , " " , "thickness_mm:" , Float , " " , "cu_oz:" , Float , " " , "profile:\"" , FabProfile , "\"" ; LayerRecord = "(L) @LAYER_STACK layer:" , Integer , " " , "name:\"" , LayerName , "\" " , "type:" , ( "COPPER" | "CORE" | "PREPREG" ) , " " , "thick_um:" , Float , [ " er:" , Float ] ; PartRecord = "(P) @PART_NODE ref:\"" , Identifier , "\" " , "val:\"" , StringLiteral , "\" " , "fp:\"" , StringLiteral , "\" " , [ "lcsc:\"" , Identifier , "\" " ] , [ "pos:[" , Float , "," , Float , "," , Float , "] " ] , "side:" , ( "TOP" | "BOTTOM" ) ; NetRecord = "(N) @NET_CONNECTION net:\"" , Identifier , "\" " , "class:" , ( "POWER" | "GROUND" | "SIGNAL" | "DIFF" | "ANALOG" ) , " " , "nodes:[" , IdentifierList , "]" ; BoundaryRecord = "(B) @BOUNDARY_OUTLINE points:[" , CoordList , "] " , [ "radius_mm:" , Float , " " ] , [ "holes:[" , HoleList , "]" ] ; RoutingRecord = "(R) @ROUTING_RULE class:\"" , Identifier , "\" " , "trace_min_mm:" , Float , " " , "clearance_min_mm:" , Float , " " , "via_drill_mm:" , Float , " " , "via_size_mm:" , Float , [ " z0_target_ohm:" , Float ] ; ZoneRecord = "(Z) @ZONE_CONTAINMENT net:\"" , Identifier , "\" " , "layer:\"" , LayerName , "\" " , "priority:" , Integer , " " , "thermal_relief_spokes:" , Integer ; DfmRecord = "(D) @DFM_INVARIANT fab:\"" , FabProfile , "\" " , "min_trace_mm:" , Float , " " , "min_space_mm:" , Float , " " , "min_drill_mm:" , Float , " " , "annular_ring_min_mm:" , Float ; ProofGateRecord = "(G) @PROOF_GATE id:\"" , Identifier , "\" " , "type:" , ( "ERC" | "DRC" | "IMPEDANCE" | "EXPORT" ) , " " , "expect:" , ( "ZERO_ERRORS" | "EXIT_CODE_0" ) ; FabProfile = "JLCPCB" | "PCBWAY" | "PCBGOGO" | "NEXTPCB" | "OSHPARK" ; LayerName = "F.Cu" | "B.Cu" | "In1.Cu" | "In2.Cu" | "Edge.Cuts" | "F.Silks" ; IdentifierList = Identifier , { "," , Identifier } ; CoordList = CoordPair , { "," , CoordPair } ; CoordPair = "[" , Float , "," , Float , "]" ; HoleList = HoleSpec , { "," , HoleSpec } ; HoleSpec = "[" , Float , "," , Float , "," , Float , "]" ; (* x, y, drill *) ``` --- ### 4. Fabricator DFM Capability Profiles (Default Invariants) The synthesis engine must enforce physical limitations based on the declared fabricator profile. The table below codifies the default limits embedded into `@DFM_INVARIANT`: | Factory Profile | Min Trace / Space (mm) | Min Via Hole / Annular Ring | Max Dimensions (Std Proto) | SMT Component Integration | | :--- | :---: | :---: | :---: | :--- | | **`JLCPCB`** | 0.127 / 0.127 ($0.09/0.09$ for 4L) | 0.30 mm / 0.15 mm | $400 \times 500\text{ mm}$ | Native LCSC Part Integration (CPL + BOM) | | **`PCBWAY`** | 0.100 / 0.100 | 0.20 mm / 0.15 mm | $500 \times 600\text{ mm}$ | Flexible Turnkey SMT, ENIG/Hard Gold | | **`PCBGOGO`** | 0.100 / 0.100 | 0.20 mm / 0.15 mm | $500 \times 500\text{ mm}$ | Express Turnaround, High-Density BGA | | **`NEXTPCB`** | 0.100 / 0.100 | 0.25 mm / 0.15 mm | $400 \times 500\text{ mm}$ | HQEW Global Supply Chain Sourcing | | **`OSHPARK`** | 0.152 / 0.152 | 0.254 mm / 0.127 mm | Custom Panel Sharing | USA Domestic, Direct `.kicad_pcb` Drag-and-Drop | --- ### 5. Multi-Turn Routing Feedback Protocol (Slack Telemetry) When headless DRC fails, the Zig harness does not return an unstructured 500-line text dump. It extracts topological failure coordinates into an actionable **Directional Slack Packet**: ```spdl (E) @SLACK_TELEMETRY gate:"DRC_CLEARANCE" net_a:"NET_USB_D_P" net_b:"NET_GND" at:[14.250,22.100] measured_mm:0.092 required_mm:0.127 slack:-0.035 delta_vector:[+0.035,0.0] ``` The MLLM uses the `delta_vector` to calculate the spatial clearance push needed to resolve the DRC violation on the next cognitive turn without manual routing intervention.