Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/plans/batcher-regression/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Batcher Regression Task

This task captures the planned RTL regression work for `protocols/batcher`.
It is a child effort of the broader `docs/plans/rtl-regression/` rollout and
uses the same Python-only cocotb methodology.

## Files
- `plan.md`: scope, staged test strategy, acceptance criteria, and risks.
- `progress.md`: factual status log for this task.
- `handoff.md`: short resume notes for the next coding session.
56 changes: 56 additions & 0 deletions docs/plans/batcher-regression/handoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Batcher Regression Handoff

## Resume Point
- Start from `docs/plans/batcher-regression/plan.md`.
- The first implementation target, standalone `AxiStreamBatcher` V2 leaf
behavior at the default 8-byte width, now has a passing cocotb regression.
- A narrow `AxiStreamBatcherAxil` common/async-clock wrapper regression is also
in place for register readback and control propagation.
- A focused `AxiStreamBatcherEventBuilder` two-source regression is in place for
INDEXED and ROUTED integration policy.
- Keep any further event-builder work targeted; the current pass is not an
exhaustive source-count or generic matrix.

## Expected File Areas
- RTL wrappers: `protocols/batcher/wrappers/`
- Tests: `tests/protocols/batcher/`
- Source RTL: `protocols/batcher/rtl/`

## Immediate Next Action
- If continuing Phase 1, add only focused leaf gaps such as a compact V1 case or
adverse forced-termination timing.
- If deepening Phase 2, keep it wrapper-specific: additional blowoff timing,
soft-reset timing, or other AXI-Lite control-surface edge cases. Avoid
duplicating leaf byte grammar tests.
- If deepening Phase 3, add only targeted event-builder integration cases such
as more source-count/generic breadth, alternate route tables, external-only
blowoff behavior, or bug-driven transition/bypass timing.

## Current Coverage
- `AxiStreamBatcher`: compacted V2 output, subframe metadata, multi-subframe
superframes, max-subframe/idle-gap/byte-threshold termination, forced
termination with terminal `EOFE`, output backpressure, and reset recovery.
- `AxiStreamBatcherAxil`: documented register reset/readback, threshold/count/gap
control propagation, `softRst`, and `blowoff` drop/recovery in both common and
independent AXI-Lite clock modes.
- `AxiStreamBatcherEventBuilder`: two-source INDEXED/ROUTED source selection,
TDEST remap including fixed/passthrough routed bits, null counting without
forwarding, timeout drop for a missing source followed by a clean later event,
shared-output backpressure while both inputs contribute to an event, bypass
skip/recovery, blowoff drop/recovery, routed transition-frame preemption,
alternate route-table remap, non-default transition TDEST, and visible
counter/status readback.

## Deferred Scope
- V1 and non-default stream-width leaf coverage.
- Event-builder source-count matrices and exhaustive transition/bypass timing
permutations.

## Validation Checklist
- Latest completed:
- `./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`
- `PYTHONPYCACHEPREFIX=/private/tmp/surf-pycache ./.venv/bin/python -m py_compile tests/protocols/batcher/batcher_test_utils.py tests/protocols/batcher/test_AxiStreamBatcher.py tests/protocols/batcher/test_AxiStreamBatcherAxil.py tests/protocols/batcher/test_AxiStreamBatcherEventBuilder.py`
- `./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher` (`6 passed`)
- Stale simulator process sweep, no leftover batcher `ghdl`/`pytest`/cocotb
processes observed
- `git diff --check`
163 changes: 163 additions & 0 deletions docs/plans/batcher-regression/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Batcher Regression Plan

## Objective
- Add focused, standalone cocotb regressions for the VHDL modules under
`protocols/batcher/`.
- Start with leaf-module behavior, then add AXI-Lite and event-builder coverage
only where it proves wrapper or integration behavior that the leaf tests do
not already prove.
- Keep executable stimulus and scoreboards in Python.
- Keep VHDL additions limited to thin cocotb-facing wrappers beside the batcher
RTL.

