Product Requirements Document: Electrical Rules Check (ERC)

Feature: Electrical Rules Check (ERC) Validation Issue: #32 Priority: πŸ”΄ HIGHEST Estimated Effort: 6-8 hours Target Version: 0.5.0


Executive Summary

Implement comprehensive Electrical Rules Check (ERC) validation for KiCAD schematics, enabling automated detection of electrical design errors before manufacturing. This feature brings professional-grade circuit validation to kicad-sch-api, matching KiCAD’s built-in ERC capabilities.

Problem Statement

Current State

  • No circuit validation available - Users cannot verify schematic electrical correctness

  • Manual error detection only - Designers must visually inspect for errors

  • Risk of manufacturing issues - Electrical errors may reach production

  • No AI validation - AI-generated circuits cannot be automatically validated

User Pain Points

  1. Cannot detect output-to-output shorts programmatically

  2. No way to verify power supply connectivity

  3. Missing wire detection requires manual inspection

  4. Duplicate component references go unnoticed

  5. Undriven nets are hard to identify

Impact

  • Professional credibility - Library cannot be used for production without validation

  • AI agent reliability - AI-generated circuits cannot be trusted without ERC

  • User confidence - Users hesitant to adopt without quality checks

Goals & Success Metrics

Primary Goals

  1. βœ… Implement industry-standard ERC validation

  2. βœ… Match KiCAD’s ERC capabilities

  3. βœ… Provide actionable error reports

  4. βœ… Support customizable severity levels

Success Metrics

  • Coverage: Detect all major KiCAD ERC error types

  • Accuracy: <1% false positives

  • Performance: <100ms for 100-component schematics

  • Usability: Clear, actionable error messages

Requirements

Functional Requirements

FR1: Pin Type Validation

Must Support All KiCAD Pin Types:

  • Input (PT_INPUT)

  • Output (PT_OUTPUT)

  • Bidirectional (PT_BIDI)

  • Tri-state (PT_TRISTATE)

  • Passive (PT_PASSIVE)

  • Not Internally Connected/Free (PT_NIC)

  • Unspecified (PT_UNSPECIFIED)

  • Power Input (PT_POWER_IN)

  • Power Output (PT_POWER_OUT)

  • Open Collector (PT_OPENCOLLECTOR)

  • Open Emitter (PT_OPENEMITTER)

  • Not Connected (PT_NC)

FR2: Pin Conflict Matrix

Implement ERC conflict matrix following KiCAD standards:

Error Conditions (must detect):

  • Output ↔ Output (driving conflict)

  • Power Output ↔ Power Output (power short)

  • Output ↔ Power Output (logic/power conflict)

Warning Conditions (should warn):

  • Unspecified ↔ Any pin type

  • Input with no driver

  • Tri-state ↔ Output

OK Conditions (explicitly allowed):

  • Input ↔ Output

  • Passive ↔ Any

  • Bidirectional ↔ Any logic type

  • Power Input ↔ Power Output

FR3: Connectivity Validation

Must Detect:

  1. Unconnected Required Pins

    • Input pins without connections

    • Power input pins without power source

  2. Dangling Wires

    • Wires with only one connection

    • Wires not connected to any pin

  3. Undriven Nets

    • Nets with only input pins

    • Power nets without power output

  4. Multiple Drivers

    • Multiple outputs on same net (conflict)

    • Multiple power outputs (short)

FR4: Component Validation

Must Detect:

  1. Duplicate References

    • Same reference used multiple times (e.g., R1, R1)

  2. Invalid References

    • Missing references

    • Malformed reference format

  3. Missing Properties

    • Components without values

    • Missing footprints (warning)

FR5: Power Supply Validation

Must Detect:

  1. Power Flags

    • Power input pins without PWR_FLAG or power output

  2. Power Continuity

    • VCC/GND nets properly connected

    • Power supply presence

  3. Power Conflicts

    • Multiple voltage sources on same net

FR6: Hierarchical Design Validation

Must Detect:

  1. Sheet Pin Mismatches

    • Hierarchical labels without matching sheet pins

    • Type mismatches (input/output)

  2. Bus Consistency

    • Bus alias consistency across hierarchy

    • Bus member consistency

