Skip to content

Commit 12ea6d8

Browse files
authored
Merge pull request #269 from krcb197/258-optimise-test_traversal_iterators_with_rolled_and_unrolled_v2
Improve the iterator test to cover the rolled and unrolled cases
2 parents d9d2263 + f3cda7d commit 12ea6d8

6 files changed

Lines changed: 107 additions & 32 deletions

File tree

src/peakrdl_python/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
1818
Variables that describes the peakrdl-python Package
1919
"""
20-
__version__ = "3.0.0rc5"
20+
__version__ = "3.0.0rc6"

src/peakrdl_python/exporter.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
get_memory_max_entry_value_hex_string, get_memory_width_bytes, \
4747
get_field_default_value, get_enum_values, get_properties_to_include, \
4848
HideNodeCallback, hide_based_on_property, \
49-
full_slice_accessor, ShowUDPCallback
49+
full_slice_accessor, ShowUDPCallback, \
50+
node_iterator_entry
5051
from .unique_component_iterator import UniqueComponents
5152
from .unique_component_iterator import PeakRDLPythonUniqueRegisterComponents
5253
from .unique_component_iterator import PeakRDLPythonUniqueMemoryComponents
@@ -865,7 +866,8 @@ def is_reg_node(node: Node) -> TypeGuard[RegNode]:
865866
'get_properties_to_include': get_properties_to_include,
866867
'hide_node_func': hide_node_func,
867868
'legacy_enum_type': legacy_enum_type,
868-
'skip_systemrdl_name_and_desc_properties': skip_systemrdl_name_and_desc_properties
869+
'skip_systemrdl_name_and_desc_properties': skip_systemrdl_name_and_desc_properties,
870+
'node_iterator_entry': node_iterator_entry,
869871
}
870872

871873
self.__stream_jinja_template(template_name="addrmap_tb.py.jinja",

src/peakrdl_python/lib_test/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@
2222
from .async_reg_base_test_class import AsyncLibTestBase
2323

2424
from .utilities import reverse_bits
25+
26+
from ._common_base_test_class import NodeIterators

src/peakrdl_python/lib_test/_common_base_test_class.py

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import unittest
2222
from abc import ABC, abstractmethod
2323
from typing import Union, Optional
24+
from itertools import product
2425

2526
from ..lib import FieldReadWrite, FieldReadOnly, FieldWriteOnly
2627
from ..lib import FieldEnumReadWrite, FieldEnumReadOnly, FieldEnumWriteOnly
@@ -41,6 +42,46 @@
4142
from .utilities import get_field_bitmask_int, get_field_inv_bitmask
4243
from ..sim_lib.simulator import BaseSimulator
4344

45+
class NodeIterators:
46+
"""
47+
The Node Iterator class is intended to an efficient way to define the iterators of particular
48+
type that are present on a node
49+
"""
50+
__slots__ = ['__node_descriptions']
51+
def __init__(self, *args:Union[str, tuple[str, list[int]]]):
52+
self.__node_descriptions = args
53+
54+
@staticmethod
55+
def __rolled_item(item:Union[str, tuple[str, list[int]]]) -> str:
56+
if isinstance(item, tuple):
57+
return item[0]
58+
return item
59+
60+
@property
61+
def rolled(self) -> set[str]:
62+
"""
63+
name of all the rolled nodes in a set
64+
"""
65+
return { self.__rolled_item(item) for item in self.__node_descriptions }
66+
67+
@property
68+
def unrolled(self) -> set[str]:
69+
"""
70+
name of all the unrolled nodes in a set
71+
"""
72+
return_list = []
73+
for item in self.__node_descriptions:
74+
if isinstance(item, tuple):
75+
dim_set = list(product(*[range(dim) for dim in item[1]]))
76+
for dim in dim_set:
77+
# to match the systemrdl compiler dimension put into the inst name of
78+
# the array, the name must be item[x][y]
79+
dim_str = ''.join([f'[{str(i)}]' for i in dim])
80+
return_list.append(f'{item[0]}{dim_str}')
81+
else:
82+
return_list.append(item)
83+
return set(return_list)
84+
4485
class CommonTestBase(unittest.TestCase, ABC):
4586
"""
4687
Base Test class for the autogenerated register test to be used for the async and
@@ -201,8 +242,8 @@ def _test_register_iterators(self,
201242
MemoryAsyncReadOnly, MemoryAsyncReadOnlyLegacy,
202243
MemoryAsyncWriteOnly, MemoryAsyncWriteOnlyLegacy,
203244
MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy],
204-
readable_registers: set[str],
205-
writeable_registers: set[str]) -> None:
245+
readable_registers: NodeIterators,
246+
writeable_registers: NodeIterators) -> None:
206247

