From 75f489cddf1153f5b351662123521c04199309ab Mon Sep 17 00:00:00 2001 From: Daniel Keller Date: Thu, 13 Aug 2026 10:25:32 +0200 Subject: [PATCH] frontend: Report the documented stall polarity in the inst64 events The Snitch cluster defines these counters, and it defines them explicitly: dma_r_stall = 12 "Incremented whenever r_ready = 1 but r_valid = 0" dma_w_stall = 13 "Incremented whenever w_valid = 1 but w_ready = 0" dma_buf_w_stall = 14 "Incremented whenever w_ready = 1 but w_valid = 0" dma_buf_r_stall = 15 "Incremented whenever r_valid = 1 but r_ready = 0" The two lines removed here are, verbatim, the definitions of 14 and 15 sitting in the fields for 12 and 13, where they overrode the correct assignments made earlier in the same always_comb. Both pairs arrived in one commit that flattened if-guarded set-only writes into unconditional ones, so the later pair silently won. Removing them restores 12 and 13. The asymmetry that remains is the intended one: iDMA drives w_valid but r_ready, so waiting on the fabric is valid without ready on AW, AR and W, and ready without valid on R. The inst64 testbench asserted the old behaviour, so its two goldens move with the RTL. Verified both ways: the testbench passes with this change and fails with "events.EvRStall disagrees with the AXI pins" if either side is reverted. --- src/frontend/inst64/idma_inst64_events.sv | 4 ---- test/frontend/tb_idma_inst64_axi_copy.sv | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/frontend/inst64/idma_inst64_events.sv b/src/frontend/inst64/idma_inst64_events.sv index 0a1eb05f..59d0a5ea 100644 --- a/src/frontend/inst64/idma_inst64_events.sv +++ b/src/frontend/inst64/idma_inst64_events.sv @@ -91,10 +91,6 @@ module idma_inst64_events #( events_o.obi_wr_req = obi_req_i.req && obi_res_i.gnt && obi_req_i.a.we; events_o.obi_rd_req = obi_req_i.req && obi_res_i.gnt && ~obi_req_i.a.we; - // buffer - events_o.w_stall = axi_rsp_i.w_ready && !axi_req_i.w_valid; - events_o.r_stall = !axi_req_i.r_ready && axi_rsp_i.r_valid; - // busy events_o.dma_busy = busy_i; end diff --git a/test/frontend/tb_idma_inst64_axi_copy.sv b/test/frontend/tb_idma_inst64_axi_copy.sv index bdbe87fd..a41eecb8 100644 --- a/test/frontend/tb_idma_inst64_axi_copy.sv +++ b/test/frontend/tb_idma_inst64_axi_copy.sv @@ -87,12 +87,12 @@ module tb_idma_inst64_axi_copy; ev_field_ok[EvRDone ] = ev.r_done === (bus_req.r_ready && bus_res.r_valid); // r_bw duplicates r_done in the RTL; compare it to the pins, never to ev.r_done. ev_field_ok[EvRBw ] = ev.r_bw === (bus_req.r_ready && bus_res.r_valid); - ev_field_ok[EvRStall ] = ev.r_stall === (!bus_req.r_ready && bus_res.r_valid); + ev_field_ok[EvRStall ] = ev.r_stall === (bus_req.r_ready && !bus_res.r_valid); ev_field_ok[EvWValid ] = ev.w_valid === bus_req.w_valid; ev_field_ok[EvWReady ] = ev.w_ready === bus_res.w_ready; ev_field_ok[EvWDone ] = ev.w_done === w_hs; - ev_field_ok[EvWStall ] = ev.w_stall === (bus_res.w_ready && !bus_req.w_valid); + ev_field_ok[EvWStall ] = ev.w_stall === (bus_req.w_valid && !bus_res.w_ready); ev_field_ok[EvBytes ] = ev.num_bytes_written === (w_hs ? 32'($countones(bus_req.w.strb)) : 32'd0);