axi: fix AxiStreamDmaV2 stray write burst at continued buffer boundary#1429
Open
ruck314 wants to merge 1 commit into
Open
axi: fix AxiStreamDmaV2 stray write burst at continued buffer boundary#1429ruck314 wants to merge 1 commit into
ruck314 wants to merge 1 commit into
Conversation
When a continued (multi-buffer) frame fills a buffer exactly on an AXI
burst boundary, AxiStreamDmaV2Write falls through MOVE_S -> IDLE_S ->
ADDR_S and issues one more burst at the next buffer's base address before
the MOVE_S overflow check triggers the continue. With maxSize already
zero this is a degenerate zero-length burst at the buffer boundary:
* Simulation: getAxiLen() is called with length 0 (typed
"integer range 1 to 4096") -> bound-check failure.
* Hardware: the off-by-one address is one element past the buffer.
For the on-chip HBM store-and-forward (HbmDmaBuffer/HbmDmaBufferV2,
which wrap AxiStreamDmaV2Fifo) it lands in the next contiguous buffer
and is masked, corrupting frames larger than the per-buffer frame size
(512 KiB on the XilinxVariumC1100). For the host PCIe DMA, where each
continued buffer is a separately-mapped page, it lands past the
mapping and raises an IOMMU IO_PAGE_FAULT once frames exceed the host
buffer size (2 MiB).
Detect the exact-fill-on-burst-boundary case at burst completion and
start the continue there (return the descriptor with continue set,
release the buffer) instead of re-entering ADDR_S, so no boundary burst
is emitted. contEn=0 keeps the legacy overflow/drop path unchanged.
Add two cocotb regression benches:
* test_AxiStreamDmaV2FifoLoopback.py -- streams a frame through
AxiStreamDmaV2Fifo (AxiRam-backed M_AXI) and checks it is re-merged
byte-for-byte; frames crossing the buffer boundary failed before.
* test_AxiStreamDmaV2WriteContinue.py -- drives a multi-buffer continue
with distinct, gapped buffer addresses and asserts every write burst
stays inside a declared buffer window (the IOMMU-fault signature).
Full tests/axi/dma suite passes (21 tests).
54aea67 to
11a9277
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AxiStreamDmaV2Writeemits a stray write burst at a continued buffer's boundary. When a continued (multi-buffer) frame fills a buffer exactly on an AXI burst boundary, the engine falls throughMOVE_S → IDLE_S → ADDR_Sand issues one more burst at the next buffer's base address before theMOVE_Soverflow check starts the continue. WithmaxSizealready zero this is a degenerate zero-length burst one element past the buffer.This manifests at two different boundaries on the
XilinxVariumC1100:HbmDmaBuffer/HbmDmaBufferV2(wrapAxiStreamDmaV2Fifo, on-chip HBM)BUFF_FRAME_WIDTH_G=19)AxiPcieDma→AxiStreamDmaV2Desc, host 2 MiB pages)cfgSize)IO_PAGE_FAULT+ PRBS errors > 2 MiBFix
Detect the exact-fill-on-burst-boundary case at burst completion and start the continue there (return the descriptor with
continueset, release the buffer) instead of re-enteringADDR_S, so no boundary burst is emitted.contEn=0keeps the legacy overflow/drop path unchanged. One change inAxiStreamDmaV2Write.vhd.Verification (cocotb)
Two new datapath benches; the stray boundary burst is directly detectable in simulation:
test_AxiStreamDmaV2FifoLoopback.py— streams a frame throughAxiStreamDmaV2Fifo(AXI-RAM-backedM_AXI) and checks it is re-merged byte-for-byte. A single-buffer frame passed before; any frame crossing the 256-byte buffer boundary failed. All pass after the fix.test_AxiStreamDmaV2WriteContinue.py— drives a multi-buffer continue with distinct, gapped buffer addresses and asserts every write burst stays inside a declared buffer window (a burst landing in the gap between buffers is the IOMMU-fault signature). 2- and 3-buffer cases pass after the fix; reproduced the stray boundary burst before it.Full
tests/axi/dmasuite: 21 passed.Hardware status
Both boundaries confirmed fixed on hardware (rebuilt
XilinxVariumC1100PrbsTester, PRBS software run):IO_PAGE_FAULTand no PRBS errors indmesg.