Parallel pcb_status pipeline: parse board, classify domains/groups, inventory traces, PE-LAY/PLC/SI/DRT checks, per-IC datasheet review. Findings merge into the report UI. No auto-place or pcbnew write-back.
87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
"""Pad net on the PCB vs pin net on the schematic graph.
|
|
|
|
Silent when either side has no name. Power-flag footprints (#PWR) skipped.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from backend.periscopex.models import DesignGraph, Finding, LayoutGraph
|
|
|
|
|
|
def _ensure_recommendation(f: Finding) -> Finding:
|
|
if not (f.recommendation or "").strip():
|
|
f.recommendation = (
|
|
"Align the PCB pad net with the schematic pin, then re-run PCB review."
|
|
)
|
|
return f
|
|
|
|
|
|
def check_pcb_net_match(
|
|
graph: DesignGraph,
|
|
layout: LayoutGraph | None,
|
|
) -> list[Finding]:
|
|
if layout is None or not layout.footprints:
|
|
return []
|
|
findings: list[Finding] = []
|
|
sch_refs = {
|
|
ref for ref in graph.components
|
|
if not ref.startswith("#")
|
|
}
|
|
pcb_refs = {
|
|
ref for ref in layout.footprints
|
|
if not ref.startswith("#")
|
|
}
|
|
|
|
for ref in sorted(sch_refs - pcb_refs):
|
|
comp = graph.components[ref]
|
|
findings.append(_ensure_recommendation(Finding(
|
|
designator=ref,
|
|
mpn=comp.mpn or "",
|
|
aspect="pcb_match",
|
|
finding=f"{ref} is in the schematic but has no footprint on the PCB.",
|
|
why="Layout review cannot check a part that is not placed.",
|
|
status="WARNING",
|
|
recommendation=f"Place {ref} on the board or remove it from the schematic/BOM.",
|
|
source="pcb_net_match",
|
|
rule_id="PE-LAY-002",
|
|
pins=[],
|
|
)))
|
|
|
|
for ref, fp in sorted(layout.footprints.items()):
|
|
if ref.startswith("#"):
|
|
continue
|
|
comp = graph.components.get(ref)
|
|
if comp is None:
|
|
continue
|
|
for pad in fp.pads:
|
|
if not pad.net or not pad.number:
|
|
continue
|
|
sch_net = graph.pin_net(ref, pad.number)
|
|
if not sch_net:
|
|
continue
|
|
if sch_net == pad.net:
|
|
continue
|
|
findings.append(_ensure_recommendation(Finding(
|
|
designator=ref,
|
|
mpn=comp.mpn or "",
|
|
aspect="pcb_match",
|
|
finding=(
|
|
f"{ref}.{pad.number} PCB net '{pad.net}' does not match "
|
|
f"schematic net '{sch_net}'."
|
|
),
|
|
why=(
|
|
"Datasheet and SI checks follow schematic net names. "
|
|
"A pad on the wrong net is a layout error, not a BOM typo."
|
|
),
|
|
status="ERROR",
|
|
recommendation=(
|
|
f"Reconnect pad {ref}.{pad.number} to '{sch_net}' "
|
|
f"(or fix the schematic if the PCB is authoritative)."
|
|
),
|
|
source="pcb_net_match",
|
|
rule_id="PE-LAY-001",
|
|
net=pad.net,
|
|
pins=[pad.number],
|
|
)))
|
|
return findings
|