Skip to content

AXI4-Lite: hold BVALID/RVALID until ready in bus-error mode - #88

Merged
tgingold-cern merged 1 commit into
tgingold-cern:masterfrom
dsiquantum:fix-axi4lite-buserr-handshake
Aug 25, 2026
Merged

tgingold-cern merged 1 commit into
tgingold-cern:masterfrom
dsiquantum:fix-axi4lite-buserr-handshake

Conversation

@dsiquantum

Copy link
Copy Markdown
Contributor

Summary

Fixes #86.

With bus-error enabled, the AXI4-Lite write and read response channels made BVALID/RVALID a one-cycle pulse and could deadlock the slave:

  • The sync process cleared axi_wdone/axi_rdone unconditionally every cycle, and the clear-on-handshake was gated behind if not opts.bus_error, so it was dropped.
  • BVALID/RVALID therefore asserted for a single cycle after the internal ack, instead of being held until the master asserted BREADY/RREADY (AXI4-Lite A3.2.1).
  • A master that was not immediately ready lost the response. And since AWREADY/WREADY (resp. ARREADY) are only re-asserted once the response is accepted (axi_wdone & bready), the slave then wedged permanently.

Fix

Drive the handshake in bus-error mode exactly as without it:

  • Hold axi_wdone/axi_rdone until the handshake (restore the clear on VALID & READY, remove the unconditional per-cycle clear).
  • Register BRESP/RRESP (set on ack, held until accepted) so the response value is stable while VALID is high — the previous per-cycle reset of axi_werr/axi_rerr would otherwise change the response while VALID was held.

The existing reset-time behaviour is preserved: accesses issued while in reset are still completed with SLVERR rather than stalling. BVALID/RVALID are forced high from the reset signal during reset, so out of reset VALID reflects only a real, held response (no phantom response leaks past reset).

Non-bus-error output is unchanged.

Testing

  • cd proto && python tests.py — all generation tests pass (output unchanged except the bus-error golden).
  • testfiles/tb/buserr_axi4_tb.vhdl: the existing testbench used an always-ready master, so it could never observe the pulse/deadlock. Extended it to hold BREADY/RREADY low for several cycles and assert that VALID stays high with stable DATA/RESP.
  • Verified under GHDL:
    • Against this change: the full testbench (including the new delayed-ready cases) passes.
    • Against the previous generator output: the new assertions fail (RVALID dropped before RREADY), i.e. the test genuinely catches the bug.

With bus-error enabled, the write and read response channels cleared
axi_wdone/axi_rdone unconditionally every cycle and no longer cleared
them on the BREADY/RREADY handshake. BVALID/RVALID therefore asserted
for a single cycle after the internal ack instead of being held until
the master accepted the response (AXI4-Lite A3.2.1). A master that was
not immediately ready lost the response, and because AWREADY/WREADY
(resp. ARREADY) are only re-asserted once the response is accepted, the
slave then deadlocked.

Drive the handshake in bus-error mode exactly as without it: hold
axi_wdone/axi_rdone until the handshake, and register BRESP/RRESP (set
on ack, held until accepted) so the response is stable while VALID is
high. The reset-time behaviour (accept accesses and return SLVERR while
in reset) is preserved by forcing BVALID/RVALID high from the reset
signal, so out of reset VALID reflects only a real response.

The existing bus-error testbench used an always-ready master and could
not observe the deadlock; extend it to hold BREADY/RREADY low for
several cycles and check VALID stays asserted with stable data/response.
That check fails against the previous output and passes with this change.

Fixes tgingold-cern#86
@tgingold-cern
tgingold-cern merged commit b0dccdd into tgingold-cern:master Aug 25, 2026
2 checks passed
@tgingold-cern

Copy link
Copy Markdown
Owner

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AXI4-Lite: bus-error makes BVALID/RVALID single-cycle pulses and can deadlock the slave

2 participants