Skip to content

Commit e8ae637

Browse files
bengineerdruck314
authored andcommitted
docs: add batcher regression plan and handoff notes
1 parent f637a21 commit e8ae637

4 files changed

Lines changed: 317 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Batcher Regression Task
2+
3+
This task captures the planned RTL regression work for `protocols/batcher`.
4+
It is a child effort of the broader `docs/plans/rtl-regression/` rollout and
5+
uses the same Python-only cocotb methodology.
6+
7+
## Files
8+
- `plan.md`: scope, staged test strategy, acceptance criteria, and risks.
9+
- `progress.md`: factual status log for this task.
10+
- `handoff.md`: short resume notes for the next coding session.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Batcher Regression Handoff
2+
3+
## Resume Point
4+
- Start from `docs/plans/batcher-regression/plan.md`.
5+
- The first implementation target, standalone `AxiStreamBatcher` V2 leaf
6+
behavior at the default 8-byte width, now has a passing cocotb regression.
7+
- A narrow `AxiStreamBatcherAxil` common/async-clock wrapper regression is also
8+
in place for register readback and control propagation.
9+
- A focused `AxiStreamBatcherEventBuilder` two-source regression is in place for
10+
INDEXED and ROUTED integration policy.
11+
- Keep any further event-builder work targeted; the current pass is not an
12+
exhaustive source-count or generic matrix.
13+
14+
## Expected File Areas
15+
- RTL wrappers: `protocols/batcher/wrappers/`
16+
- Tests: `tests/protocols/batcher/`
17+
- Source RTL: `protocols/batcher/rtl/`
18+
19+
## Immediate Next Action
20+
- If continuing Phase 1, add only focused leaf gaps such as a compact V1 case or
21+
adverse forced-termination timing.
22+
- If deepening Phase 2, keep it wrapper-specific: additional blowoff timing,
23+
soft-reset timing, or other AXI-Lite control-surface edge cases. Avoid
24+
duplicating leaf byte grammar tests.
25+
- If deepening Phase 3, add only targeted event-builder integration cases such
26+
as more source-count/generic breadth, alternate route tables, external-only
27+
blowoff behavior, or bug-driven transition/bypass timing.
28+
29+
## Current Coverage
30+
- `AxiStreamBatcher`: compacted V2 output, subframe metadata, multi-subframe
31+
superframes, max-subframe/idle-gap/byte-threshold termination, forced
32+
termination with terminal `EOFE`, output backpressure, and reset recovery.
33+
- `AxiStreamBatcherAxil`: documented register reset/readback, threshold/count/gap
34+
control propagation, `softRst`, and `blowoff` drop/recovery in both common and
35+
independent AXI-Lite clock modes.
36+
- `AxiStreamBatcherEventBuilder`: two-source INDEXED/ROUTED source selection,
37+
TDEST remap including fixed/passthrough routed bits, null counting without
38+
forwarding, timeout drop for a missing source followed by a clean later event,
39+
shared-output backpressure while both inputs contribute to an event, bypass
40+
skip/recovery, blowoff drop/recovery, routed transition-frame preemption,
41+
alternate route-table remap, non-default transition TDEST, and visible
42+
counter/status readback.
43+
44+
## Deferred Scope
45+
- V1 and non-default stream-width leaf coverage.
46+
- Event-builder source-count matrices and exhaustive transition/bypass timing
47+
permutations.
48+
49+
## Validation Checklist
50+
- Latest completed:
51+
- `./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`
52+
- `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`
53+
- `./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher` (`6 passed`)
54+
- Stale simulator process sweep, no leftover batcher `ghdl`/`pytest`/cocotb
55+
processes observed
56+
- `git diff --check`
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Batcher Regression Progress
2+
3+
## Status
4+
- Current phase: Phase 3 event-builder implementation completed for the first
5+
focused two-source slice.
6+
- Current implementation gate: `AxiStreamBatcher` V2 8-byte leaf coverage,
7+
`AxiStreamBatcherAxil` common-clock plus async AXI-Lite register/control
8+
coverage, and `AxiStreamBatcherEventBuilder` two-source INDEXED/ROUTED
9+
integration coverage are validated locally.
10+
- Current target: keep future work focused on intentionally deferred generic
11+
breadth or specific bug-driven edge cases.
12+
13+
## Decisions
14+
- Use a standalone leaf-first strategy.
15+
- Use Python/cocotb for executable stimulus and scoreboards.
16+
- Use a thin checked-in wrapper only when the native record interface is too
17+
awkward for direct cocotb stimulus.
18+
- Keep high-level wrapper tests focused on register/control/integration policy
19+
instead of re-proving the full leaf packet grammar.
20+
21+
## Draft Work In This Session
22+
- Added a thin cocotb-facing wrapper at
23+
`protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd`.
24+
- Added a common/async-clock AXI-Lite wrapper at
25+
`protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd`.
26+
- Added a two-source event-builder wrapper at
27+
`protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`.
28+
- Added shared batcher helpers in
29+
`tests/protocols/batcher/batcher_test_utils.py`.
30+
- Added a standalone leaf regression in
31+
`tests/protocols/batcher/test_AxiStreamBatcher.py`.
32+
- Added an AXI-Lite wrapper regression in
33+
`tests/protocols/batcher/test_AxiStreamBatcherAxil.py`.
34+
- Added an event-builder regression in
35+
`tests/protocols/batcher/test_AxiStreamBatcherEventBuilder.py`.
36+
- Covered V2 compacted output for the default 8-byte width: superframe header
37+
bytes, subframe payload/tail bytes, multiple subframes per superframe,
38+
termination by max-subframe count, idle gap, byte threshold, forced
39+
termination with terminal `EOFE`, output backpressure stability, and reset
40+
recovery after a partial superframe.
41+
- Covered `AxiStreamBatcherAxil` reset/readback for the documented register map,
42+
control propagation for max-subframe count, byte threshold, and clock gap,
43+
`softRst` recovery from a partial superframe, and `blowoff` accept/drop
44+
behavior followed by normal recovery traffic in both common-clock and
45+
independent AXI-Lite clock configurations. The async readback assertions allow
46+
the CDC bridge to settle to the expected value before checking each register.
47+
- Covered `AxiStreamBatcherEventBuilder` in small two-source INDEXED and ROUTED
48+
configurations: reset/status/readback, source selection, TDEST remap including
49+
fixed/passthrough routed bits, null source counting without forwarding,
50+
timeout drop behavior for a missing source followed by a clean later event,
51+
shared-output backpressure while both inputs contribute to an event, bypass
52+
skip/recovery behavior, blowoff drop/recovery behavior, and routed
53+
transition-frame preemption through `TRANS_TDEST_G`. The routed sweep now
54+
includes one alternate route-table shape and non-default transition TDEST.
55+
- The event-builder tests deliberately reuse the leaf byte-stream helpers for
56+
final batcher output shape instead of duplicating the full packet grammar.
57+
58+
## Deferred Scope
59+
- Phase 1 is intentionally limited to V2 at the default 8-byte width. V1 and
60+
non-default stream widths remain targeted follow-ups if future changes touch
61+
those branches.
62+
- Phase 3 is intentionally limited to a two-source event-builder wrapper.
63+
Broader source-count matrices and exhaustive transition/bypass timing
64+
permutations remain out of the current pass.
65+
66+
## Validation
67+
- `./.venv/bin/vsg -c vsg-linter.yml -f protocols/batcher/wrappers/AxiStreamBatcherWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherAxilWrapper.vhd protocols/batcher/wrappers/AxiStreamBatcherEventBuilderWrapper.vhd`
68+
passed with zero violations.
69+
- `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`
70+
passed.
71+
- `./.venv/bin/python -m pytest -n 0 -q tests/protocols/batcher` passed with
72+
`6 passed`.
73+
- Stale simulator process sweep did not show leftover `ghdl`, `pytest`, or
74+
cocotb batcher processes.
75+
- `git diff --check` passed for tracked changes. The new batcher files are
76+
still untracked, so whitespace on those files was also covered by `vsg` and
77+
`py_compile`.
78+
79+
## Next Steps
80+
1. Keep Phase 1 intentionally narrow unless a change touches the batcher leaf:
81+
possible next leaf additions are a small V1/power-of-two-width case or more
82+
adverse `forceTerm` timing.
83+
2. If Phase 2 deepens, stay focused on wrapper-specific behavior such as
84+
additional malformed/blowoff or reset timing; do not duplicate the full leaf
85+
byte grammar.
86+
3. If Phase 3 deepens, add only targeted event-builder cases such as more
87+
source-count/generic breadth, external-only blowoff behavior, or bug-driven
88+
transition/bypass timing.

0 commit comments

Comments
 (0)