## Parent Methodology
- Follow `docs/plans/rtl-regression/plan.md`.
- New Python regression files need the standard SURF header, a module-specific
`Test methodology` block, and in-body comments explaining major cocotb steps.
- Checked-in VHDL wrappers need the standard SURF banner and short section
comments for bus shims, DUT hookup, and flattened/status wiring.
- Validate edited VHDL with `./.venv/bin/vsg -c vsg-linter.yml ...`.
- Validate Python syntax with the repo virtualenv interpreter.
- After any pytest/cocotb/GHDL run, sweep for stale simulator processes.

## Helper And Reuse Directives
- Keep shared batcher test code in `tests/protocols/batcher/batcher_test_utils.py`
or another clearly named helper in the same package.
- Do not duplicate flat AXI Stream endpoint drivers, ready/valid wait loops,
reset/clock setup, byte packing/unpacking helpers, V2 header/tail builders,
or common receive/backpressure monitors across individual test files.
- Prefer extending the batcher helper with narrow reusable utilities over adding
local helper functions to each module test.
- Keep module test files focused on scenario setup and assertions that are
specific to that module.
- Reuse existing repo helpers first where they already fit, especially
`tests/axi/utils.py` for sampled ready/valid handshakes and
`tests/common/regression_utils.py` for cocotb/GHDL launch plumbing.
- If AXI-Lite wrapper tests need repeated register transactions, add small
batcher-local register helpers or reuse existing AXI-Lite helpers rather than
spelling out raw bus operations in every test.
- Keep helper code from becoming a hidden DUT oracle: shared utilities may build
protocol bytes and perform mechanical handshakes, but module-specific policy
checks should remain visible in the tests that depend on them.

## Module Inventory
| Module | Role | Planned Coverage |
| --- | --- | --- |
| `AxiStreamBatcher` | Leaf stream batcher for V1/V2 superframes | Direct functional regression |
| `AxiStreamBatcherAxil` | AXI-Lite register/control wrapper around the leaf batcher | Register-map and control-path regression after the leaf contract is covered |
| `AxiStreamBatcherEventBuilder` | Multi-input event-builder wrapper above the batcher | Integration regression for source selection, TDEST remap, timeout/drop behavior, and counters |

## Phase 1: Leaf Batcher Contract
Target `protocols/batcher/rtl/AxiStreamBatcher.vhd` through a thin wrapper that
exposes flat AXI Stream ports, control generics, and runtime termination knobs.

Planned checks:
- V2 superframe header formatting, including version, width, and sequence byte.
- V2 compacted byte stream through the `AxiStreamGearbox` path: header, payload,
and 7-byte subframe tail with no zero-padding bytes.
- Subframe tail metadata: byte count, `TDEST`, first-byte `TUSER`, and last-byte
`TUSER`.
- Termination modes: `maxSubFrames`, `maxClkGap`, `superFrameByteThreshold`, and
`forceTerm` where the EOFE bit placement can be asserted cleanly.
- Multiple subframes inside one superframe, including non-word-aligned payloads.
- Output backpressure stability while `M_AXIS_TREADY` is low.
- Reset/idleness recovery after a partial or pending superframe.
- Curated generic sweep after the default V2 case is stable:
- V2 at the default 8-byte width first.
- V1 with a power-of-two stream width if the compacted expected model remains
readable.
- Avoid broad Cartesian sweeps unless a bug or high-risk branch justifies them.

Acceptance for Phase 1:
- One checked-in wrapper under `protocols/batcher/wrappers/` if an existing shim
is insufficient.
- Tests under `tests/protocols/batcher/`.
- Focused validation passes for the batcher test file.
- `vsg`, `py_compile`, and `git diff --check` are clean.

## Phase 2: AXI-Lite Wrapper
Target `AxiStreamBatcherAxil` only after Phase 1 establishes the underlying
stream contract.

