Skip to content

Commit a0e8adf

Browse files
committed
Add i3c_target_read_to_multiple_targets test
This test performs multiple random read operations to the device under test. The transactions are interleaved with accesses to other random I3C devices. Signed-off-by: Maciej Dudek <[email protected]>
1 parent 5b328eb commit a0e8adf

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

third_party/cocotbext-i3c

verification/cocotb/top/lib_i3c_top/test_i3c_target.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
import cocotb
1515
from cocotb.triggers import ClockCycles, RisingEdge, Timer
1616

17+
VALID_I3C_ADDRESSES = (
18+
[i for i in range(0x03, 0x3E)]
19+
+ [i for i in range(0x3F, 0x5B)]
20+
+ [i for i in range(0x5C, 0x5E)]
21+
+ [i for i in range(0x5F, 0x6E)]
22+
+ [i for i in range(0x5F, 0x6E)]
23+
+ [i for i in range(0x6F, 0x76)]
24+
+ [i for i in range(0x77, 0x7A)]
25+
+ [0x7B, 0x7D]
26+
)
1727
TARGET_ADDRESS = 0x5A
1828

1929

@@ -32,7 +42,7 @@ async def test_setup(dut, fclk=100.0, fbus=12.5):
3242
"""
3343

3444
cocotb.log.setLevel(logging.INFO)
35-
cocotb.start_soon(timeout_task(200))
45+
cocotb.start_soon(timeout_task(500000))
3646

3747
dut._log.info(f"fclk = {fclk:.3f} MHz")
3848
dut._log.info(f"fbus = {fbus:.3f} MHz")
@@ -338,6 +348,78 @@ def compare(expected, received, lnt=None):
338348
assert response.nack
339349

340350

351+
@cocotb.test()
352+
async def test_i3c_target_read_to_multiple_targets(dut):
353+
354+
# Setup
355+
i3c_controller, i3c_target, tb = await test_setup(dut, fclk=400)
356+
357+
# Generates a randomized transfer and puts it into the TTI TX queue
358+
async def make_transfer(min_len=1, max_len=16):
359+
360+
length = random.randint(min_len, max_len)
361+
data = [random.randint(0, 255) for _ in range(length)]
362+
363+
dut._log.info(f"Enqueueing transfer of length {length}")
364+
365+
# Write data to TTI TX FIFO
366+
for i in range((length + 3) // 4):
367+
word = data[4 * i]
368+
if 4 * i + 1 < length:
369+
word |= data[4 * i + 1] << 8
370+
if 4 * i + 2 < length:
371+
word |= data[4 * i + 2] << 16
372+
if 4 * i + 3 < length:
373+
word |= data[4 * i + 3] << 24
374+
375+
await tb.write_csr(tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr, int2dword(word), 4)
376+
377+
# Write the TX descriptor
378+
await tb.write_csr(tb.reg_map.I3C_EC.TTI.TX_DESC_QUEUE_PORT.base_addr, int2dword(length), 4)
379+
380+
return data
381+
382+
def compare(expected, received, lnt=None):
383+
if lnt is None or lnt == len(expected):
384+
sfx = ""
385+
else:
386+
sfx = " ([" + " ".join([f"{d:02X}" for d in expected[lnt:]]) + "] skipped)"
387+
expected = expected[:lnt]
388+
389+
dut._log.info("Expected: [" + " ".join([f"{d:02X}" for d in expected]) + "]" + sfx)
390+
dut._log.info("Received: [" + " ".join([f"{d:02X}" for d in received]) + "]")
391+
assert expected == received
392+
393+
# issue 40 random read transactions
394+
# randomly choose to inicialize the FIFO or not
395+
# if FIFO is not initialized the transation should be NACKed
396+
for _ in range(40):
397+
num_transfers = random.randint(3, 10)
398+
addresses = []
399+
num_transfers_to_our_target = random.randint(1, num_transfers - 1)
400+
for _ in range(num_transfers_to_our_target):
401+
addresses.append(TARGET_ADDRESS)
402+
while len(addresses) < num_transfers:
403+
addresses.append(random.choice(VALID_I3C_ADDRESSES))
404+
random.shuffle(addresses)
405+
data_len_rsvd_stop_nack = []
406+
for i, addr in enumerate(addresses):
407+
send_rsvd = random.choice([True, False]) if i == 0 else False
408+
stop = i == num_transfers - 1
409+
if addr == TARGET_ADDRESS:
410+
tx_data = await make_transfer()
411+
data_len_rsvd_stop_nack.append((tx_data, len(tx_data), send_rsvd, stop, False))
412+
else:
413+
data_len_rsvd_stop_nack.append((None, random.randint(1, 16), send_rsvd, stop, True))
414+
415+
for address, (tx_data, length, rsvd, stop, nack) in zip(addresses, data_len_rsvd_stop_nack):
416+
response = await i3c_controller.i3c_read(address, length, send_rsvd=rsvd, stop=stop)
417+
assert nack == response.nack
418+
if not nack:
419+
rx_data = list(response.data)
420+
compare(tx_data, rx_data)
421+
422+
341423
@cocotb.test()
342424
async def test_i3c_target_ibi(dut):
343425
"""

0 commit comments

Comments
 (0)