207248
if isinstance(dut, (AddressMap, AsyncAddressMap, RegFile, AsyncRegFile,
208249
MemoryReadOnly, MemoryReadOnlyLegacy,
@@ -211,7 +252,10 @@ def _test_register_iterators(self,
211252
MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy)):
212253
child_readable_reg_names = { reg.inst_name for reg in
213254
dut.get_readable_registers(unroll=True)}
214-
self.assertEqual(readable_registers, child_readable_reg_names)
255+
self.assertEqual(readable_registers.unrolled, child_readable_reg_names)
256+
child_readable_reg_names = {reg.inst_name for reg in
257+
dut.get_readable_registers(unroll=False)}
258+
self.assertEqual(readable_registers.rolled, child_readable_reg_names)
215259
else:
216260
self.assertFalse(hasattr(dut, 'get_readable_registers'))
217261

@@ -222,32 +266,43 @@ def _test_register_iterators(self,
222266
MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy)):
223267
child_writable_reg_names = {reg.inst_name for reg in
224268
dut.get_writable_registers(unroll=True)}
225-
self.assertEqual(writeable_registers, child_writable_reg_names)
269+
self.assertEqual(writeable_registers.unrolled, child_writable_reg_names)
270+
child_writable_reg_names = {reg.inst_name for reg in
271+
dut.get_writable_registers(unroll=False)}
272+
self.assertEqual(writeable_registers.rolled, child_writable_reg_names)
226273
else:
227274
self.assertFalse(hasattr(dut, 'get_writable_registers'))
228275

229276
child_reg_names = {field.inst_name for field in dut.get_registers(unroll=True)}
230-
self.assertEqual(readable_registers | writeable_registers, child_reg_names)
277+
self.assertEqual(readable_registers.unrolled | writeable_registers.unrolled,
278+
child_reg_names)
279+
child_reg_names = {field.inst_name for field in dut.get_registers(unroll=False)}
280+
self.assertEqual(readable_registers.rolled | writeable_registers.rolled,
281+
child_reg_names)
231282

232283

233284
def _test_memory_iterators(self,
234285
dut: Union[AddressMap, AsyncAddressMap],
235-
memories: set[str]) -> None:
286+
memories: NodeIterators) -> None:
236287
child_mem_names = {reg.inst_name for reg in dut.get_memories(unroll=True)}
237-
self.assertEqual(memories, child_mem_names)
288+
self.assertEqual(memories.unrolled, child_mem_names)
289+
child_mem_names = {reg.inst_name for reg in dut.get_memories(unroll=False)}
290+
self.assertEqual(memories.rolled, child_mem_names)
238291

239292
def __test_section_iterators(self,
240293
dut: Union[AddressMap, AsyncAddressMap, RegFile, AsyncRegFile],
241-
sections: set[str]) -> None:
294+
sections: NodeIterators) -> None:
242295
child_section_names = {reg.inst_name for reg in dut.get_sections(unroll=True)}
243-
self.assertEqual(sections, child_section_names)
296+
self.assertEqual(sections.unrolled, child_section_names)
297+
child_section_names = {reg.inst_name for reg in dut.get_sections(unroll=False)}
298+
self.assertEqual(sections.rolled, child_section_names)
244299

245300
def _test_addrmap_iterators(self, *,
246301
dut: Union[AddressMap, AsyncAddressMap],
247-
memories: set[str],
248-
sections: set[str],
249-
readable_registers: set[str],
250-
writeable_registers: set[str]) -> None:
302+
memories: NodeIterators,
303+
sections: NodeIterators,
304+
readable_registers: NodeIterators,
305+
writeable_registers: NodeIterators) -> None:
251306
self._test_register_iterators(dut=dut,
252307
readable_registers=readable_registers,
253308
writeable_registers=writeable_registers)
@@ -258,9 +313,9 @@ def _test_addrmap_iterators(self, *,
258313

259314
def _test_regfile_iterators(self,
260315
dut: Union[RegFile, AsyncRegFile],
261-
sections: set[str],
262-
readable_registers: set[str],
263-
writeable_registers: set[str]) -> None:
316+
sections: NodeIterators,
317+
readable_registers: NodeIterators,
318+
writeable_registers: NodeIterators) -> None:
264319
self._test_register_iterators(dut=dut,
265320
readable_registers=readable_registers,
266321
writeable_registers=writeable_registers)

