From 7271b13348e8e2f450d99d9162508ab600490e7c Mon Sep 17 00:00:00 2001 From: Flavien Solt Date: Fri, 8 May 2026 21:42:08 +0800 Subject: [PATCH] idma_rt_midend: track every arbiter handshake in the choice FIFO The RT midend funnels two request sources -- internal counter-driven events (nd_req_valid_int / nd_req_ready_int) and external bypass events (nd_req_valid_i / nd_req_ready_o) -- into one downstream port through stream_arbiter_bypass. Each outgoing request is tagged with a 1-bit `choice` (1 = ext, 0 = int) which is supposed to be pushed into i_stream_fifo so the response demux can route returning bursts back to the bypass user (choice=1) or discard them at int_valid (choice=0, internal RT events have no consumer). The current push/pop conditions only match the *external* side of the handshake: .valid_i ( nd_req_valid_i & nd_req_ready_o ) .ready_i ( burst_rsp_valid_o & burst_rsp_ready_i ) So an internal RT event passes through stream_arbiter_bypass and reaches the downstream port (nd_req_valid_o), but nothing is pushed into the FIFO. Likewise, when the corresponding response returns and the demux routes it to int_valid, the FIFO is not popped. The FIFO is therefore systematically out of sync with the response stream whenever ext and int events interleave: it contains only ext entries while burst_rsp_valid_i carries a mix. Replace the conditions with the arbiter-output and demux-input handshakes so every outgoing request pushes once and every incoming response pops once: .valid_i ( nd_req_valid_o & nd_req_ready_i ) .ready_i ( burst_rsp_valid_i & burst_rsp_ready_o ) Reproducer (Verilator 5.046, NumEvents=1, NumOutstanding=8): release reset, enable event 0 with event_counts=5, issue an ext bypass, wait for the internal counter to fire, issue a second ext bypass. Send three downstream burst responses tagged 1, 0, 1 (the expected source of each event in issue order). Without the fix, the demux delivers the int-tagged response to burst_rsp_o (corrupting the bypass user's response stream) and silently routes one of the ext-tagged responses to int_valid (lost). With the fix, all three responses arrive at their declared source. The existing testbench (tb_idma_rt_midend.sv) ties the bypass input off (nd_req_valid_i = 1'b0) and leaves burst_rsp_o / burst_rsp_valid_o unconnected, so the mixed-traffic interleaving and the demux output side are never exercised; the bug therefore did not surface in CI. --- src/midend/idma_rt_midend.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/midend/idma_rt_midend.sv b/src/midend/idma_rt_midend.sv index 1ab81cc4..20197ec7 100644 --- a/src/midend/idma_rt_midend.sv +++ b/src/midend/idma_rt_midend.sv @@ -206,11 +206,11 @@ module idma_rt_midend #( .testmode_i ( 1'b0 ), .usage_o ( /* NC */ ), .data_i ( choice ), - .valid_i ( nd_req_valid_i & nd_req_ready_o ), + .valid_i ( nd_req_valid_o & nd_req_ready_i ), .ready_o ( /* HACK: NC */ ), .data_o ( choice_head ), .valid_o ( /* HACK: NC */ ), - .ready_i ( burst_rsp_valid_o & burst_rsp_ready_i ) + .ready_i ( burst_rsp_valid_i & burst_rsp_ready_o ) ); // arbitration of responses