Post-Silicon Validation

Verify that a physical microprocessor sample behaves in accordance with its datasheet. The tool connects to a target over a debug probe, reads documented registers/memory, and reports PASS / FAIL / INDETERMINATE against datasheet-derived expectations — with a citation for every check.

v1 target: STM32F103C8T6 (Arm Cortex-M3) over ST-Link V2 / SWD, via pyOCD. See docs/post_silicon_validation_prd.md for the full PRD.

Architecture

Four decoupled layers (PRD FR5.1) — swap any one without touching the others:

datasheets/*.yaml   →  Datasheet model   (data, not code — FR2.1)
psv/model/          →  Loader + schema   (validates the YAML into typed objects)
psv/engine/         →  Check engine      (reads target, judges PASS/FAIL/INDETERMINATE)
psv/transport/      →  Debug transport   (pyOCD | mock; abstract base = Transport)
psv/report/         →  Reporting         (JSON + Markdown, timestamped, cited)
psv/cli.py          →  CLI entry point

Setup

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt

Confirm the probe is seen: python -m pyocd list

Web Dashboard (Frontend + API)

The React dashboard talks to a FastAPI backend that wraps the same validation engine used by the CLI.

Start the API

.\.venv\Scripts\python.exe -m uvicorn psv.api:app --reload --port 8000

API docs: http://localhost:8000/docs

Start the frontend

In a second terminal:

cd frontend
npm install
npm run dev

Open http://localhost:5173 — the Vite dev server proxies /api to port 8000.

Copy .env.example to .env and set ANTHROPIC_API_KEY for document scan.

Active project model

Executable checks live in projects/postsiliconf1/model.yaml. The API and dashboard read this file — not hardcoded UI data. Upload + scan produces model.draft.yaml; activate it from the UI or POST /api/model/activate.

Real hardware workflow

  1. Connect ST-Link + STM32F103C8T6; verify python -m pyocd list
  2. Start API + frontend (below)
  3. Upload datasheet PDFs on Project Overview → Scan with Claude → Activate draft
  4. Open Peripheral Dashboard → Run Validation (uses pyOCD by default)
  5. Use Mock run (no hardware) only for offline dev

API endpoints

Method Path Description
GET /api/device ST-Link / SWD connection status
GET /api/project Target metadata from active model + uploaded docs
GET /api/peripherals Navigation derived from model groups
GET /api/peripherals/{id} Checks, coverage from latest report
POST /api/validate Run checks (mock: false default; optional peripheral_id)
POST /api/documents Upload PDF/TXT/MD
POST /api/documents/scan Claude extraction → draft model
POST /api/model/activate Promote draft to active model
GET /api/reports List report files

Usage (CLI)

# Validate on real hardware (active project model or legacy path)
.\.venv\Scripts\python.exe -m psv --datasheet projects\postsiliconf1\model.yaml

# Mock transport (values derived from model expectations)
.\.venv\Scripts\python.exe -m psv --datasheet projects\postsiliconf1\model.yaml --mock

Each run prints a summary and writes timestamped reports/<part>_<ts>.json and .md artifacts. Exit code is 0 only if every check passes (non-zero on any FAIL/INDETERMINATE), so it drops straight into CI or a bench script.

Adding checks (no code changes — FR5.2)

Edit the datasheet YAML. A check is: an access (how to read a value), an expect (how to judge it), and a citation.

- id: flash.size
  name: Flash size register (F_SIZE)
  access:
    op: read16          # read8 | read16 | read32
    address: 0x1FFFF7E0
    shift: 0            # optional: (raw >> shift) & mask
    mask: 0xFFFF        # optional bitfield mask
  expect:
    equals: 64          # or:  one_of: [..]   |   in_range: [min, max]
  unit: KB
  citation: "DS5319 — flash size register; C8 = 64 KB"

Safety

v1 is read-only (PRD NFR3). The pyOCD transport implements no writes, so no run can brick the target via flash or option-byte access.

Tests

.\.venv\Scripts\python.exe tests\test_engine.py
.\.venv\Scripts\python.exe tests\test_catalog.py
.\.venv\Scripts\python.exe tests\test_mock_memory.py
.\.venv\Scripts\python.exe tests\test_extract.py
.\.venv\Scripts\python.exe tests\smoke_api.py   # API on :8000
$env:PSV_HARDWARE=1; .\.venv\Scripts\python.exe tests\test_hardware.py   # optional bench

Most tests use mock transport. Set PSV_HARDWARE=1 only when ST-Link and target are connected.

Status

Active project model includes identification, flash size, RCC/GPIO/I2C reset-value checks (RM0008 / DS5319). Upload + Claude scan extends the model from your documents. Functional I2C/UART bus tests remain future work (bench wiring).

Share this project:

Updates