Skip to content

Commit 14b2e95

Browse files
robertszczepanskikgugala
authored andcommitted
Do not hang AXI bus on empty/full queue accesses
Internal-tag: [#74211]
1 parent 329aa6c commit 14b2e95

File tree

5 files changed

+44
-14
lines changed

5 files changed

+44
-14
lines changed

src/hci/tti.sv

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ module tti
7474
output logic tx_data_queue_reg_rst_o,
7575
input logic tx_data_queue_reg_rst_we_i,
7676
input logic tx_data_queue_reg_rst_data_i,
77+
input logic tx_data_queue_full_i,
7778

7879
// In-band Interrupt queue
7980
output logic ibi_queue_req_o,
@@ -84,6 +85,8 @@ module tti
8485
input logic ibi_queue_reg_rst_we_i,
8586
input logic ibi_queue_reg_rst_data_i,
8687

88+
input logic bypass_i3c_core_i,
89+
8790
// IBI status
8891
input logic [1:0] ibi_status_i,
8992
input logic ibi_status_we_i,
@@ -150,6 +153,15 @@ module tti
150153
ibi_queue_ready_thld_o = IbiThldWidth'(hwif_tti_i.QUEUE_THLD_CTRL.IBI_THLD.value);
151154
end : wire_hwif_thld
152155

156+
logic tx_data_queue_full_r;
157+
always_ff @(posedge clk_i or negedge rst_ni) begin : register_fifo_status
158+
if (~rst_ni) begin
159+
tx_data_queue_full_r <= '0;
160+
end else begin
161+
tx_data_queue_full_r <= tx_data_queue_full_i;
162+
end
163+
end
164+
153165
always_comb begin : wire_hwif_xfer
154166
rx_desc_queue_req_o = hwif_tti_i.RX_DESC_QUEUE_PORT.req;
155167
hwif_tti_o.RX_DESC_QUEUE_PORT.rd_ack = rx_desc_queue_ack_i;
@@ -169,9 +181,15 @@ module tti
169181
hwif_tti_o.RESET_CONTROL.RX_DATA_RST.we = rx_data_queue_reg_rst_we_i;
170182
hwif_tti_o.RESET_CONTROL.RX_DATA_RST.next = rx_data_queue_reg_rst_data_i;
171183

172-
tx_data_queue_req_o = hwif_tti_i.TX_DATA_PORT.req & hwif_tti_i.TX_DATA_PORT.req_is_wr;
173-
tx_data_queue_data_o = hwif_tti_i.TX_DATA_PORT.wr_data;
174-
hwif_tti_o.TX_DATA_PORT.wr_ack = tx_data_queue_ack_i;
184+
if (bypass_i3c_core_i & tx_data_queue_full_r) begin
185+
tx_data_queue_req_o = '0;
186+
tx_data_queue_data_o = '0;
187+
hwif_tti_o.TX_DATA_PORT.wr_ack = hwif_tti_i.TX_DATA_PORT.req & hwif_tti_i.TX_DATA_PORT.req_is_wr;
188+
end else begin
189+
tx_data_queue_req_o = hwif_tti_i.TX_DATA_PORT.req & hwif_tti_i.TX_DATA_PORT.req_is_wr;
190+
tx_data_queue_data_o = hwif_tti_i.TX_DATA_PORT.wr_data;
191+
hwif_tti_o.TX_DATA_PORT.wr_ack = tx_data_queue_ack_i;
192+
end
175193
hwif_tti_o.RESET_CONTROL.TX_DATA_RST.we = tx_data_queue_reg_rst_we_i;
176194
hwif_tti_o.RESET_CONTROL.TX_DATA_RST.next = tx_data_queue_reg_rst_data_i;
177195

src/i3c.sv

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ module i3c
911911
logic csr_tti_tx_data_reg_rst;
912912
logic csr_tti_tx_data_reg_rst_we;
913913
logic csr_tti_tx_data_reg_rst_data;
914+
logic csr_tti_tx_data_full;
914915

915916
// TTI In-band Interrupt (IBI) queue
916917
logic csr_tti_ibi_req;
@@ -979,6 +980,7 @@ module i3c
979980
.tx_data_queue_reg_rst_o (csr_tti_tx_data_reg_rst),
980981
.tx_data_queue_reg_rst_we_i (csr_tti_tx_data_reg_rst_we),
981982
.tx_data_queue_reg_rst_data_i(csr_tti_tx_data_reg_rst_data),
983+
.tx_data_queue_full_i (csr_tti_tx_data_full),
982984

983985
// TTI In-band Interrupt (IBI) queue
984986
.ibi_queue_req_o (csr_tti_ibi_req),
@@ -989,6 +991,8 @@ module i3c
989991
.ibi_queue_reg_rst_we_i (csr_tti_ibi_reg_rst_we),
990992
.ibi_queue_reg_rst_data_i(csr_tti_ibi_reg_rst_data),
991993

994+
.bypass_i3c_core_i(bypass_i3c_core),
995+
992996
.recovery_mode_enabled_i(recovery_mode_enabled),
993997
.ibi_status_i(ibi_status),
994998
.ibi_status_we_i(ibi_status_we),
@@ -1083,6 +1087,7 @@ module i3c
10831087
.csr_tti_tx_data_queue_reg_rst_i (csr_tti_tx_data_reg_rst),
10841088
.csr_tti_tx_data_queue_reg_rst_we_o (csr_tti_tx_data_reg_rst_we),
10851089
.csr_tti_tx_data_queue_reg_rst_data_o(csr_tti_tx_data_reg_rst_data),
1090+
.csr_tti_tx_data_queue_full_o (csr_tti_tx_data_full),
10861091

10871092
// TTI In-band Interrupt (IBI) queue
10881093
.csr_tti_ibi_queue_req_i (csr_tti_ibi_req),

src/recovery/recovery_executor.sv

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,9 +723,15 @@ module recovery_executor
723723

724724
// Connect CSR logic to indirect FIFO rx data port
725725
always_comb begin
726-
indirect_rx_rreq_o = hwif_rec_i.INDIRECT_FIFO_DATA.req & !hwif_rec_i.INDIRECT_FIFO_DATA.req_is_wr;
727-
hwif_rec_o.INDIRECT_FIFO_DATA.rd_data = indirect_rx_rdata_i;
728-
hwif_rec_o.INDIRECT_FIFO_DATA.rd_ack = indirect_rx_rack_i;
726+
if (~fifo_empty_r) begin
727+
indirect_rx_rreq_o = hwif_rec_i.INDIRECT_FIFO_DATA.req & !hwif_rec_i.INDIRECT_FIFO_DATA.req_is_wr;
728+
hwif_rec_o.INDIRECT_FIFO_DATA.rd_data = indirect_rx_rdata_i;
729+
hwif_rec_o.INDIRECT_FIFO_DATA.rd_ack = indirect_rx_rack_i;
730+
end else begin
731+
indirect_rx_rreq_o = '0;
732+
hwif_rec_o.INDIRECT_FIFO_DATA.rd_data = '0;
733+
hwif_rec_o.INDIRECT_FIFO_DATA.rd_ack = hwif_rec_i.INDIRECT_FIFO_DATA.req & !hwif_rec_i.INDIRECT_FIFO_DATA.req_is_wr;
734+
end
729735
end
730736

731737
// tie unused signals

src/recovery/recovery_handler.sv

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ module recovery_handler
142142
output logic csr_tti_rx_data_queue_ready_thld_trig_o,
143143

144144
// TX data queue
145+
output logic csr_tti_tx_data_queue_full_o,
145146
input logic csr_tti_tx_data_queue_req_i,
146147
output logic csr_tti_tx_data_queue_ack_o,
147148
input logic [ CsrDataWidth-1:0] csr_tti_tx_data_queue_data_i,
@@ -780,7 +781,9 @@ module recovery_handler
780781
// ......................
781782
// TX data queue is always connected. The recovery logic does not use it
782783
logic exec_tti_tx_data_queue_clr;
784+
logic indirect_rx_full;
783785

786+
assign csr_tti_tx_data_queue_full_o = bypass_i3c_core_i ? indirect_rx_full : tti_tx_data_queue_full;
784787
assign csr_tti_tx_data_queue_ack_o = tti_tx_data_queue_ack;
785788
assign csr_tti_tx_data_queue_reg_rst_we_o = tti_tx_data_queue_reg_rst_we;
786789
assign csr_tti_tx_data_queue_reg_rst_data_o = tti_tx_data_queue_reg_rst_next;
@@ -965,7 +968,6 @@ module recovery_handler
965968

966969
logic indirect_rx_clr;
967970

968-
logic indirect_rx_full;
969971
logic indirect_rx_empty;
970972

971973
// Indirect FIFO (RX only)

verification/cocotb/top/lib_i3c_top/test_bypass.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,7 @@ async def test_indirect_fifo_overflow(dut):
202202
tb, [random.randint(2, 2**32 - 1)], format="dwords", timeout=100, units="ns"
203203
)
204204
except SimTimeoutError:
205-
pass
206-
else:
207-
assert False, "Write to Indirect FIFO was not rejected while it's full!"
205+
assert False, "Write to full Indirect FIFO was rejected while it should be ignored"
208206

209207

210208
@cocotb.test()
@@ -215,17 +213,18 @@ async def test_indirect_fifo_underflow(dut):
215213
tb = await initialize(dut)
216214

217215
# Cause the Indirect FIFO to underflow
216+
d = 0
218217
try:
219-
await tb.read_csr(
218+
d = dword2int(await tb.read_csr(
220219
tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr,
221220
4,
222221
timeout=100,
223222
units="ns",
224-
)
223+
))
225224
except SimTimeoutError:
226-
pass
225+
assert False, "Read from empty Indirect FIFO was rejected while it should return 0"
227226
else:
228-
assert False, "Read from empty Indirect FIFO was not rejected!"
227+
assert d == 0, "Read from empty Indirect FIFO did not return 0"
229228

230229

231230
@cocotb.test()

0 commit comments

Comments
 (0)