Skip to content

Commit 20aa150

Browse files
wkkunakgugala
authored andcommitted
Release CSR access tests
Signed-off-by: Wiktoria Kuna <[email protected]>
1 parent 0981cdb commit 20aa150

File tree

4 files changed

+190
-0
lines changed

4 files changed

+190
-0
lines changed

verification/cocotb/noxfile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ def hci_queues_axi_verify(session, test_group, test_name, coverage, simulator):
254254
# "test_enter_exit_hdr_mode",
255255
"test_target_reset",
256256
"test_ccc",
257+
"test_csr_access",
257258
],
258259
)
259260
@nox.parametrize("coverage", coverage_types)
@@ -272,6 +273,7 @@ def i3c_ahb_verify(session, test_group, test_name, coverage, simulator):
272273
# "test_enter_exit_hdr_mode",
273274
"test_target_reset",
274275
"test_ccc",
276+
"test_csr_access",
275277
],
276278
)
277279
@nox.parametrize("coverage", coverage_types)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../lib_i3c_top/test_csr_access.py
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../lib_i3c_top/test_csr_access.py
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
import logging
4+
import random
5+
6+
from bus2csr import compare_values, int2dword
7+
from interface import I3CTopTestInterface
8+
9+
import cocotb
10+
from cocotb.triggers import Timer
11+
12+
13+
async def timeout_task(timeout):
14+
await Timer(timeout, "us")
15+
raise RuntimeError("Test timeout!")
16+
17+
18+
async def initialize(dut, fclk=100.0, timeout=50):
19+
"""
20+
Common test initialization routine
21+
"""
22+
23+
cocotb.log.setLevel(logging.DEBUG)
24+
25+
# Start the background timeout task
26+
await cocotb.start(timeout_task(timeout))
27+
28+
tb = I3CTopTestInterface(dut)
29+
await tb.setup(fclk)
30+
return tb
31+
32+
33+
def rand_reg_val(reg):
34+
wdata = random.randint(0, 2**32 - 1)
35+
exp_rd = 0
36+
for f_name in reg:
37+
if f_name in ["base_addr", "offset"]:
38+
continue
39+
f = getattr(reg, f_name)
40+
reset = 0 if "reset" not in f else f.reset
41+
if f.sw == "r":
42+
data = (reset << f.low) & f.mask
43+
elif any([f.woclr, f.hwclr, f.sw == "w"]):
44+
data = 0
45+
else:
46+
data = wdata & f.mask
47+
exp_rd |= data
48+
return wdata, exp_rd
49+
50+
51+
def csr_access_test_data(reg_if, skip_regs=[]):
52+
"""
53+
reg_if: dict
54+
Sub-dictionary of `common.reg_map`. Contains a collection of registers.
55+
Each register contains a collection of register fields.
56+
skip_regs: list
57+
Names of the registers to be excluded from generated test data.
58+
59+
Takes a dictionary of registers and prepares CSR read-write test data.
60+
Draws a random 32-bit word and deduces expected read from the register based on
61+
register field descriptions.
62+
63+
Will expect to read `0` if register is set to clear on write or contains `hwclr` property.
64+
65+
Will expect to read `reset` value (`0` if `reset` is not specified) if a register is read-only
66+
by software.
67+
68+
Otherwise, will expect to read respective sub-word with account for field mask.
69+
70+
NOTE: Limitation of this function is that it will only prepare test data for the registers
71+
at the depth `1` of the `reg_if`.
72+
Will skip registers that are contained within the additional regfiles of the `reg_if`.
73+
"""
74+
skip_regs.extend(["start_addr"])
75+
test_data = []
76+
for reg_name in reg_if:
77+
# Do not consider embedded register structures for now
78+
if reg_name in skip_regs or "base_addr" not in getattr(reg_if, reg_name):
79+
continue
80+
reg = getattr(reg_if, reg_name)
81+
test_data.append([reg_name, reg.base_addr, *rand_reg_val(reg)])
82+
return test_data
83+
84+
85+
async def run_basic_csr_access(tb, reg_if, exceptions=[]):
86+
test_data = csr_access_test_data(reg_if, skip_regs=exceptions)
87+
88+
for _, addr, wdata, exp_rd in test_data:
89+
await tb.write_csr(addr, int2dword(wdata), 4)
90+
rd_data = await tb.read_csr(addr)
91+
compare_values(int2dword(exp_rd), rd_data, addr)
92+
93+
94+
@cocotb.test()
95+
async def test_dat_csr_access(dut):
96+
tb = await initialize(dut)
97+
await run_basic_csr_access(tb, tb.reg_map.DAT)
98+
99+
100+
@cocotb.test()
101+
async def test_dct_csr_access(dut):
102+
exceptions = [
103+
"DCT_MEMORY", # Out-of-use
104+
]
105+
tb = await initialize(dut)
106+
await run_basic_csr_access(tb, tb.reg_map.DCT, exceptions)
107+
108+
109+
@cocotb.test()
110+
async def test_base_csr_access(dut):
111+
exceptions = [
112+
"RESET_CONTROL",
113+
]
114+
tb = await initialize(dut)
115+
await run_basic_csr_access(tb, tb.reg_map.I3CBASE, exceptions)
116+
117+
118+
@cocotb.test()
119+
async def test_pio_csr_access(dut):
120+
exceptions = [
121+
"RESPONSE_PORT",
122+
"TX_DATA_PORT",
123+
"RX_DATA_PORT",
124+
"IBI_PORT",
125+
"QUEUE_THLD_CTRL",
126+
]
127+
tb = await initialize(dut)
128+
await run_basic_csr_access(tb, tb.reg_map.PIOCONTROL, exceptions)
129+
130+
131+
@cocotb.test()
132+
async def test_ec_sec_fw_rec_csr_access(dut):
133+
exceptions = [
134+
"INDIRECT_FIFO_CTRL_0",
135+
"INDIRECT_FIFO_DATA", # Viable only in recovery mode
136+
]
137+
tb = await initialize(dut)
138+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC.SECFWRECOVERYIF, exceptions)
139+
140+
141+
@cocotb.test()
142+
async def test_ec_stdby_ctrl_mode_csr_access(dut):
143+
exceptions = [
144+
"STBY_CR_CONTROL",
145+
"__RSVD_0",
146+
"__RSVD_1",
147+
"STBY_CR_INTR_FORCE",
148+
"__RSVD_3",
149+
"STBY_CR_INTR_STATUS",
150+
"STBY_CR_STATUS",
151+
"STBY_CR_INTR_SIGNAL_ENABLE",
152+
"STBY_CR_CCC_CONFIG_GETCAPS",
153+
"STBY_CR_CCC_CONFIG_RSTACT_PARAMS",
154+
]
155+
tb = await initialize(dut)
156+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC.STDBYCTRLMODE, exceptions)
157+
158+
159+
@cocotb.test()
160+
async def test_ec_tti_csr_access(dut):
161+
exceptions = [
162+
"RESET_CONTROL",
163+
"RX_DESC_QUEUE_PORT",
164+
"RX_DATA_PORT",
165+
"QUEUE_THLD_CTRL",
166+
]
167+
tb = await initialize(dut)
168+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC.TTI, exceptions)
169+
170+
171+
@cocotb.test()
172+
async def test_ec_soc_mgmt_csr_access(dut):
173+
tb = await initialize(dut)
174+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC.SOCMGMTIF)
175+
176+
177+
@cocotb.test()
178+
async def test_ec_contrl_config_csr_access(dut):
179+
tb = await initialize(dut)
180+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC.CTRLCFG)
181+
182+
183+
@cocotb.test()
184+
async def test_ec_csr_access(dut):
185+
tb = await initialize(dut)
186+
await run_basic_csr_access(tb, tb.reg_map.I3C_EC)

0 commit comments

Comments
 (0)