FR7: Net Labeling Validation

Must Detect:

  1. Conflicting Labels

    • Multiple different labels on same net

  2. Suspicious Patterns

    • Very similar label names (e.g., VCC vs VCC1)

    • Common typos

Non-Functional Requirements

NFR1: Performance

  • Target: <100ms for typical schematics (<100 components)

  • Maximum: <500ms for large schematics (<1000 components)

  • Scalability: O(n) complexity where n = number of nets

NFR2: Usability

  • Clear Error Messages: Include component references, net names, pin numbers

  • Severity Levels: Error, Warning, Info

  • Actionable: Suggest fixes where possible

NFR3: Configurability

  • Customizable Rules: Users can adjust severity levels

  • Rule Suppression: Ability to suppress specific warnings

  • Profile Support: Different rule sets for different projects

NFR4: Compatibility

  • KiCAD 7/8 Compatible: Match KiCAD ERC behavior

  • Standard Compliance: Follow industry ERC standards

User Stories

US1: AI Agent Validation

As an AI agent generating circuits I want to automatically validate electrical correctness So that I can ensure generated circuits are safe to manufacture

Acceptance Criteria:

  • ERC runs automatically after circuit generation

  • Returns structured error report

  • Errors include specific fix suggestions

US2: Manual Design Validation

As a circuit designer using the library I want to validate my schematic before saving So that I catch errors before manufacturing

Acceptance Criteria:

  • Simple API: sch.run_erc()

  • Returns all errors and warnings

  • Can configure severity levels

US3: Batch Validation

As a design automation engineer I want to validate hundreds of schematics So that I can ensure design quality at scale

Acceptance Criteria:

  • Fast performance (<100ms per schematic)

  • Parallel execution support

  • Summary reports

US4: Custom Rule Configuration

As an experienced designer I want to customize ERC rules So that I can match my organization’s standards

Acceptance Criteria:

  • Configurable severity levels

  • Rule suppression

  • Custom rule definitions

Technical Design

Architecture

ElectricalRulesChecker
β”œβ”€β”€ PinTypeValidator
β”‚   β”œβ”€β”€ pin_conflict_matrix
β”‚   └── validate_pin_connections()
β”œβ”€β”€ ConnectivityValidator
β”‚   β”œβ”€β”€ find_dangling_wires()
β”‚   β”œβ”€β”€ find_undriven_nets()
β”‚   └── find_unconnected_pins()
β”œβ”€β”€ ComponentValidator
β”‚   β”œβ”€β”€ find_duplicate_references()
β”‚   └── validate_component_properties()
β”œβ”€β”€ PowerValidator
β”‚   β”œβ”€β”€ validate_power_flags()
β”‚   └── check_power_continuity()
└── HierarchyValidator
    β”œβ”€β”€ validate_sheet_pins()
    └── validate_bus_aliases()

API Design

# Basic usage
from kicad_sch_api.validation import ElectricalRulesChecker

sch = ksa.load_schematic("circuit.kicad_sch")
erc = ElectricalRulesChecker(sch)

# Run all checks
results = erc.run_all_checks()

# Access results
for error in results.errors:
    print(f"ERROR: {error.message}")
    print(f"  Component: {error.component_ref}")
    print(f"  Location: {error.location}")

# Check specific categories
pin_conflicts = erc.check_pin_conflicts()
dangling_wires = erc.check_dangling_wires()
power_issues = erc.check_power_supply()

# Custom configuration
config = ERCConfig()
config.set_severity("unconnected_input", "warning")  # Downgrade to warning
config.suppress_warning("W001", component="R1")       # Suppress specific warning

erc = ElectricalRulesChecker(sch, config=config)
results = erc.run_all_checks()

Data Models

@dataclass
class ERCViolation:
    """Single ERC violation."""
    violation_type: str           # "pin_conflict", "dangling_wire", etc.
    severity: str                 # "error", "warning", "info"
    message: str                  # Human-readable description
    component_refs: List[str]     # Affected components
    net_name: Optional[str]       # Affected net
    pin_numbers: List[str]        # Affected pins
    location: Optional[Point]     # Schematic location
    suggested_fix: Optional[str]  # How to fix
    error_code: str              # e.g., "E001", "W042"

