In software engineering, automated testing, continuous integration, and machine-verifiable requirements have been standard practice for decades. In hardware engineering, however, requirements frequently rot inside static PDF contracts or untracked Word documents:

  • An engineer increases an LDO voltage from $3.3\text{ V}$ to $3.6\text{ V}$ in a meeting, but forgets to update the microcontroller’s maximum operating ratings.
  • A client requests an operating temperature of $-40^\circ\text{C}$ to $+85^\circ\text{C}$, but a commercial $0^\circ\text{C}$-rated crystal is selected during schematic capture.
  • Interface connector pinouts change during mechanical design without alerting firmware developers.

To eliminate hardware drift, we designed Hardware Toolkit (hw-toolkit): an automated requirements gate for KiCad 9 where a structured YAML schema acts as the Single Source of Truth (SSOT) for schematics, layout constraints, and manufacturing outputs.


1. Core Rule: A Requirement Without Verification is a Wish

In hw-toolkit, requirements cannot be written as vague prose paragraphs. Every requirement must follow a strict JSON-Schema-backed structure:

requirements:
  - id: REQ-PWR-001
    title: 3.3V System Rail Transient Voltage Margin
    statement: The primary 3.3V buck regulator output shall maintain 3.30V +/- 3% under dynamic 0 to 2A load steps.
    domain: PWR
    priority: shall
    verification: oscilloscope_measurement
    verified_at: proto_bringup
    status: closed
    evidence: tests/reports/pwr_transient_revB.pdf
    derived_from: REQ-SYS-012

Key Schema Invariants

  1. Contractual Language (shall vs should): shall is contractual; failure to meet it blocks release. should is a negotiable design goal.
  2. Mandatory Verification: Every requirement must declare its verification method (inspection, simulation, measurement, analysis) and lifecycle phase (schematic_review, proto_bringup, dv_test). Unverifiable wishes are rejected at the gate.
  3. Evidence Requirement: A requirement cannot transition to status: closed without linking to verifiable evidence (a commit hash, simulation report, or test data).
  4. Upstream Derivation (derived_from): Derived requirements point to parent system requirements. If a customer changes an upstream requirement, the pipeline flags all invalidated child specs.

2. Automated Traceability & Gate Enforcement (reqcheck.py)

Using uv for instant, deterministic Python runtime execution, the pipeline runs automated gate checks before schematic freeze and layout completion:

uv run reqcheck.py --report traceability.md --strict
[PASS] Schema validation: 48 requirements loaded.
[PASS] Zero orphan derived_from references.
[PASS] 100% of closed requirements have documented evidence.
[INFO] Generating traceability matrix -> traceability.md

What reqcheck.py Catches That Schematics Miss

Error Code Violation Engineering Impact
TRACE-MISS Sub-requirement references non-existent parent Customer spec change was missed or improperly propagated
STATUS-UNVERIFIED Requirement marked closed without test evidence Incomplete hardware verification slip
IF-UNMAPPED Interface definition lacks corresponding net name Pinout discrepancy between schematic and hardware spec

3. Bi-Directional KiCad Integration

Requirements in a YAML file are only useful if they actively drive and constrain CAD tools. hw-toolkit includes automated bidirectional bridges into KiCad 9:

[ requirements.yaml (SSOT) ]
       │            ▲
 kicad-apply.py  kicad-extract.py
       │            │
       ▼            │
[ KiCad 9 Schematic (.kicad_sch) & Layout (.kicad_pcb) ]
       │
       ▼
[ kicad-netcheck.py (DRC vs Interface Validator) ]

1. kicad-apply.py: Pushing Specs to Layout

Instead of manually typing track widths and clearances into KiCad’s Board Setup:

  • Reads differential impedance rules ($Z_0 = 90,\Omega \pm 10%$ for USB, $100,\Omega$ for Ethernet).
  • Generates KiCad net classes (HighSpeed_USB, Power_5V, RF_Feed).
  • Writes clearances directly into .kicad_pcb design rules.

2. kicad-extract.py: Verifying Built Boards Against Specs

  • Parses .kicad_pcb files and extracts the actual copper stackup, layer counts, finished trace widths, via drill sizes, and placed components.
  • Compares actual component operating temperatures and footprints against requirements.yaml constraints.

3. kicad-netcheck.py: Interface Net Validation

  • Cross-checks connector pinouts and signal nets across multi-sheet schematics against formal IF-CONN-XXX interface definitions, preventing cross-wired UART, SPI, or power lines before fabricating prototype PCBs.

4. Automated CI/CD Configuration (gen-kibot.py)

Different hardware boards require different manufacturing configurations (2-layer hobby prototypes vs 6-layer high-speed controlled impedance boards).

Rather than hand-authoring complex kibot.yaml files, gen-kibot.py inspects the board’s layer stackup and fabrication notes from requirements.yaml and dynamically outputs an optimized KiBot CI/CD pipeline tailored specifically for that design.