Skip to content

Commit 8973ec6

Browse files
Improve AXI B stall test to cover more conds
Internal-tag: [#95639]
1 parent 6cbe895 commit 8973ec6

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

verification/cocotb/top/lib_i3c_top/test_csr_access.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import cocotb
1313
from cocotb_helpers import reset_n
14-
from cocotb.triggers import ClockCycles, RisingEdge, Timer
14+
from cocotb.triggers import ClockCycles, RisingEdge, Combine
1515
from cocotbext.axi import AxiLockType, AxiBurstType, AxiResp
1616
from common import timeout_task, log_seed
1717

@@ -657,11 +657,11 @@ async def test_read_stall(dut):
657657
@cocotb.test()
658658
async def test_write_b_channel_skid_full(dut):
659659
"""
660-
Verify that when the B-channel is stalled and two write responses are pending
660+
Verify that when the B-channel is stalled and three write responses are pending
661661
(output stage + hold register of the response skidbuffer), rp_ready drops to 0,
662-
req_ready follows, and AWREADY deasserts to prevent a third response from
663-
overflowing the skidbuffer. Releasing the stall drains all responses and all
664-
three writes complete with correct data.
662+
req_ready follows, and AWREADY deasserts to prevent a third and fourth responses
663+
from overflowing the skidbuffer. Releasing the stall drains all responses and all
664+
four writes complete with correct data.
665665
"""
666666
tb = await initialize(dut)
667667

@@ -673,10 +673,11 @@ async def test_write_b_channel_skid_full(dut):
673673
b_channel = tb.busIf.axi_m.write_if.b_channel
674674

675675
test_data = csr_access_test_data(tb.reg_map.I3CBASE, skip_regs=["RESET_CONTROL"])
676-
assert len(test_data) >= 3, "Need at least 3 writable registers in I3CBASE"
676+
assert len(test_data) >= 4, "Need at least 4 writable registers in I3CBASE"
677677
(reg1_name, addr1, wdata1, exp_rd1) = test_data[0]
678678
(reg2_name, addr2, wdata2, exp_rd2) = test_data[1]
679679
(reg3_name, addr3, wdata3, exp_rd3) = test_data[2]
680+
(reg4_name, addr4, wdata4, exp_rd4) = test_data[3]
680681

681682
# Stall all write responses — no B-channel handshake until we release
682683
b_channel.pause = True
@@ -687,15 +688,20 @@ async def test_write_b_channel_skid_full(dut):
687688
await RisingEdge(dut.aclk)
688689

689690
# Write 2: when its final beat completes with bvalid=1 already asserted,
690-
# the skidbuffer hold register fills (r_valid=1) and rp_ready drops to 0.
691+
# the skidbuffer hold register fills (r_valid=1) and rp_ready
692+
# drops to 0.
691693
task2 = cocotb.start_soon(tb.write_csr(addr2, int2dword(wdata2), 4))
692694
# Allow enough cycles for write 2 to complete its AW+W phases
693695
await ClockCycles(dut.aclk, 20)
694696

695697
# Write 3: AW arrives when req_ready=0 (rp_ready=0), so the request skidbuffer
696-
# fills and AWREADY must deassert to apply backpressure
698+
# fills and AWREADY must deassert to apply backpressure
697699
task3 = cocotb.start_soon(tb.write_csr(addr3, int2dword(wdata3), 4))
698700

701+
# Write 4: Request skidbuffer is already full, AWVALID is asserted while
702+
# AWREADY is deasserted
703+
task4 = cocotb.start_soon(tb.write_csr(addr4, int2dword(wdata4), 4))
704+
699705
awready_went_low = False
700706
for _ in range(30):
701707
await RisingEdge(dut.aclk)
@@ -707,14 +713,13 @@ async def test_write_b_channel_skid_full(dut):
707713

708714
# Release the stall — all three responses drain, all three tasks complete
709715
b_channel.pause = False
710-
await task1
711-
await task2
712-
await task3
716+
await Combine(task1, task2, task3, task4)
713717

714718
for reg_name, addr, exp_rd in [
715719
(reg1_name, addr1, exp_rd1),
716720
(reg2_name, addr2, exp_rd2),
717721
(reg3_name, addr3, exp_rd3),
722+
(reg4_name, addr4, exp_rd4),
718723
]:
719724
rd = bytes2int(await tb.read_csr(addr, 4))
720725
assert rd == exp_rd, (

0 commit comments

Comments
 (0)