Skip to content

Commit 9c6ea8c

Browse files
wkkunakgugala
authored andcommitted
Cleanup AXI filtering-related verification
Move helpers common for both 'block' and 'top' tests to 'common'. Lint AXI ID filtering tests. Signed-off-by: Wiktoria Kuna <[email protected]>
1 parent 1a367e4 commit 9c6ea8c

File tree

6 files changed

+183
-176
lines changed

6 files changed

+183
-176
lines changed

verification/cocotb/block/axi_adapter_id_filter/axi_utils.py

Lines changed: 6 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
# SPDX-License-Identifier: Apache-2.0
22
import logging
3-
import random
4-
from enum import IntEnum
53

64
from bus2csr import get_frontend_bus_if
75
from cocotb_helpers import reset_n
8-
from cocotbext.axi import AxiResp
9-
from utils import rand_bits
106

117
import cocotb
128
from cocotb.triggers import ClockCycles, RisingEdge, Timer
@@ -34,93 +30,6 @@ async def error_monitor(dut):
3430
await RisingEdge(dut.aclk)
3531

3632

37-
def _report_axi_response(got, expected, is_read=False):
38-
op = "read" if is_read else "write"
39-
name = ["OKAY", "EXOKAY", "SLVERR", "DECERR"]
40-
return (
41-
f"{hex(expected)} != {hex(got)}."
42-
f" Anticipated {op} response: {name[expected]} got: {name[got]}."
43-
)
44-
45-
46-
async def _wait(dut, cond):
47-
while not cond():
48-
await RisingEdge(dut.aclk)
49-
50-
51-
async def axi_read_monitor(dut):
52-
"""
53-
Ensures the AXI read response is set appropriately to
54-
current filtering configuration and transaction ID.
55-
"""
56-
await RisingEdge(dut.areset_n)
57-
58-
while True:
59-
await _wait(dut, lambda: dut.arvalid.value and dut.arready.value)
60-
priv_ids = dut.priv_ids_i.value
61-
filter_off = dut.disable_id_filtering_i.value
62-
63-
await _wait(dut, lambda: dut.rvalid.value and dut.rready.value)
64-
rid = dut.rid.value
65-
rresp = dut.rresp.value
66-
if filter_off or rid in priv_ids:
67-
assert rresp == AxiResp.OKAY, _report_axi_response(rresp, AxiResp.OKAY, True)
68-
else:
69-
assert rresp == AxiResp.SLVERR, _report_axi_response(rresp, AxiResp.SLVERR, True)
70-
71-
await RisingEdge(dut.aclk)
72-
73-
74-
async def axi_write_monitor(dut):
75-
"""
76-
Ensures the AXI write response is set appropriately to
77-
current filtering configuration and transaction ID.
78-
"""
79-
await RisingEdge(dut.areset_n)
80-
81-
while True:
82-
await _wait(dut, lambda: dut.awvalid.value and dut.awready.value)
83-
priv_ids = dut.priv_ids_i.value
84-
filter_off = dut.disable_id_filtering_i.value
85-
86-
await _wait(dut, lambda: dut.bvalid.value and dut.bready.value)
87-
bid = dut.bid.value
88-
bresp = dut.bresp.value
89-
90-
if filter_off or bid in priv_ids:
91-
assert bresp == AxiResp.OKAY, _report_axi_response(bresp, AxiResp.OKAY)
92-
else:
93-
assert bresp == AxiResp.SLVERR, _report_axi_response(bresp, AxiResp.SLVERR)
94-
95-
await RisingEdge(dut.aclk)
96-
97-
98-
class Access(IntEnum):
99-
Priv = 0
100-
Unpriv = 1
101-
Mixed = 2
102-
103-
104-
def draw_ids(id_width=AxiIdWidth, num_priv_ids=NumPrivIds):
105-
return [rand_bits(id_width) for _ in range(num_priv_ids)]
106-
107-
108-
def get_ids(priv_ids, count, priv=False, id_width=AxiIdWidth):
109-
id_space = range(0, (1 << id_width))
110-
unpriv = [x for x in id_space if x not in priv_ids]
111-
112-
is_priv = priv == Access.Priv
113-
out = []
114-
for _ in range(count):
115-
if priv == Access.Mixed:
116-
is_priv = random.randint(0, 1)
117-
118-
id_scope = priv_ids if is_priv else unpriv
119-
out.append(random.choice(id_scope))
120-
121-
return out
122-
123-
12433
async def initialize_dut(dut, disable_id_filtering=False, priv_ids=None, timeout=50):
12534
"""
12635
Common test initialization routine which sets up environment and starts a timeout coroutine
@@ -129,11 +38,15 @@ async def initialize_dut(dut, disable_id_filtering=False, priv_ids=None, timeout
12938

13039
cocotb.log.setLevel(logging.DEBUG)
13140

41+
tb = get_frontend_bus_if()(dut)
42+
tb.log = dut._log
43+
await tb.register_test_interfaces()
44+
13245
# Start the background timeout task
13346
cocotb.start_soon(timeout_task(timeout))
13447
cocotb.start_soon(error_monitor(dut))
135-
cocotb.start_soon(axi_read_monitor(dut))
136-
cocotb.start_soon(axi_write_monitor(dut))
48+
cocotb.start_soon(tb.read_access_monitor())
49+
cocotb.start_soon(tb.write_access_monitor())
13750

13851
# Initialize inputs
13952
dut.araddr.value = 0
@@ -166,10 +79,6 @@ async def initialize_dut(dut, disable_id_filtering=False, priv_ids=None, timeout
16679
if hasattr(dut, "priv_ids_i"):
16780
dut.priv_ids_i.value = priv_ids
16881

169-
# Configure testbench
170-
tb = get_frontend_bus_if()(dut)
171-
tb.log = dut._log
172-
await tb.register_test_interfaces()
17382
await ClockCycles(tb.clk, 20)
17483
await reset_n(tb.clk, tb.rst_n, cycles=5)
17584

verification/cocotb/block/axi_adapter_id_filter/test_bus_stress.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
# SPDX-License-Identifier: Apache-2.0
22
import random
33

4-
from axi_utils import Access, draw_ids, get_ids, initialize_dut
4+
from axi_utils import initialize_dut
55
from bus2csr import dword2int, int2bytes, int2dword
66
from cocotbext.axi.constants import AxiBurstType
7+
from utils import Access, draw_axi_priv_ids, get_axi_ids_seq
78

89
import cocotb
910
from cocotb.triggers import ClockCycles, Combine, RisingEdge, with_timeout
1011

1112

1213
async def initialize(dut, filter_off=False, priv_ids=None, timeout=50):
13-
tb = await initialize_dut(
14-
dut, disable_id_filtering=filter_off, priv_ids=priv_ids, timeout=timeout
15-
)
14+
tb = await initialize_dut(dut, filter_off, priv_ids, timeout)
1615

1716
# Generate test data
1817
data_len = random.randint(10, 64)
@@ -37,10 +36,10 @@ def verify_data(write_data, awids, read_data, arids, disable_id_filtering=False,
3736

3837

3938
async def collision_with_write(dut, filter_off=False, awid_priv=Access.Priv, arid_priv=Access.Priv):
40-
priv_ids = draw_ids()
39+
priv_ids = draw_axi_priv_ids()
4140
tb, data_len, test_data = await initialize(dut, filter_off, priv_ids)
42-
awids = get_ids(priv_ids, data_len, awid_priv)
43-
arids = get_ids(priv_ids, data_len, arid_priv)
41+
awids = get_axi_ids_seq(priv_ids, data_len, awid_priv)
42+
arids = get_axi_ids_seq(priv_ids, data_len, arid_priv)
4443

4544
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
4645
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
@@ -96,10 +95,10 @@ async def test_collision_with_write_id_filter_on_mixed(dut):
9695

9796

9897
async def collision_with_read(dut, filter_off=False, awid_priv=True, arid_priv=True):
99-
priv_ids = draw_ids()
98+
priv_ids = draw_axi_priv_ids()
10099
tb, data_len, test_data = await initialize(dut, filter_off, priv_ids)
101-
awids = get_ids(priv_ids, data_len, awid_priv)
102-
arids = get_ids(priv_ids, data_len, arid_priv)
100+
awids = get_axi_ids_seq(priv_ids, data_len, awid_priv)
101+
arids = get_axi_ids_seq(priv_ids, data_len, arid_priv)
103102

104103
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
105104
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
@@ -162,10 +161,10 @@ async def test_collision_with_read_id_filter_on_mixed(dut):
162161

163162

164163
async def write_read_burst(dut, filter_off=False, awid_priv=True, arid_priv=True):
165-
priv_ids = draw_ids()
164+
priv_ids = draw_axi_priv_ids()
166165
tb, data_len, test_data = await initialize(dut, filter_off, priv_ids)
167-
awids = get_ids(priv_ids, 1, awid_priv)
168-
arids = get_ids(priv_ids, 1, arid_priv)
166+
awids = get_axi_ids_seq(priv_ids, 1, awid_priv)
167+
arids = get_axi_ids_seq(priv_ids, 1, arid_priv)
169168
awid, arid = awids[0], arids[0]
170169

171170
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
@@ -198,10 +197,10 @@ async def test_write_read_burst_id_filter_on_non_priv(dut):
198197

199198

200199
async def write_burst_collision_with_read(dut, filter_off=False, awid_priv=True, arid_priv=True):
201-
priv_ids = draw_ids()
200+
priv_ids = draw_axi_priv_ids()
202201
tb, data_len, test_data = await initialize(dut, filter_off, priv_ids)
203-
awids = get_ids(priv_ids, 1, awid_priv)
204-
arids = get_ids(priv_ids, 1, arid_priv)
202+
awids = get_axi_ids_seq(priv_ids, 1, awid_priv)
203+
arids = get_axi_ids_seq(priv_ids, 1, arid_priv)
205204
awid, arid = awids[0], arids[0]
206205

207206
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
@@ -249,10 +248,10 @@ async def test_write_burst_collision_with_read_id_filter_non_priv(dut):
249248

250249

251250
async def read_burst_collision_with_write(dut, filter_off=False, awid_priv=True, arid_priv=True):
252-
priv_ids = draw_ids()
251+
priv_ids = draw_axi_priv_ids()
253252
tb, data_len, test_data = await initialize(dut, filter_off, priv_ids)
254-
awids = get_ids(priv_ids, 1, awid_priv)
255-
arids = get_ids(priv_ids, 1, arid_priv)
253+
awids = get_axi_ids_seq(priv_ids, 1, awid_priv)
254+
arids = get_axi_ids_seq(priv_ids, 1, arid_priv)
256255
awid, arid = awids[0], arids[0]
257256

258257
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
@@ -311,10 +310,10 @@ async def test_read_burst_collision_with_write_id_filter_on_non_priv(dut):
311310

312311
@cocotb.test()
313312
async def test_collision_with_write_mixed_priv(dut):
314-
priv_ids = draw_ids()
313+
priv_ids = draw_axi_priv_ids()
315314
tb, data_len, test_data = await initialize(dut, filter_off=False, priv_ids=priv_ids)
316-
awids = get_ids(priv_ids, data_len, Access.Mixed)
317-
arids = get_ids(priv_ids, data_len, Access.Mixed)
315+
awids = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
316+
arids = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
318317

319318
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
320319
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
@@ -348,10 +347,10 @@ async def reader():
348347

349348
@cocotb.test()
350349
async def test_collision_with_read_mixed_priv(dut):
351-
priv_ids = draw_ids()
350+
priv_ids = draw_axi_priv_ids()
352351
tb, data_len, test_data = await initialize(dut, filter_off=False, priv_ids=priv_ids)
353-
awids = get_ids(priv_ids, data_len, Access.Mixed)
354-
arids = get_ids(priv_ids, data_len, Access.Mixed)
352+
awids = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
353+
arids = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
355354

356355
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
357356
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr

verification/cocotb/block/axi_adapter_id_filter/test_runtime_id_change.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# SPDX-License-Identifier: Apache-2.0
22
import random
33

4-
from axi_utils import Access, _wait, draw_ids, get_ids, initialize_dut
4+
from axi_utils import initialize_dut
55
from bus2csr import dword2int, int2bytes
66
from cocotbext.axi.constants import AxiBurstType
7+
from utils import Access, draw_axi_priv_ids, get_axi_ids_seq
78

89
import cocotb
910
from cocotb.triggers import Combine, RisingEdge
@@ -23,7 +24,8 @@ async def initialize(dut, filter_off=False, priv_ids=None, timeout=50):
2324
async def id_filter_disable_toggle(dut, cond):
2425
while True:
2526
filter_off = int(dut.disable_id_filtering_i.value)
26-
await _wait(dut, cond)
27+
while not cond:
28+
await RisingEdge(dut.aclk)
2729
dut.disable_id_filtering_i.value = not filter_off
2830
await RisingEdge(dut.aclk)
2931

@@ -32,7 +34,8 @@ async def priv_ids_swapper(dut, cond, new_priv_ids):
3234
assert isinstance(new_priv_ids, list)
3335
i, n = 0, len(new_priv_ids)
3436
while i < n:
35-
await _wait(dut, cond)
37+
while not cond:
38+
await RisingEdge(dut.aclk)
3639
dut.priv_ids_i.value = new_priv_ids[i]
3740
i += 1
3841
await RisingEdge(dut.aclk)
@@ -64,7 +67,7 @@ async def reader(tb, addr, count, tids, return_data):
6467

6568

6669
async def toggle_filtering(dut, cond):
67-
priv_ids = draw_ids()
70+
priv_ids = draw_axi_priv_ids()
6871
tb, data_len, test_data = await initialize(dut, True, priv_ids)
6972
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
7073
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
@@ -74,8 +77,8 @@ async def toggle_filtering(dut, cond):
7477

7578
cocotb.start_soon(id_filter_disable_toggle(dut, cond))
7679

77-
awid = get_ids(priv_ids, data_len, Access.Mixed)
78-
arid = get_ids(priv_ids, data_len, Access.Mixed)
80+
awid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
81+
arid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
7982

8083
received_data = []
8184
w = cocotb.start_soon(writer(tb, waddr, test_data, awid))
@@ -95,19 +98,19 @@ async def test_toggle_filtering_mid_write(dut):
9598

9699

97100
async def swap_priv_ids(dut, cond):
98-
priv_ids = draw_ids()
101+
priv_ids = draw_axi_priv_ids()
99102
tb, data_len, test_data = await initialize(dut, True, priv_ids)
100103
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
101104
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
102105

103106
# Fill fifo halfway to avoid reads when empty
104107
await tb.axi_m.write_dwords(waddr, range(64), burst=AxiBurstType.FIXED, awid=priv_ids[0])
105108

106-
priv_ids_seq = [draw_ids() for _ in range(data_len)]
109+
priv_ids_seq = [draw_axi_priv_ids() for _ in range(data_len)]
107110
cocotb.start_soon(priv_ids_swapper(dut, cond, priv_ids_seq))
108111

109-
awid = get_ids(priv_ids, data_len, Access.Mixed)
110-
arid = get_ids(priv_ids, data_len, Access.Mixed)
112+
awid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
113+
arid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
111114

112115
received_data = []
113116
w = cocotb.start_soon(writer(tb, waddr, test_data, awid))
@@ -138,10 +141,10 @@ async def disable_random():
138141
async def priv_id_swap_random():
139142
while True:
140143
if abs(random.random()) < 0.2:
141-
dut.priv_ids_i.value = draw_ids()
144+
dut.priv_ids_i.value = draw_axi_priv_ids()
142145
await RisingEdge(dut.aclk)
143146

144-
priv_ids = draw_ids()
147+
priv_ids = draw_axi_priv_ids()
145148
tb, data_len, test_data = await initialize(dut, True, priv_ids)
146149
waddr = tb.reg_map.I3C_EC.TTI.TX_DATA_PORT.base_addr
147150
raddr = tb.reg_map.I3C_EC.SECFWRECOVERYIF.INDIRECT_FIFO_DATA.base_addr
@@ -152,8 +155,8 @@ async def priv_id_swap_random():
152155
cocotb.start_soon(disable_random())
153156
cocotb.start_soon(priv_id_swap_random())
154157

155-
awid = get_ids(priv_ids, data_len, Access.Mixed)
156-
arid = get_ids(priv_ids, data_len, Access.Mixed)
158+
awid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
159+
arid = get_axi_ids_seq(priv_ids, data_len, Access.Mixed)
157160

158161
received_data = []
159162
w = cocotb.start_soon(writer(tb, waddr, test_data, awid))

0 commit comments

Comments
 (0)