src/peakrdl_python/systemrdl_node_utility_functions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,18 @@ def full_slice_accessor(node: AddressableNode) -> str:
480480
if dimensions is None:
481481
raise RuntimeError('array node should have dimensions')
482482
return '[' + ','.join([':' for _ in range(len(dimensions))]) + ']'
483+
484+
def node_iterator_entry(node: AddressableNode) -> str:
485+
"""
486+
The NodeIterators in the lib_test requires all the children of a node to be presented in the
487+
following format:
488+
- non-array node: str of the name inst name from the system RDL
489+
- array node: a tuple with the inst name and the length
490+
"""
491+
if node.is_array:
492+
dimensions = node.array_dimensions
493+
if dimensions is None:
494+
raise RuntimeError('array node should have dimensions')
495+
return f"('{node.inst_name}', {str(dimensions)})"
496+
497+
return "'" + node.inst_name + "'"

src/peakrdl_python/templates/addrmap_tb.py.jinja

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ from {{ peakrdl_python_lib(depth=lib_depth) }} import Reg
7575
from {{ peakrdl_python_lib(depth=lib_depth) }} import SystemRDLEnum, SystemRDLEnumEntry
7676
{% endif %}
7777
from {{ peakrdl_python_lib_test(depth=lib_depth) }} import reverse_bits
78+
from {{ peakrdl_python_lib_test(depth=lib_depth) }} import NodeIterators
7879

7980
from ._{{top_node.inst_name}}_test_base import {{top_node.inst_name}}_TestCase, {{top_node.inst_name}}_TestCase_BlockAccess, {{top_node.inst_name}}_TestCase_AltBlockAccess
8081
from ._{{top_node.inst_name}}_test_base import __name__ as base_name
@@ -345,10 +346,10 @@ class {{fq_block_name}}_single_access({{top_node.inst_name}}_TestCase): # type:
345346
def test_top_traversal_iterators(self) -> None:
346347

347348
self._test_addrmap_iterators(dut=self.dut,
348-
writeable_registers=set([ {%- for child_node in top_node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
349-
readable_registers=set([ {%- for child_node in top_node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
350-
sections=set([ {%- for child_node in top_node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endfor %} ]),
351-
memories=set([ {%- for child_node in top_node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlMemNode) %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endfor %} ]))
349+
writeable_registers=NodeIterators({%- for child_node in top_node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
350+
readable_registers=NodeIterators({%- for child_node in top_node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
351+
sections=NodeIterators({%- for child_node in top_node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endfor %}),
352+
memories=NodeIterators({%- for child_node in top_node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlMemNode) %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endfor %}))
352353

353354
{% endif %}{# if block == top_block #}
354355

@@ -363,25 +364,25 @@ class {{fq_block_name}}_single_access({{top_node.inst_name}}_TestCase): # type:
363364
{% for node in owned_elements.memories -%}
364365
with self.subTest(msg='memory: {{'.'.join(node.get_path_segments())}}'):
365366
self._test_register_iterators(dut=self.dut.{{'.'.join(get_python_path_segments(node))}},
366-
writeable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
367-
readable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]))
367+
writeable_registers=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
368+
readable_registers=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}))
368369
{% endfor %}
369370
# test all the address maps
370371
{% for node in owned_elements.addr_maps -%}
371372
with self.subTest(msg='addrmap: {{'.'.join(node.get_path_segments())}}'):
372373
self._test_addrmap_iterators(dut=self.dut.{{'.'.join(get_python_path_segments(node))}},
373-
writeable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
374-
readable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
375-
sections=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endfor %} ]),
376-
memories=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlMemNode) %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endfor %} ]))
374+
writeable_registers=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
375+
readable_registers=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
376+
sections=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endfor %}),
377+
memories=NodeIterators( {%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlMemNode) %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endfor %}))
377378
{% endfor %}
378379
# test all the register files
379380
{% for node in owned_elements.reg_files -%}
380381
with self.subTest(msg='regfile: {{'.'.join(node.get_path_segments())}}'):
381382
self._test_regfile_iterators(dut=self.dut.{{'.'.join(get_python_path_segments(node))}},
382-
writeable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
383-
readable_registers=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endif %}{% endfor %} ]),
384-
sections=set([ {%- for child_node in node.children(unroll=True) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}'{{child_node.get_path_segments()[-1]}}',{% endif %}{% endif %}{% endfor %} ]))
383+
writeable_registers=NodeIterators({%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_writable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
384+
readable_registers=NodeIterators({%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, systemrdlRegNode) %}{% if child_node.has_sw_readable %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endif %}{% endfor %}),
385+
sections=NodeIterators({%- for child_node in node.children(unroll=False) %}{%- if not hide_node_func(child_node) %}{%- if isinstance(child_node, (systemrdlRegfileNode,systemrdlAddrmapNode)) %}{{node_iterator_entry(child_node)}},{% endif %}{% endif %}{% endfor %}))
385386
{% endfor %}
386387

387388
def test_name_map(self) -> None:

0 commit comments

Comments
 (0)