Planned checks:
- Reset values and readback for:
- `superFrameByteThreshold` at `0x00`
- `maxSubFrames` at `0x04`
- `maxClkGap` at `0x08`
- idle/version status at `0x0C`
- Writes to the threshold/count/gap registers affect subsequent superframe
termination behavior.
- `softRst` at `0xFC` returns the stream path to idle and clears any pending
partial superframe.
- `blowoff` at `0xF8` accepts/drops inbound traffic without emitting malformed
output.
- `COMMON_CLOCK_G=true` first; async AXI-Lite crossing can be deferred unless the
wrapper proves stable under the local GHDL flow.

Acceptance for Phase 2:
- AXI-Lite helper reuse from existing test utilities where practical.
- Tests prove register-visible behavior and one stream-side effect per control
register family.
- No duplicate leaf-batcher packet grammar tests unless they are necessary to
prove AXI-Lite control propagation.

## Phase 3: Event Builder
Target `AxiStreamBatcherEventBuilder` as an integration layer, not as another
full batcher grammar test.

Planned checks:
- Indexed mode source selection and output `TDEST` remap.
- Routed mode `TDEST_ROUTES_G` behavior for fixed and passthrough bits.
- Transition-frame handling through `TRANS_TDEST_G`.
- Bypass/drop behavior and related counters.
- Timeout behavior: stale or missing source data increments timeout-drop counters
and does not corrupt later accepted events.
- AXI-Lite readback for status/counters that are visible through the event
builder.
- Backpressure on the shared output while multiple inputs are ready.

Acceptance for Phase 3:
- Event-builder tests use small `NUM_SLAVES_G` cases first.
- The Python expected model focuses on arbitration/remap/drop policy and reuses
leaf-batcher byte-stream helpers for the final output shape.
- Known intentionally untested branches are recorded in `progress.md`.

## Out Of Scope
- Exhaustive generic Cartesian sweeps.
- Throughput/performance benchmarking.
- Replacing the existing RTL register map or public Python APIs.
- Vendor or mixed-language simulator work.
- Re-proving every leaf-batcher byte in higher-level wrappers when a narrower
control/integration assertion is sufficient.

## Validation Commands
Planned focused commands:

```bash
./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/*.vhd
PYTHONPYCACHEPREFIX=/private/tmp/surf-pycache ./.venv/bin/python -m py_compile tests/protocols/batcher/*.py
./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher
git diff --check
```

After simulator runs, sweep for stale processes with an explicit `ps`/`rg`
filter and kill only leftover run trees.

## Risks
- V2 output uses `AxiStreamGearbox`, so expected data must model compacted bytes
rather than raw input beats.
- `forceTerm` sets SSI EOFE through `TUSER_FIRST_LAST_C`; bit placement should
be checked against SURF helpers before asserting exact raw `TUSER` bits.
- The byte threshold logic counts in word-sized internal increments; tests
should assert externally visible termination behavior, not an over-precise
internal byte accounting model.
- Event-builder scope can grow quickly; keep it to integration-specific policy
and avoid recreating a complete event-system simulation.

## Done Criteria
- The batcher task docs identify what is covered, what is intentionally deferred,
and how to resume.
- Focused batcher regressions pass locally.
- New wrappers and tests follow the RTL regression style rules.
- `docs/plans/rtl-regression/progress.md` and `handoff.md` are updated only
after validated batcher work lands in the working tree.
88 changes: 88 additions & 0 deletions docs/plans/batcher-regression/progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Batcher Regression Progress

## Status
- Current phase: Phase 3 event-builder implementation completed for the first
focused two-source slice.
- Current implementation gate: `AxiStreamBatcher` V2 8-byte leaf coverage,
`AxiStreamBatcherAxil` common-clock plus async AXI-Lite register/control
coverage, and `AxiStreamBatcherEventBuilder` two-source INDEXED/ROUTED
integration coverage are validated locally.
- Current target: keep future work focused on intentionally deferred generic
breadth or specific bug-driven edge cases.