@dataclass
class ERCResult:
    """Complete ERC results."""
    errors: List[ERCViolation]
    warnings: List[ERCViolation]
    info: List[ERCViolation]
    total_checks: int
    passed_checks: int
    duration_ms: float

    def has_errors(self) -> bool:
        return len(self.errors) > 0

    def summary(self) -> str:
        return f"{len(self.errors)} errors, {len(self.warnings)} warnings"

Pin Conflict Matrix Implementation

class PinConflictMatrix:
    """KiCAD-compatible pin conflict matrix."""

    # Severity levels
    OK = 0
    WARNING = 1
    ERROR = 2

    # Default matrix (matches KiCAD defaults)
    MATRIX = {
        # (pin_type_1, pin_type_2): severity
        ("output", "output"): ERROR,
        ("power_output", "power_output"): ERROR,
        ("output", "power_output"): ERROR,
        ("input", "output"): OK,
        ("passive", "*"): OK,  # Passive OK with everything
        ("unspecified", "*"): WARNING,
        # ... full matrix
    }

    def check_connection(self, pin1_type: str, pin2_type: str) -> int:
        """Check if connection is OK, warning, or error."""
        pass

Validation Rules

Error-Level Violations (E-xxx)

Code

Violation

Description

E001

Output to Output

Two or more output pins connected

E002

Power Output Conflict

Multiple power outputs on same net

E003

Output to Power Output

Logic output connected to power rail

E004

Duplicate Reference

Same reference designator used twice

E005

Unconnected NC Pin

Pin marked NC has connection

E006

Multiple Net Labels

Different labels on same net

Warning-Level Violations (W-xxx)

Code

Violation

Description

W001

Unconnected Input

Input pin has no connection

W002

Dangling Wire

Wire has only one endpoint

W003

Undriven Net

Net has no output driver

W004

Missing Power Flag

Power net without PWR_FLAG

W005

Unspecified Pin Type

Pin with unspecified electrical type

W006

Similar Labels

Labels with similar names on different nets

W007

Missing Footprint

Component has no footprint assigned

W008

Missing Value

Component has no value

Info-Level Violations (I-xxx)

Code

Violation

Description

I001

Single-Pin Net

Net has only one connection

I002

Passive-Only Net

Net has only passive pins

Implementation Phases

Phase 1: Core Infrastructure (2 hours)

  • Create ElectricalRulesChecker class

  • Implement ERCViolation and ERCResult dataclasses

  • Create ERCConfig for configuration

  • Basic test framework

Phase 2: Pin Validation (2 hours)

  • Implement PinConflictMatrix

  • Implement PinTypeValidator

  • Add all 12 KiCAD pin types

  • Test pin-to-pin conflict detection

Phase 3: Connectivity Validation (2 hours)

  • Implement ConnectivityValidator

  • Dangling wire detection

  • Undriven net detection

  • Unconnected pin detection

Phase 4: Component & Power Validation (2 hours)

  • Implement ComponentValidator

  • Implement PowerValidator

  • Duplicate reference detection

  • Power flag validation

Phase 5: Integration & Testing (2 hours)

  • Comprehensive test suite

  • Reference schematic validation

  • Documentation

  • Performance optimization

Testing Strategy

Unit Tests

  • Pin conflict matrix (all combinations)

  • Individual validators (each rule)

  • Configuration system

  • Error message generation

Integration Tests

  • Complete ERC run on sample schematics

  • Known-good schematics (should pass)

  • Known-bad schematics (should fail with expected errors)

Reference Tests

  • KiCAD-created schematics with deliberate errors

  • Compare results with KiCAD’s ERC output

  • Ensure compatibility

Performance Tests

  • 10-component schematic: <10ms

  • 100-component schematic: <100ms

  • 1000-component schematic: <500ms

Questions for Product Owner

