From 01a7669f5b2fbaf50b60cae4cbf617b1a9f98ae6 Mon Sep 17 00:00:00 2001 From: Philippe Sauter Date: Sun, 31 May 2026 18:26:15 +0200 Subject: [PATCH 1/2] Fix mux R channel backpressure The mux could let the response route and upstream rready disagree while a destination R phase was backpressured. Derive rready from the existing response FIFO head so UseRReady keeps response payloads stable without adding owner state or buffering the payload. --- src/obi_mux.sv | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/obi_mux.sv b/src/obi_mux.sv index 5e17b5c..ea1105e 100644 --- a/src/obi_mux.sv +++ b/src/obi_mux.sv @@ -58,6 +58,8 @@ module obi_mux #( sbr_port_a_chan_t mgr_port_a_in_sbr; logic [RequiredExtraIdWidth-1:0] selected_id, response_id; logic mgr_port_req, fifo_full, fifo_pop; + logic [NumSbrPorts-1:0] sbr_rsp_rvalid; + sbr_port_r_chan_t [NumSbrPorts-1:0] sbr_rsp_r; rr_arb_tree #( .NumIn ( NumSbrPorts ), @@ -135,10 +137,17 @@ module obi_mux #( end if (MgrPortObiCfg.UseRReady) begin : gen_rready_connect - assign mgr_port_req_o.rready = sbr_ports_req_i[response_id].rready; + logic routed_rsp_ready; + + always_comb begin + // R-4.1.1: route readiness from the active response owner + routed_rsp_ready = sbr_ports_req_i[response_id].rready; + end + + assign mgr_port_req_o.rready = routed_rsp_ready; + end else begin : gen_no_rready_connect end - logic [NumSbrPorts-1:0] sbr_rsp_rvalid; - sbr_port_r_chan_t [NumSbrPorts-1:0] sbr_rsp_r; + always_comb begin : proc_sbr_rsp for (int i = 0; i < NumSbrPorts; i++) begin sbr_rsp_r[i] = '0; @@ -154,6 +163,7 @@ module obi_mux #( end if (MgrPortObiCfg.UseRReady) begin : gen_fifo_pop + // R-6: pop the response owner only after its R phase transfer completes assign fifo_pop = mgr_port_rsp_i.rvalid && mgr_port_req_o.rready; end else begin : gen_fifo_pop assign fifo_pop = mgr_port_rsp_i.rvalid; From ae3130fe52c9146c239d2e9b58f4bec43f00aed2 Mon Sep 17 00:00:00 2001 From: Philippe Sauter Date: Sun, 31 May 2026 18:26:22 +0200 Subject: [PATCH 2/2] Fix demux R channel backpressure The demux could change its selected response source while the upstream R phase was stalled. Keep routing responses through the existing selected source and block source changes until the response phase completes so the upstream response remains stable. --- src/obi_demux.sv | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/obi_demux.sv b/src/obi_demux.sv index 3eb016e..fa9c37d 100644 --- a/src/obi_demux.sv +++ b/src/obi_demux.sv @@ -40,6 +40,7 @@ module obi_demux #( logic [CounterWidth-1:0] in_flight; logic sbr_port_gnt; logic sbr_port_rready; + logic rsp_phase_stalled; select_t select_d, select_q; @@ -53,7 +54,9 @@ module obi_demux #( sbr_port_gnt = 1'b0; if (!overflow) begin - if (sbr_port_select_i == select_q || in_flight == '0 || (in_flight == 1 && cnt_down)) begin + // R-4.1.1: block source changes while a stalled R phase is active + if (sbr_port_select_i == select_q || (!rsp_phase_stalled && + (in_flight == '0 || (in_flight == 1 && cnt_down)))) begin mgr_ports_req_o[sbr_port_select_i].req = sbr_port_req_i.req; mgr_ports_req_o[sbr_port_select_i].a = sbr_port_req_i.a; sbr_port_gnt = mgr_ports_rsp_i[sbr_port_select_i].gnt; @@ -72,14 +75,18 @@ module obi_demux #( if (ObiCfg.UseRReady) begin : gen_rready assign sbr_port_rready = sbr_port_req_i.rready; + assign rsp_phase_stalled = sbr_port_rsp_o.rvalid && !sbr_port_rready; + for (genvar i = 0; i < NumMgrPorts; i++) begin : gen_rready assign mgr_ports_req_o[i].rready = sbr_port_req_i.rready; end end else begin : gen_no_rready assign sbr_port_rready = 1'b1; + assign rsp_phase_stalled = 1'b0; end - assign cnt_down = mgr_ports_rsp_i[select_q].rvalid && sbr_port_rready; + // R-6: retire the active response only after its R phase transfer completes + assign cnt_down = sbr_port_rsp_o.rvalid && sbr_port_rready; delta_counter #( .WIDTH ( CounterWidth ), @@ -164,4 +171,3 @@ module obi_demux_intf #( ); endmodule -