Skip to content

Commit d609c7b

Browse files
committed
Added support for referencing a field in a UDP
1 parent 4acae5c commit d609c7b

5 files changed

Lines changed: 71 additions & 2 deletions

File tree

src/peakrdl_python/lib/base.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,35 @@ def udp(self) -> UDPStruct:
9797
"""
9898
return {}
9999

100+
def _traverse_from_fully_qualified_name(self, fully_qualified_name: list[str]) -> 'Base':
101+
"""
102+
This method allows another node in the structure to located based on a list of string
103+
which represented the systemRDL path.
104+
105+
This function is intended for use with UDPs which reference other UDPs
106+
"""
107+
108+
# 1) location the root node by walking backwards up the tree until the parent is
109+
# found
110+
def locate_root(node: 'Base') -> 'Base':
111+
if node.parent is None:
112+
return node
113+
return locate_root(node.parent)
114+
root_node = locate_root(self)
115+
# 2) check the 1st entry in the list matches the name of the root
116+
if root_node.inst_name != fully_qualified_name[0]:
117+
raise RuntimeError('root node name mismatch')
118+
# 3) start walking down the tree matching the nodes
119+
walking_node = root_node
120+
for node_name in fully_qualified_name[1:]:
121+
if not isinstance(walking_node, Node):
122+
# the current node being traversed must be a Node type i.e. not a field
123+
raise RuntimeError('node traversal has failed as type:{type(walking_node)} was'
124+
' unexpectedly encountered')
125+
walking_node = walking_node.get_child_by_system_rdl_name(node_name)
126+
127+
return walking_node
128+
100129
@property
101130
def rdl_name(self) -> Optional[str]:
102131
"""

src/peakrdl_python/systemrdl_node_hashes.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,12 @@ def __node_hash_components(node: Node,
168168
value_to_hash.append(desc)
169169

170170
for udp in get_properties_to_include(node, udp_include_func):
171-
value_to_hash.append(node.get_property(udp))
171+
udp_value = node.get_property(udp)
172+
# systemRDL supports UDPs that cross-reference other parts of the register model
173+
if isinstance(udp_value, Node):
174+
value_to_hash.append('.'.join(udp_value.get_path_segments()))
175+
else:
176+
value_to_hash.append(node.get_property(udp))
172177

173178
return value_to_hash
174179

src/peakrdl_python/templates/addrmap_tb.py.jinja

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ class {{fq_block_name}}_single_access({{top_node.inst_name}}_TestCase): # type:
102102
} )
103103
{% elif isinstance(property_value, systemrdlUserEnum) %}
104104
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ type(property_value).type_name }}_property_enumcls.{{ property_value.name.upper() }} )
105-
{% elif isinstance(property_value, str) %}
105+
{% elif isinstance(property_value, str) %}
106106
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], "{{ property_value }}" )
107+
{% elif isinstance(property_value, systemrdlFieldNode) %}
108+
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], self.dut.{{'.'.join(get_python_path_segments(property_value))}} )
107109
{% else %}
108110
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ property_value }} )
109111
{% endif %}

src/peakrdl_python/templates/addrmap_udp_property.py.jinja

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2727
'{{name}}' : {{ type(value).type_name + '_property_enumcls.' + value.name.upper() }} ,
2828
{% elif isinstance(value, str) %}
2929
'{{name}}' : "{{ value }}" ,
30+
{% elif isinstance(value, systemrdlFieldNode) %}
31+
'{{name}}' : self._traverse_from_fully_qualified_name({{ value.get_path_segments() }}) ,
3032
{% else %}
3133
'{{name}}' : {{ value }} ,
3234
{% endif %}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Testcase the #292 bug
3+
with a UDP that cross-references another
4+
*/
5+
property field_pointer {
6+
type = field;
7+
component = field;
8+
};
9+
10+
property register_pointer {
11+
type = reg;
12+
component = reg;
13+
};
14+
15+
addrmap udp_with_referencing {
16+
reg {
17+
field {
18+
hw = rw;
19+
sw = rw;
20+
} value;
21+
} view;
22+
23+
reg {
24+
field {
25+
hw = rw;
26+
sw = rw;
27+
} value;
28+
} pointer;
29+
30+
view.value->field_pointer = pointer.value;
31+
};

0 commit comments

Comments
 (0)