## Decisions
- Use a standalone leaf-first strategy.
- Use Python/cocotb for executable stimulus and scoreboards.
- Use a thin checked-in wrapper only when the native record interface is too
awkward for direct cocotb stimulus.
- Keep high-level wrapper tests focused on register/control/integration policy
instead of re-proving the full leaf packet grammar.

## Draft Work In This Session
- Added a thin cocotb-facing wrapper at
`protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd`.
- Added a common/async-clock AXI-Lite wrapper at
`protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd`.
- Added a two-source event-builder wrapper at
`protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`.
- Added shared batcher helpers in
`tests/protocols/batcher/batcher_test_utils.py`.
- Added a standalone leaf regression in
`tests/protocols/batcher/test_AxiStreamBatcher.py`.
- Added an AXI-Lite wrapper regression in
`tests/protocols/batcher/test_AxiStreamBatcherAxil.py`.
- Added an event-builder regression in
`tests/protocols/batcher/test_AxiStreamBatcherEventBuilder.py`.
- Covered V2 compacted output for the default 8-byte width: superframe header
bytes, subframe payload/tail bytes, multiple subframes per superframe,
termination by max-subframe count, idle gap, byte threshold, forced
termination with terminal `EOFE`, output backpressure stability, and reset
recovery after a partial superframe.
- Covered `AxiStreamBatcherAxil` reset/readback for the documented register map,
control propagation for max-subframe count, byte threshold, and clock gap,
`softRst` recovery from a partial superframe, and `blowoff` accept/drop
behavior followed by normal recovery traffic in both common-clock and
independent AXI-Lite clock configurations. The async readback assertions allow
the CDC bridge to settle to the expected value before checking each register.
- Covered `AxiStreamBatcherEventBuilder` in small two-source INDEXED and ROUTED
configurations: reset/status/readback, source selection, TDEST remap including
fixed/passthrough routed bits, null source counting without forwarding,
timeout drop behavior for a missing source followed by a clean later event,
shared-output backpressure while both inputs contribute to an event, bypass
skip/recovery behavior, blowoff drop/recovery behavior, and routed
transition-frame preemption through `TRANS_TDEST_G`. The routed sweep now
includes one alternate route-table shape and non-default transition TDEST.
- The event-builder tests deliberately reuse the leaf byte-stream helpers for
final batcher output shape instead of duplicating the full packet grammar.

## Deferred Scope
- Phase 1 is intentionally limited to V2 at the default 8-byte width. V1 and
non-default stream widths remain targeted follow-ups if future changes touch
those branches.
- Phase 3 is intentionally limited to a two-source event-builder wrapper.
Broader source-count matrices and exhaustive transition/bypass timing
permutations remain out of the current pass.

## Validation
- `./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`
passed with zero violations.
- `PYTHONPYCACHEPREFIX=/private/tmp/surf-pycache ./.venv/bin/python -m py_compile tests/protocols/batcher/batcher_test_utils.py tests/protocols/batcher/test_AxiStreamBatcher.py tests/protocols/batcher/test_AxiStreamBatcherAxil.py tests/protocols/batcher/test_AxiStreamBatcherEventBuilder.py`
passed.
- `./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher` passed with
`6 passed`.
- Stale simulator process sweep did not show leftover `ghdl`, `pytest`, or
cocotb batcher processes.
- `git diff --check` passed for tracked changes. The new batcher files are
still untracked, so whitespace on those files was also covered by `vsg` and
`py_compile`.

## Next Steps
1. Keep Phase 1 intentionally narrow unless a change touches the batcher leaf:
possible next leaf additions are a small V1/power-of-two-width case or more
adverse `forceTerm` timing.
2. If Phase 2 deepens, stay focused on wrapper-specific behavior such as
additional malformed/blowoff or reset timing; do not duplicate the full leaf
byte grammar.
3. If Phase 3 deepens, add only targeted event-builder cases such as more
source-count/generic breadth, external-only blowoff behavior, or bug-driven
transition/bypass timing.
Loading
Loading