|
| 1 | +# Batcher Regression Plan |
| 2 | + |
| 3 | +## Objective |
| 4 | +- Add focused, standalone cocotb regressions for the VHDL modules under |
| 5 | + `protocols/batcher/`. |
| 6 | +- Start with leaf-module behavior, then add AXI-Lite and event-builder coverage |
| 7 | + only where it proves wrapper or integration behavior that the leaf tests do |
| 8 | + not already prove. |
| 9 | +- Keep executable stimulus and scoreboards in Python. |
| 10 | +- Keep VHDL additions limited to thin cocotb-facing wrappers beside the batcher |
| 11 | + RTL. |
| 12 | + |
| 13 | +## Parent Methodology |
| 14 | +- Follow `docs/plans/rtl-regression/plan.md`. |
| 15 | +- New Python regression files need the standard SURF header, a module-specific |
| 16 | + `Test methodology` block, and in-body comments explaining major cocotb steps. |
| 17 | +- Checked-in VHDL wrappers need the standard SURF banner and short section |
| 18 | + comments for bus shims, DUT hookup, and flattened/status wiring. |
| 19 | +- Validate edited VHDL with `./.venv/bin/vsg -c vsg-linter.yml ...`. |
| 20 | +- Validate Python syntax with the repo virtualenv interpreter. |
| 21 | +- After any pytest/cocotb/GHDL run, sweep for stale simulator processes. |
| 22 | + |
| 23 | +## Helper And Reuse Directives |
| 24 | +- Keep shared batcher test code in `tests/protocols/batcher/batcher_test_utils.py` |
| 25 | + or another clearly named helper in the same package. |
| 26 | +- Do not duplicate flat AXI Stream endpoint drivers, ready/valid wait loops, |
| 27 | + reset/clock setup, byte packing/unpacking helpers, V2 header/tail builders, |
| 28 | + or common receive/backpressure monitors across individual test files. |
| 29 | +- Prefer extending the batcher helper with narrow reusable utilities over adding |
| 30 | + local helper functions to each module test. |
| 31 | +- Keep module test files focused on scenario setup and assertions that are |
| 32 | + specific to that module. |
| 33 | +- Reuse existing repo helpers first where they already fit, especially |
| 34 | + `tests/axi/utils.py` for sampled ready/valid handshakes and |
| 35 | + `tests/common/regression_utils.py` for cocotb/GHDL launch plumbing. |
| 36 | +- If AXI-Lite wrapper tests need repeated register transactions, add small |
| 37 | + batcher-local register helpers or reuse existing AXI-Lite helpers rather than |
| 38 | + spelling out raw bus operations in every test. |
| 39 | +- Keep helper code from becoming a hidden DUT oracle: shared utilities may build |
| 40 | + protocol bytes and perform mechanical handshakes, but module-specific policy |
| 41 | + checks should remain visible in the tests that depend on them. |
| 42 | + |
| 43 | +## Module Inventory |
| 44 | +| Module | Role | Planned Coverage | |
| 45 | +| --- | --- | --- | |
| 46 | +| `AxiStreamBatcher` | Leaf stream batcher for V1/V2 superframes | Direct functional regression | |
| 47 | +| `AxiStreamBatcherAxil` | AXI-Lite register/control wrapper around the leaf batcher | Register-map and control-path regression after the leaf contract is covered | |
| 48 | +| `AxiStreamBatcherEventBuilder` | Multi-input event-builder wrapper above the batcher | Integration regression for source selection, TDEST remap, timeout/drop behavior, and counters | |
| 49 | + |
| 50 | +## Phase 1: Leaf Batcher Contract |
| 51 | +Target `protocols/batcher/rtl/AxiStreamBatcher.vhd` through a thin wrapper that |
| 52 | +exposes flat AXI Stream ports, control generics, and runtime termination knobs. |
| 53 | + |
| 54 | +Planned checks: |
| 55 | +- V2 superframe header formatting, including version, width, and sequence byte. |
| 56 | +- V2 compacted byte stream through the `AxiStreamGearbox` path: header, payload, |
| 57 | + and 7-byte subframe tail with no zero-padding bytes. |
| 58 | +- Subframe tail metadata: byte count, `TDEST`, first-byte `TUSER`, and last-byte |
| 59 | + `TUSER`. |
| 60 | +- Termination modes: `maxSubFrames`, `maxClkGap`, `superFrameByteThreshold`, and |
| 61 | + `forceTerm` where the EOFE bit placement can be asserted cleanly. |
| 62 | +- Multiple subframes inside one superframe, including non-word-aligned payloads. |
| 63 | +- Output backpressure stability while `M_AXIS_TREADY` is low. |
| 64 | +- Reset/idleness recovery after a partial or pending superframe. |
| 65 | +- Curated generic sweep after the default V2 case is stable: |
| 66 | + - V2 at the default 8-byte width first. |
| 67 | + - V1 with a power-of-two stream width if the compacted expected model remains |
| 68 | + readable. |
| 69 | + - Avoid broad Cartesian sweeps unless a bug or high-risk branch justifies them. |
| 70 | + |
| 71 | +Acceptance for Phase 1: |
| 72 | +- One checked-in wrapper under `protocols/batcher/wrappers/` if an existing shim |
| 73 | + is insufficient. |
| 74 | +- Tests under `tests/protocols/batcher/`. |
| 75 | +- Focused validation passes for the batcher test file. |
| 76 | +- `vsg`, `py_compile`, and `git diff --check` are clean. |
| 77 | + |
| 78 | +## Phase 2: AXI-Lite Wrapper |
| 79 | +Target `AxiStreamBatcherAxil` only after Phase 1 establishes the underlying |
| 80 | +stream contract. |
| 81 | + |
| 82 | +Planned checks: |
| 83 | +- Reset values and readback for: |
| 84 | + - `superFrameByteThreshold` at `0x00` |
| 85 | + - `maxSubFrames` at `0x04` |
| 86 | + - `maxClkGap` at `0x08` |
| 87 | + - idle/version status at `0x0C` |
| 88 | +- Writes to the threshold/count/gap registers affect subsequent superframe |
| 89 | + termination behavior. |
| 90 | +- `softRst` at `0xFC` returns the stream path to idle and clears any pending |
| 91 | + partial superframe. |
| 92 | +- `blowoff` at `0xF8` accepts/drops inbound traffic without emitting malformed |
| 93 | + output. |
| 94 | +- `COMMON_CLOCK_G=true` first; async AXI-Lite crossing can be deferred unless the |
| 95 | + wrapper proves stable under the local GHDL flow. |
| 96 | + |
| 97 | +Acceptance for Phase 2: |
| 98 | +- AXI-Lite helper reuse from existing test utilities where practical. |
| 99 | +- Tests prove register-visible behavior and one stream-side effect per control |
| 100 | + register family. |
| 101 | +- No duplicate leaf-batcher packet grammar tests unless they are necessary to |
| 102 | + prove AXI-Lite control propagation. |
| 103 | + |
| 104 | +## Phase 3: Event Builder |
| 105 | +Target `AxiStreamBatcherEventBuilder` as an integration layer, not as another |
| 106 | +full batcher grammar test. |
| 107 | + |
| 108 | +Planned checks: |
| 109 | +- Indexed mode source selection and output `TDEST` remap. |
| 110 | +- Routed mode `TDEST_ROUTES_G` behavior for fixed and passthrough bits. |
| 111 | +- Transition-frame handling through `TRANS_TDEST_G`. |
| 112 | +- Bypass/drop behavior and related counters. |
| 113 | +- Timeout behavior: stale or missing source data increments timeout-drop counters |
| 114 | + and does not corrupt later accepted events. |
| 115 | +- AXI-Lite readback for status/counters that are visible through the event |
| 116 | + builder. |
| 117 | +- Backpressure on the shared output while multiple inputs are ready. |
| 118 | + |
| 119 | +Acceptance for Phase 3: |
| 120 | +- Event-builder tests use small `NUM_SLAVES_G` cases first. |
| 121 | +- The Python expected model focuses on arbitration/remap/drop policy and reuses |
| 122 | + leaf-batcher byte-stream helpers for the final output shape. |
| 123 | +- Known intentionally untested branches are recorded in `progress.md`. |
| 124 | + |
| 125 | +## Out Of Scope |
| 126 | +- Exhaustive generic Cartesian sweeps. |
| 127 | +- Throughput/performance benchmarking. |
| 128 | +- Replacing the existing RTL register map or public Python APIs. |
| 129 | +- Vendor or mixed-language simulator work. |
| 130 | +- Re-proving every leaf-batcher byte in higher-level wrappers when a narrower |
| 131 | + control/integration assertion is sufficient. |
| 132 | + |
| 133 | +## Validation Commands |
| 134 | +Planned focused commands: |
| 135 | + |
| 136 | +```bash |
| 137 | +./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/*.vhd |
| 138 | +PYTHONPYCACHEPREFIX=/private/tmp/surf-pycache ./.venv/bin/python -m py_compile tests/protocols/batcher/*.py |
| 139 | +./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher |
| 140 | +git diff --check |
| 141 | +``` |
| 142 | + |
| 143 | +After simulator runs, sweep for stale processes with an explicit `ps`/`rg` |
| 144 | +filter and kill only leftover run trees. |
| 145 | + |
| 146 | +## Risks |
| 147 | +- V2 output uses `AxiStreamGearbox`, so expected data must model compacted bytes |
| 148 | + rather than raw input beats. |
| 149 | +- `forceTerm` sets SSI EOFE through `TUSER_FIRST_LAST_C`; bit placement should |
| 150 | + be checked against SURF helpers before asserting exact raw `TUSER` bits. |
| 151 | +- The byte threshold logic counts in word-sized internal increments; tests |
| 152 | + should assert externally visible termination behavior, not an over-precise |
| 153 | + internal byte accounting model. |
| 154 | +- Event-builder scope can grow quickly; keep it to integration-specific policy |
| 155 | + and avoid recreating a complete event-system simulation. |
| 156 | + |
| 157 | +## Done Criteria |
| 158 | +- The batcher task docs identify what is covered, what is intentionally deferred, |
| 159 | + and how to resume. |
| 160 | +- Focused batcher regressions pass locally. |
| 161 | +- New wrappers and tests follow the RTL regression style rules. |
| 162 | +- `docs/plans/rtl-regression/progress.md` and `handoff.md` are updated only |
| 163 | + after validated batcher work lands in the working tree. |
0 commit comments