doc: design note for boundary-scan board test
Capture the plan for the strongest fit of the tool: feed a board netlist + the chain devices' BSDL and auto-generate/run boundary-scan interconnect tests (opens/shorts/stuck-at) + chain integrity. Covers inputs (netlist, BSDL, board.yaml), a new bstest/ layer whose central primitive is a whole-chain boundary register (lifts the current single-device assumption), the test types, the hard parts (safety/ contention, control-cell mapping, multi-device bit order, vector gen), and a 5-phase plan. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
88
CLAUDE.md
88
CLAUDE.md
@@ -416,6 +416,94 @@ images (huge SVF vectors) stay on the host or a large MCU.
|
||||
- 3.3 V GPIO → **level-shift** for 1.8 V JTAG targets (e.g. KCU105),
|
||||
same as on the host side.
|
||||
|
||||
## Boundary-scan board test (design note)
|
||||
|
||||
Not yet implemented — captured for the strongest fit of this tool.
|
||||
Guiding idea: **feed a board's netlist + the BSDL of each device on the
|
||||
JTAG chain, and automatically generate & run boundary-scan interconnect
|
||||
tests** (opens / shorts / stuck-at) plus chain-integrity checks. This is
|
||||
bs_explorer's real niche: a job badly served by open source (OpenOCD does
|
||||
almost no boundary scan; the good tools are commercial — XJTAG, JTAG
|
||||
Technologies — or legacy like UrJTAG) and where proprietary debuggers
|
||||
(ST-LINK, JTAGICE) don't play at all.
|
||||
|
||||
### What it tests (and doesn't)
|
||||
|
||||
Tests the **interconnect between BS-accessible pins**: drive a net from
|
||||
one boundary-scan output (EXTEST) and sense it on the other BS pins of
|
||||
that net. Detects opens (driven value not seen), shorts (two nets read
|
||||
alike when driven differently), stuck-at, and chain integrity. Cannot
|
||||
test nets with no BS pin, analog, or logic inside a chip. The Viveris
|
||||
`bus_over_jtag` (SPI/I²C/parallel over EXTEST) also enables testing
|
||||
*connected memory* as an optional cluster test.
|
||||
|
||||
### Inputs
|
||||
|
||||
1. **Netlist** — `net → [(refdes, pin), …]`. Start with a neutral format
|
||||
(CSV `net,refdes,pin` or YAML); a KiCad importer later.
|
||||
2. **BSDL** per scannable device (already handled by `bsdl_parser`:
|
||||
IDCODE, IR length, boundary register, per-cell function, pin↔cell,
|
||||
control/enable cell + disable value).
|
||||
3. **Board file (`board.yaml`)** — the glue: chain order (TDI→TDO),
|
||||
`refdes → bsdl`, netlist path, power/ground/clock nets to **exclude**,
|
||||
pull-up/down and series-resistor info, compliance/"safe" pins to force.
|
||||
|
||||
### Architecture (a new `bstest/` layer)
|
||||
|
||||
Reuses `jtag_core` (TAP, IR/DR shift), `bsdl_parser`, `bscan_*`, the YAML
|
||||
config pattern. **The central new primitive is a whole-chain boundary
|
||||
register**: today the Viveris pin API is single-device, but board test
|
||||
must drive/sense **all pins of all BS devices in one DR pass** — the
|
||||
chain BSR is the concatenation of every device's boundary register
|
||||
(others in BYPASS), in the right bit order. This is the enabler, and it
|
||||
**lifts the "single device on the chain" assumption** baked into the
|
||||
current `bscan_*` primitives — validate it early on a real 2-device
|
||||
chain.
|
||||
|
||||
Layers:
|
||||
- **A. Chain model** — ordered devices (BSDL + IDCODE + length), checked
|
||||
against a live `jtag_scan`; map `(refdes, pin) → device → BSDL port →
|
||||
global BSR bit(s)` (data cell + control/enable cell + disable value).
|
||||
- **B. Netlist ingest + net classification** — drivable (≥1 BS
|
||||
output/bidir), sense-only, untestable (no BS pin), excluded
|
||||
(power/clock).
|
||||
- **C. Vector generation** — give each testable net a unique binary code
|
||||
over N steps (N ≈ log2(#nets) to disambiguate every short; counting
|
||||
sequence). Per step: exactly **one driver per net** sets its bit, all
|
||||
other pins of the net go Hi-Z, shift the chain BSR (EXTEST), capture
|
||||
the input cells.
|
||||
- **D. Execution** — per step, build the full-chain DR, shift, capture.
|
||||
- **E. Diagnosis + report** — compare captured vs expected → open / short
|
||||
(with the net pair) / stuck-at / missing device; pass-fail per net +
|
||||
fault list (refdes/pin) + a **coverage report** (which pins are
|
||||
BS-testable).
|
||||
|
||||
### The hard parts (honest)
|
||||
|
||||
- **Safety**: EXTEST drives real pins on a powered board → contention
|
||||
risk (a BS driver against a non-BS output). The generator must
|
||||
guarantee **one active driver per net per step**, tristate the rest,
|
||||
exclude power/clock nets, and honour the BSDL **compliance patterns**.
|
||||
Treat this as a generator invariant, not an option.
|
||||
- **Control/bidir cells**: driving needs the enable cell set, sensing
|
||||
needs Hi-Z — all in the BSDL, but the mapping is the bulk of the work.
|
||||
- **Multi-device bit ordering** (TDI-side device shifts last; IR
|
||||
concatenation).
|
||||
- **Pulls / series resistors** skew sensing of undriven nets — model from
|
||||
`board.yaml`.
|
||||
- **Minimal, safe vector generation** (counting sequence / adjacency
|
||||
colouring) — well documented, but the "smart" piece.
|
||||
|
||||
### Phasing
|
||||
|
||||
| Phase | Content | Value |
|
||||
|-------|---------|-------|
|
||||
| 1 | Chain model + infrastructure test (IDCODE / BYPASS / chain length) | Immediate, mostly on existing code |
|
||||
| 2 | **Whole-chain BSR primitive** (drive/sense all pins, multi-device, EXTEST) | The enabler |
|
||||
| 3 | Netlist ingest + `(refdes,pin)→bit` mapping + net classification | — |
|
||||
| 4 | Interconnect vector gen + execution + open/short/stuck diagnosis + report | The deliverable |
|
||||
| 5 | Pulls/series, bidir, clusters, connected-memory tests via `bus_over_jtag` | Refinement |
|
||||
|
||||
## External references
|
||||
|
||||
- **BSCAN proxy bitstreams**: `quartiq/bscan_spi_bitstreams` (MIT).
|
||||
|
||||
Reference in New Issue
Block a user