Scope Questions

  1. KiCAD Version Compatibility

    • Should we match KiCAD 7, KiCAD 8, or both?

    • Are there version-specific ERC differences we need to handle?

  2. Customization Level

    • How customizable should the pin conflict matrix be?

    • Should users be able to add custom validation rules?

    • Do we need rule profiles (strict, standard, relaxed)?

  3. Hierarchy Handling

    • How deep should hierarchical validation go?

    • Should we validate across hierarchy boundaries?

    • Should sheet pin type mismatches be errors or warnings?

  4. Power Flag Handling

    • Should missing PWR_FLAG be an error or warning?

    • Do we auto-detect power symbols (like GND, VCC)?

    • How to handle custom power symbols?

Feature Priority

  1. Which validations are MUST-HAVE for v1?

    • Pin conflicts (Output-Output)? βœ…

    • Duplicate references? βœ…

    • Dangling wires? βœ…

    • Power validation? βœ…

    • Hierarchical validation? ❓

    • Bus validation? ❓

    • Advanced routing checks? ❓

  2. Performance vs. Completeness

    • Is <100ms for 100 components acceptable?

    • Should we optimize for speed or thoroughness?

    • Is incremental/cached validation needed?

API Design

  1. Integration Points

    • Should Schematic.save() automatically run ERC?

    • Should we raise exceptions on errors or just return results?

    • Do we need both programmatic and CLI interfaces?

  2. Error Reporting

    • Text reports? JSON? HTML?

    • Should we generate visual annotations on schematic?

    • Integration with CI/CD systems?

Compatibility

  1. Third-Party Tools

    • Should output be compatible with KiCAD’s ERC report format?

    • Need to support external ERC rule files?

    • Integration with other EDA tools?

  2. Future Extensibility

    • Plugin system for custom rules?

    • AI-powered error detection?

    • Learning from user corrections?

Success Criteria

Minimum Viable Product (MVP)

  • βœ… Detects all major pin conflicts (Output-Output, Power shorts)

  • βœ… Finds duplicate references

  • βœ… Identifies dangling wires

  • βœ… Validates power connectivity

  • βœ… Clear, actionable error messages

  • βœ… <100ms for 100-component schematics

  • βœ… Comprehensive test coverage (>90%)

Full Release

  • βœ… All KiCAD ERC checks implemented

  • βœ… Configurable severity levels

  • βœ… Hierarchical validation

  • βœ… Bus validation

  • βœ… Custom rule support

  • βœ… Multiple output formats

  • βœ… Performance benchmarks met

Risks & Mitigation

Risk

Impact

Probability

Mitigation

KiCAD ERC changes

High

Medium

Version detection, compatibility layer

Performance issues

Medium

Low

Caching, incremental validation

False positives

High

Medium

Extensive testing, user feedback

Complex hierarchy

Medium

Medium

Phased approach, start simple

Pin type confusion

High

Medium

Clear documentation, examples

Dependencies

Internal

  • Symbol library cache (for pin type lookup)

  • Net connectivity analysis (for net tracing)

  • Component collections (for reference checking)

External

  • None (pure Python implementation)

Documentation Requirements

  1. User Guide

    • How to run ERC

    • Understanding error messages

    • Configuration examples

    • Common fixes

  2. API Reference

    • ElectricalRulesChecker class

    • ERCConfig options

    • ERCResult structure

    • All violation codes

  3. Developer Guide

    • Architecture overview

    • Adding custom rules

    • Pin conflict matrix

    • Performance considerations

Appendix

KiCAD Pin Type Reference

Complete enumeration with ERC behavior:

Type

Symbol

Must Connect

Can Drive

Notes

Input

I

Yes

No

Requires driver

Output

O

No

Yes

Can drive nets

Bidirectional

B

No

Yes

I/O port

Tri-state

T

No

Yes

Can be high-Z

Passive

P

Yes

No

Resistors, caps

Free/NIC

F

No

No

Not connected internally

Unspecified

U

No

No

Unknown, always warns

Power Input

W

Yes

No

VCC, GND

Power Output

w

No

Yes

Regulator output

Open Collector

C

No

Yes

Needs pull-up

Open Emitter

E

No

Yes

Needs pull-down

Not Connected

N

No

No

Must stay open


Document Version: 1.0 Last Updated: 2024-10-26 Author: Claude Code Status: Ready for Review