Circuit review & bench-test guide
AXL-004 — Protocol breakout / exerciser PMOD module
Document purpose#
This document explains the axl-004-breakout prototype at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on the generated schematic (generate_design.py, rev 0.1-schematic, 2026-07-12), the README, and the Digilent Pmod Interface Specification 1.2.0 (via the platform's verified notes, ../../pmod-common/PMOD-SPEC-NOTES.md).
The board is a design-stage prototype. The schematic is generated and ERC clean (reports/erc.rpt, 2026-07-12: 0 errors / 0 warnings, with KiCad's single-global-label, four-way-junction, SPICE-model, and footprint-filter checks ignored) and the netlist has been reviewed, but PCB layout has not started and no board has been fabricated or assembled. There is no first-article bench result of any kind. Every expected value below is a design target to verify, not proof that an assembled board works.
1. What the board does#
The board is a 12-pin PMOD pass-through exerciser — the sacrificial first-lab board of the AruviX lab line (catalog #4, level L1). A PMOD plug (J1) faces the host; a PMOD socket (J2) receives the module under test; every one of the 8 signal lines passes through a 100 Ω series resistor (R1–R8) on the way. All 8 DUT-side signals plus GND and 3V3 also land on J3, a labeled 1x10 probe header for logic-analyzer clips (AXL-001). 3V3 and GND pass straight through with no series elements. There are no ICs, so there is no decoupling and no configuration of any kind.
It teaches nothing by itself — it makes the other module's transactions visible, and it makes the first miswired lab burn a 100 Ω resistor instead of an FPGA pin (signal lines only; see Section 2).
Functional block diagram#
Host (ECP5/ULX3S PMOD port) Module under test
| ^
v |
J1 PMOD plug J2 PMOD socket
1-4,7-10 SIG1..SIG8 ── R1..R8 100R ── DUT1..DUT8 1-4,7-10
5,11 GND ──────────── straight ────── GND 5,11
6,12 3V3 ──────────── straight ────── 3V3 6,12
|
v
J3 probe header 1x10
1-8 DUT1..DUT8, 9 GND, 10 3V3
2. Safety and scope boundaries#
- The 100 Ω resistors protect only the 8 signal lines. The 3V3 and GND pass-throughs have no series element: a power-pin miswire (3V3 to GND, or a probe slip across pins 9/10 of J3) is a hard short seen directly by the host's 3.3 V rail. Use a host or bench supply with current limiting.
- The board is passive and protocol-agnostic: it imposes no voltage limits of its own. Whatever the host rail is (3.3 V per the PMOD spec; some hosts can switch the power pins to 5 V) appears unmodified on J2 and J3. Do not assume the board makes a 5 V module safe on a 3.3 V host or vice versa.
- 100 Ω in series changes signal behavior slightly (Sections 6 and 7): it adds to open-drain low-level voltage and forms an RC with load capacitance. Fine for lab-speed I2C/SPI/UART; do not put it in a path where an extra 100 Ω matters (analog, matched-impedance, high-speed).
- The deliberate-short survivability test in Section 9.C computes 33 mA and ~109 mW through a resistor rated 100 mW continuous — keep that test brief and monitored (Section 9.C shows the math and the limits).
- Earth-referenced oscilloscope grounds clip only to board GND (J3 pin 9).
- A clean pass-through is not a qualification of the module under test or of the host port; this board only carries and exposes their signals.
3. Power and control sequence#
There is almost none, and that is the design. The board is fully passive:
- 3V3 and GND arrive on J1 PMOD pins 6/12 and 5/11 and connect directly — no series resistance, no fuse, no decoupling, no regulation — to J2 pins 6/12 and 5/11 and to J3 pins 10 and 9.
- The 8 signal lines are live whenever the host drives them; the board adds only 100 Ω per line. There is no enable, no sequencing, and no state: the board is "on" the moment the host port is.
- The PMOD spec's assumption that a module draws no more than ~100 mA passes through unmodified; this board adds essentially nothing to that budget (its only loads are leakage).
4. Interfaces and pin maps#
All three connectors use PMOD logical numbering as generated by generate_design.py (the odd/even translation to physical header pins of the KiCad Conn_02x06_Odd_Even symbol is shown in the continuity matrix).
| PMOD pin | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| J1 (host plug) | SIG1 | SIG2 | SIG3 | SIG4 | GND | 3V3 | SIG5 | SIG6 | SIG7 | SIG8 | GND | 3V3 |
| J2 (DUT socket) | DUT1 | DUT2 | DUT3 | DUT4 | GND | 3V3 | DUT5 | DUT6 | DUT7 | DUT8 | GND | 3V3 |
| J3 pin | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| Net | DUT1 | DUT2 | DUT3 | DUT4 | DUT5 | DUT6 | DUT7 | DUT8 | GND | 3V3 |
Pass-through continuity matrix#
Per the PMOD spec (PMOD-SPEC-NOTES.md, "Pin numbering and orientation"), a host receptacle's numbering is the mirror image of a plug's, so module pin N meets host pin N. This board's J2 is a host-style receptacle for the DUT and generate_design.py gives it the identical PMOD-logical map as J1: host pin N maps straight through to DUT-module pin N. Note this mirroring is ultimately a layout-time property (connector orientation and footprint placement); the schematic can only name the pins. Verify at layout review and again with the matrix below on the first article.
The "hdr" columns are the physical pin numbers of the 2x06 connectors (PMOD_TO_HEADER in sensor_module_lib.py: PMOD 1–6 map to odd header pins 1,3,5,7,9,11; PMOD 7–12 map to even header pins 2,4,6,8,10,12).
| PMOD pos. | J1 net | J1 hdr | Path element | J2 net | J2 hdr | J3 pin | Expected DMM (plug pin to socket pin) |
|---|---|---|---|---|---|---|---|
| 1 | SIG1 | 1 | R1 100 Ω | DUT1 | 1 | 1 | 100 Ω ± 1% |
| 2 | SIG2 | 3 | R2 100 Ω | DUT2 | 3 | 2 | 100 Ω ± 1% |
| 3 | SIG3 | 5 | R3 100 Ω | DUT3 | 5 | 3 | 100 Ω ± 1% |
| 4 | SIG4 | 7 | R4 100 Ω | DUT4 | 7 | 4 | 100 Ω ± 1% |
| 5 | GND | 9 | direct | GND | 9 | 9 | < 1 Ω (continuity) |
| 6 | 3V3 | 11 | direct | 3V3 | 11 | 10 | < 1 Ω (continuity) |
| 7 | SIG5 | 2 | R5 100 Ω | DUT5 | 2 | 5 | 100 Ω ± 1% |
| 8 | SIG6 | 4 | R6 100 Ω | DUT6 | 4 | 6 | 100 Ω ± 1% |
| 9 | SIG7 | 6 | R7 100 Ω | DUT7 | 6 | 7 | 100 Ω ± 1% |
| 10 | SIG8 | 8 | R8 100 Ω | DUT8 | 8 | 8 | 100 Ω ± 1% |
| 11 | GND | 10 | direct | GND | 10 | 9 | < 1 Ω (same GND net as pos. 5) |
| 12 | 3V3 | 12 | direct | 3V3 | 12 | 10 | < 1 Ω (same 3V3 net as pos. 6) |
Cross-position expectations (the no-short half of the check): every J1-position-M to J2-position-N pair with M ≠ N must read open, with exactly four legitimate exceptions — 5↔11 and 11↔5 (both GND, < 1 Ω) and 6↔12 and 12↔6 (both 3V3, < 1 Ω). Any SIGm-to-SIGn or DUTm-to-DUTn reading below ~1 MΩ is a fault.
5. Component-by-component review#
Every reference designator in generate_design.py appears below. #FLG01 and #FLG02 are ERC power-flag pseudo-components on 3V3 and GND; they have no physical footprint and are listed only for completeness. No component on this board is DNP.
| Ref. | Part / value | Function and why needed | If absent/open | If shorted, wrong, or misassembled |
|---|---|---|---|---|
| J1 | 12-pin PMOD plug, right-angle 2x06 male (MPN TBD) | Host power and all 8 signals | Board does nothing | Offset or reversed insertion puts 3V3 on signal pins of the host port; verify orientation against the square-pad pin 1 convention |
| J2 | 12-pin PMOD socket, female 2x06 (PinSocket_2x06_P2.54mm_Vertical stock footprint; right-angle part preferred at layout, MPN TBD) | Receives the module under test with host-mirrored numbering so module pin N meets host pin N | No DUT connection; J3 still probes the R outputs | Wrong orientation/placement at layout breaks the mirror: signals land on the wrong DUT pins, worst case 3V3 onto a DUT signal pin |
| J3 | 1x10 vertical 2.54 mm male header (MPN TBD) | Labeled probe row: 1–8 = DUT1–DUT8, 9 = GND, 10 = 3V3, for AXL-001 clips and DMM work | No probe access; pass-through still works | Probe slip across pins 9/10 is a hard, unprotected 3V3–GND short; pins 1–8 slips are limited by the 100 Ω resistors only toward the host side |
| R1, R2, R3, R4, R5, R6, R7, R8 | 100 Ω 0603 1% (Yageo RC0603FR-07100RL), one per signal: R1 SIG1–DUT1 … R8 SIG8–DUT8 | Series survivability: limits fault current to 33 mA when a signal is shorted to GND or 3V3 (Section 9.C) and damps edges into wiring capacitance | That signal line is open — protocol dead on that pin (an easy first troubleshooting check) | A solder short across the pads removes protection on that line only; a wrong (larger) value degrades VOL margin on open-drain lines and slows edges; 0 Ω defeats the board's purpose |
| #FLG01 / #FLG02 | ERC power flags (3V3, GND) | Schematic ERC bookkeeping only — they declare the pass-through rails as driven so ERC can pass with no power source on the board | ERC warnings | Not applicable; no physical part |
6. Specification summary and design interpretation#
There is no silicon on this board, so the governing document is the Digilent Pmod Interface Specification 1.2.0 (revised 2017-10-05), <https://digilent.com/reference/_media/reference/pmod/pmod-interface-specification-1_2_0.pdf> (overview: <https://digilent.com/reference/pmod/start>), consulted via the platform's verified snapshot ../../pmod-common/PMOD-SPEC-NOTES.md (retrieved 2026-07-12) rather than a fresh fetch.
| Specification fact (Pmod 1.2.0) | Board-specific interpretation |
|---|---|
| 12-pin plug: pins 1–6 upper row, 7–12 lower row; pin 1 rightmost of the upper row viewed from module top; host receptacle numbering is the mirror image, so module pin N meets host pin N | J2 is a host-style receptacle: giving it the identical PMOD-logical map as J1 yields a straight-through pin-N-to-pin-N path. The physical mirror must be realized at layout (plug and socket on opposite edges, per the README) and verified per Section 4's matrix |
| 3.3 V LVCMOS/LVTTL expected; a host may switch both power pins together to 5.0 V | The board passes whatever the rail is; it neither converts nor protects power |
| Module draw should not be assumed above ~100 mA | This board adds ~0 to that; the DUT's draw passes through the J1/J2 power contacts |
| Standard host ports already carry ESD diodes and 200 Ω series resistors; high-speed ports omit them | On a standard port the total series is ~300 Ω per line (host 200 Ω + this board's 100 Ω). Budget VOL and edge rate for 300 Ω, not 100 Ω (see Section 7). On a raw/high-speed port this board's 100 Ω is the only series element |
| Interface types (GPIO/SPI/UART/I2C/…) define pin conventions only | The board is type-agnostic: it passes any type unmodified. Type 6 (I2C) modules carry their own pull-ups per the spec, which is what makes the VOL math in Section 7 work |
| Single-connector modules: max 0.8" wide, connector centered, >25 mil edge clearance for the retaining clip | Layout constraint to carry into the (not yet started) PCB phase — with two PMOD connectors on opposite edges this board must satisfy it at both |
Check the specification revision before layout; 1.2.0 is current per the platform notes.
7. Expected values before bench testing#
All are design targets calculated from the schematic, not measured results. DMM figures assume the meter's lead resistance is nulled.
| Quantity | Design target / calculated | What to measure |
|---|---|---|
| SIGn to DUTn (each of the 12 positions per Section 4 matrix) | 100 Ω ± 1% (signals); < 1 Ω (positions 5, 6, 11, 12) | DMM plug pin to socket pin |
| DUTn to J3 pin n (n = 1–8) | < 1 Ω | DMM socket pin to probe pin |
| J3 pin 9 to any GND pin (J1/J2 pos. 5, 11) | < 1 Ω | DMM |
| J3 pin 10 to any 3V3 pin (J1/J2 pos. 6, 12) | < 1 Ω | DMM |
| 3V3 to GND, unpowered, both polarities | Open (> 10 MΩ) — nothing on the board connects them | DMM |
| Any SIGm/DUTm to SIGn/DUTn, m ≠ n | Open (> 1 MΩ) | DMM, Section 9.B adjacency pass |
| Board's own 3V3 supply current | ~0 (leakage only; no active parts) | Bench supply, DUT removed |
| Drop across one 100 Ω at a CMOS input load (~1 µA) | < 0.1 mV — negligible | DMM across R while host drives |
| Drop across one 100 Ω at 8 mA static drive | 0.8 V — visible; heavy static loads distort levels | Same |
| I2C VOL at the DUT with a 4.7 kΩ module pull-up, host pulling low through 100 Ω (this board) + 200 Ω (standard host port) | 3.3 V x 300/5000 ≈ 0.20 V — well under the 0.8 V VIL | Scope on J3 while a transaction runs |
| Edge time constant into ~15 pF of DUT + probe load | 100 Ω x 15 pF = 1.5 ns — negligible at lab I2C/SPI/UART rates, marginal above ~20–30 MHz | Scope rise time on J3 |
| Deliberate signal short current (Section 9.C) | 3.3 V / 100 Ω = 33 mA ceiling; ~109 mW in the resistor | Bench DMM in series |
8. Manual schematic and assembly review checklist#
- Confirm J1 pin 1 orientation (square pad convention) and that the plug's upper row carries PMOD 1–6 per the spec figure.
- Confirm J2's orientation realizes the mirror: with a module inserted, its pin 1 must meet net DUT1. This is the single highest-consequence check on the board (layout not yet started — carry forward to layout review).
- Verify R1–R8 are all 100 Ω (a mixed reel would silently change one line's behavior) and that no resistor pad pair is solder-bridged.
- Verify J3 silkscreen labels match the schematic net names DUT1–DUT8, GND, 3V3 (README commitment; silkscreen does not exist until layout — carry forward).
- Confirm no solder bridges between adjacent connector pins on all three connectors (2.54 mm pitch; the powered consequences are worst at positions 5/6 and 11/12 where GND and 3V3 are neighbors).
- Confirm connector MPNs before ordering: all three are TBD in
generate_design.py(J1 right-angle plug, J2 right-angle socket, J3 vertical header).
9. Ordered bench-test procedure#
Stop at the first abnormal result. Record board serial, host identity, DUT module identity, and measured rail voltage.
Two bench contexts are used below. Context (a): the board sits between a 3.3 V PMOD port on the ECP5 host (ULX3S-class) and a real PMOD module (any released AruviX sensor module, e.g. an I2C type). Context (b): standalone on the bench with a DMM only — no power applied except where stated.
A. Unpowered inspection#
- Complete the Section 8 checklist under magnification.
- Measure 3V3-to-GND resistance in both polarities; anything below ~1 MΩ is a fault on this board (there is no legitimate DC path).
B. Standalone continuity and isolation (context b, unpowered)#
- Full pass-through buzz — all 12 positions. For each row of the Section 4 matrix, measure J1 position N to J2 position N: expect 100 Ω ± 1% on the eight signal positions and < 1 Ω on 5/6/11/12. Log all 12 readings.
- Adjacency no-short check. On each connector, measure every physically adjacent pin pair. In PMOD numbering the adjacent pairs are the ten within-row pairs (1-2, 2-3, 3-4, 4-5, 5-6, 7-8, 8-9, 9-10, 10-11, 11-12) and the six across-row pairs (1-7, 2-8, 3-9, 4-10, 5-11, 6-12): 16 pairs per connector. Expect open everywhere except 5-11 (GND–GND) and 6-12 (3V3–3V3), which legitimately read < 1 Ω.
- Cross-matrix sweep. Extend to the full 12x12: spot-check every J1-M-to-J2-N pair with M ≠ N (at minimum all pairs adjacent to a correct-path pin). Only the four same-net power combinations (5↔11, 6↔12) may conduct.
- Probe header. Buzz J3 pins 1–8 to J2 positions 1–4/7–10 (< 1 Ω), J3 pin 9 to GND, pin 10 to 3V3, and confirm J3 pins 1–8 read 100 Ω — not 0 — back to the corresponding J1 pin (proves the probe taps the DUT side of the resistors, as designed).
C. Series-R survivability test (context a, deliberate fault)#
This is the board's reason to exist, so it is tested deliberately — on one line, briefly, with the current measured. This protection exists only on the 8 signal lines. The 3V3 and GND pins have no series resistance; never extend this test to them.
- Configure one host pin (SIG1) as a static LVCMOS33 output driving high, at the lowest drive-strength setting (4 mA class). No DUT inserted.
- The math: an ideal 3.3 V source shorted to GND through R1 gives I = 3.3 V / 100 Ω = 33 mA and P = (3.3 V)² / 100 Ω ≈ 109 mW in R1. The RC0603FR-07100RL is rated 100 mW continuous — the ideal-case dissipation exceeds the rating by ~9%, so treat this as a seconds-to-minutes fault-survival budget, not a continuous operating point. In reality the FPGA driver saturates well below 33 mA at the 4 mA drive setting, so both figures are ceilings.
- Through a DMM on its current range, short J3 pin 1 (DUT1) to GND (J3 pin 9). Record the current (expect well under 33 mA; the ceiling itself only applies for an ideal driver). Hold for ~10 s, remove, and confirm R1 still measures 100 Ω and the line still passes data.
- Repeat with the host driving SIG1 low and the short taken from J3 pin 1 to 3V3 (J3 pin 10): the same 33 mA / 109 mW ceiling applies by symmetry, with the current now sunk by the FPGA pin.
- Pin-safety statement: 33 mA is the absolute worst-case ceiling and only flows if the driver can source/sink it; the configured 4 mA driver limits actual current far lower. Confirm the ECP5 per-pin absolute-maximum current against the Lattice ECP5 datasheet (FPGA-DS-02012) before running this powered test — this guide does not assert that number from memory. If in doubt, run the test with the DMM current reading watched live and abort above 20 mA.
- Do not batch-test all 8 lines simultaneously; one line at a time keeps total fault power trivial.
D. In-system pass-through with a real module (context a)#
- Host FPGA unconfigured, board inserted in the PMOD port, no DUT: measure 3V3 at J3 pin 10 (expect the host rail, ~3.30 V) and confirm J3 pins 1–8 float or sit at the host's idle levels.
- Insert a known-good PMOD module (an I2C-type AruviX sensor module is ideal: its own pull-ups exercise the open-drain case) into J2.
- Run that module's own bring-up procedure through this board. First pass criterion: the transaction succeeds exactly as it does without the breakout in the path.
- Clip the logic analyzer (AXL-001) or scope to J3 pins 1–8 with ground on pin 9 and capture a transaction. Verify: logic levels reach the DUT with VOL ≈ 0.2 V or better on open-drain lines (Section 7 math), clean monotonic edges, and no protocol errors introduced by probing.
- Measure the drop across one active line's resistor during traffic and confirm it matches I x 100 Ω for the observed load.
E. Rate limits (informative)#
- Increase SPI clock (if the DUT supports it) and note the rate at which the 100 Ω + capacitance filtering first corrupts data; record it as the board's practical ceiling for the kit documentation. This is characterization, not pass/fail.
10. Troubleshooting map#
| Symptom | First measurements | Likely areas |
|---|---|---|
| One signal dead through the board | Resistance J1-N to J2-N | Open R1–R8 (that line's resistor), cracked joint, connector pin |
| One signal reads 0 Ω plug-to-socket | Resistance across that R's pads | Solder bridge across the resistor — protection defeated on that line |
| All signals dead, power OK | J1 seating, orientation | Plug inserted offset/reversed; wrong port |
| Module works direct but not through the board | VOL on the affected line during traffic | Marginal open-drain budget (300 Ω total series on a standard host port), wrong (high) R value, or a DUT that cannot tolerate 100 Ω series |
| Signals land on wrong DUT pins | Full Section 4 matrix | J2 mirror broken at layout/assembly — the highest-consequence fault; do not use the board |
| 3V3-to-GND low resistance | Unpowered ohms both polarities | Solder bridge at positions 5/6 or 11/12 of any connector, or J3 9/10; no component fault can cause this (no parts on the rails) |
| Rail sags when board inserted | Current draw with and without DUT | Short as above, or the DUT itself — the board draws ~nothing |
| Probe header disagrees with socket | J3-n to J2-n continuity | J3 solder, mislabeled silkscreen (verify against net list, not labels) |
| Burnt/discolored resistor after a lab | Value check all 8 | A sustained short exceeded the ~100 mW rating — the board did its job; replace the resistor and check the FPGA pin still drives |
11. Bench record template#
| Field | Record |
|---|---|
| Board revision / serial | |
| Host (ECP5/ULX3S port, drive-strength config) | |
| DUT module identity | |
| Measured 3V3 rail | |
| 12-position pass-through readings (Section 9.B.1) | |
| Adjacency check result, 16 pairs x 3 connectors | |
| Cross-matrix (12x12) exceptions found | |
| J3 probe-side verification (100 Ω back to J1) | |
| Short test: line, drive setting, measured current, duration, R after | |
| In-system transaction result and capture path | |
| VOL / edge measurements | |
| Rate ceiling found (Section 9.E) | |
| Deviations, photos, raw-file paths | |
| Reviewer / date / disposition |
12. Review conclusion#
The design is as simple as a board can usefully be, and the simplicity is the safety argument: eight identical, individually checkable series resistors, three connectors, no ICs, no state, and a netlist a student can verify with a DMM in ten minutes. ERC is clean and every net, value, and reference designator in this guide traces directly to generate_design.py. The README's claims match the script, with two forward-looking items to keep honest: the silkscreen-labels-equal-net-names commitment and the plug/socket mirror both live in the PCB layout, which does not exist yet — the mirror in particular is the one fault mode that could put 3V3 on a DUT signal pin, and it cannot be verified until layout. The remaining open risks: the 100 Ω / 0603 combination dissipates ~109 mW in a sustained ideal short, marginally above its 100 mW continuous rating, so protection is rated for fault survival, not indefinite shorts; the power pins are deliberately unprotected and every user document must say so; all three connector MPNs are still TBD; the ECP5 per-pin current limit is cited as a check item, not a verified number; and every expected value in this guide is calculated from the schematic rather than measured on hardware.