From 49e81b7670e757596b5abf49711d8a9841d556b6 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sat, 28 Mar 2026 07:30:46 +0000
Subject: [PATCH 1/9] Fix issue with the user defined property regex not being
passed down to the exporter in `generate_and_test.py`
---
generate_and_test.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/generate_and_test.py b/generate_and_test.py
index 9282b8e4..bb54972a 100644
--- a/generate_and_test.py
+++ b/generate_and_test.py
@@ -222,6 +222,7 @@ def build_logging_cong(logfilepath:str):
skip_library_copy=not CommandLineArgs.copy_libraries,
legacy_block_access=CommandLineArgs.legacy_block_access,
user_defined_properties_to_include=CommandLineArgs.udp,
+ user_defined_properties_to_include_regex=CommandLineArgs.udp_regex,
hidden_inst_name_regex=CommandLineArgs.hide_regex,
legacy_enum_type=CommandLineArgs.legacy_enum_type,
skip_systemrdl_name_and_desc_properties=
From 4acae5cc280f63cece8c03b3b25447fe2a30faeb Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sat, 28 Mar 2026 07:31:23 +0000
Subject: [PATCH 2/9] Update version number ready to test
---
src/peakrdl_python/__about__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/peakrdl_python/__about__.py b/src/peakrdl_python/__about__.py
index c44f87af..503b4791 100644
--- a/src/peakrdl_python/__about__.py
+++ b/src/peakrdl_python/__about__.py
@@ -17,4 +17,4 @@
Variables that describes the peakrdl-python Package
"""
-__version__ = "3.0.0"
+__version__ = "3.1.0rc1"
From d609c7b226fa52637bad7ca8686400b2cfc4946d Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sat, 28 Mar 2026 08:10:28 +0000
Subject: [PATCH 3/9] Added support for referencing a field in a UDP
---
src/peakrdl_python/lib/base.py | 29 +++++++++++++++++
src/peakrdl_python/systemrdl_node_hashes.py | 7 ++++-
.../templates/addrmap_tb.py.jinja | 4 ++-
.../templates/addrmap_udp_property.py.jinja | 2 ++
tests/testcases/udp_with_referencing.rdl | 31 +++++++++++++++++++
5 files changed, 71 insertions(+), 2 deletions(-)
create mode 100644 tests/testcases/udp_with_referencing.rdl
diff --git a/src/peakrdl_python/lib/base.py b/src/peakrdl_python/lib/base.py
index 1219f88b..90cad9ef 100644
--- a/src/peakrdl_python/lib/base.py
+++ b/src/peakrdl_python/lib/base.py
@@ -97,6 +97,35 @@ def udp(self) -> UDPStruct:
"""
return {}
+ def _traverse_from_fully_qualified_name(self, fully_qualified_name: list[str]) -> 'Base':
+ """
+ This method allows another node in the structure to located based on a list of string
+ which represented the systemRDL path.
+
+ This function is intended for use with UDPs which reference other UDPs
+ """
+
+ # 1) location the root node by walking backwards up the tree until the parent is
+ # found
+ def locate_root(node: 'Base') -> 'Base':
+ if node.parent is None:
+ return node
+ return locate_root(node.parent)
+ root_node = locate_root(self)
+ # 2) check the 1st entry in the list matches the name of the root
+ if root_node.inst_name != fully_qualified_name[0]:
+ raise RuntimeError('root node name mismatch')
+ # 3) start walking down the tree matching the nodes
+ walking_node = root_node
+ for node_name in fully_qualified_name[1:]:
+ if not isinstance(walking_node, Node):
+ # the current node being traversed must be a Node type i.e. not a field
+ raise RuntimeError('node traversal has failed as type:{type(walking_node)} was'
+ ' unexpectedly encountered')
+ walking_node = walking_node.get_child_by_system_rdl_name(node_name)
+
+ return walking_node
+
@property
def rdl_name(self) -> Optional[str]:
"""
diff --git a/src/peakrdl_python/systemrdl_node_hashes.py b/src/peakrdl_python/systemrdl_node_hashes.py
index 410cd8b1..f4848f91 100644
--- a/src/peakrdl_python/systemrdl_node_hashes.py
+++ b/src/peakrdl_python/systemrdl_node_hashes.py
@@ -168,7 +168,12 @@ def __node_hash_components(node: Node,
value_to_hash.append(desc)
for udp in get_properties_to_include(node, udp_include_func):
- value_to_hash.append(node.get_property(udp))
+ udp_value = node.get_property(udp)
+ # systemRDL supports UDPs that cross-reference other parts of the register model
+ if isinstance(udp_value, Node):
+ value_to_hash.append('.'.join(udp_value.get_path_segments()))
+ else:
+ value_to_hash.append(node.get_property(udp))
return value_to_hash
diff --git a/src/peakrdl_python/templates/addrmap_tb.py.jinja b/src/peakrdl_python/templates/addrmap_tb.py.jinja
index 426cd1d7..1cd28768 100644
--- a/src/peakrdl_python/templates/addrmap_tb.py.jinja
+++ b/src/peakrdl_python/templates/addrmap_tb.py.jinja
@@ -102,8 +102,10 @@ class {{fq_block_name}}_single_access({{top_node.inst_name}}_TestCase): # type:
} )
{% elif isinstance(property_value, systemrdlUserEnum) %}
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ type(property_value).type_name }}_property_enumcls.{{ property_value.name.upper() }} )
- {% elif isinstance(property_value, str) %}
+ {% elif isinstance(property_value, str) %}
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], "{{ property_value }}" )
+ {% elif isinstance(property_value, systemrdlFieldNode) %}
+ self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], self.dut.{{'.'.join(get_python_path_segments(property_value))}} )
{% else %}
self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ property_value }} )
{% endif %}
diff --git a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
index f7758a75..6e96574b 100644
--- a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
+++ b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
@@ -27,6 +27,8 @@ along with this program. If not, see .
'{{name}}' : {{ type(value).type_name + '_property_enumcls.' + value.name.upper() }} ,
{% elif isinstance(value, str) %}
'{{name}}' : "{{ value }}" ,
+ {% elif isinstance(value, systemrdlFieldNode) %}
+ '{{name}}' : self._traverse_from_fully_qualified_name({{ value.get_path_segments() }}) ,
{% else %}
'{{name}}' : {{ value }} ,
{% endif %}
diff --git a/tests/testcases/udp_with_referencing.rdl b/tests/testcases/udp_with_referencing.rdl
new file mode 100644
index 00000000..5bd8ce02
--- /dev/null
+++ b/tests/testcases/udp_with_referencing.rdl
@@ -0,0 +1,31 @@
+/*
+Testcase the #292 bug
+with a UDP that cross-references another
+*/
+property field_pointer {
+ type = field;
+ component = field;
+};
+
+property register_pointer {
+ type = reg;
+ component = reg;
+};
+
+addrmap udp_with_referencing {
+ reg {
+ field {
+ hw = rw;
+ sw = rw;
+ } value;
+ } view;
+
+ reg {
+ field {
+ hw = rw;
+ sw = rw;
+ } value;
+ } pointer;
+
+ view.value->field_pointer = pointer.value;
+};
\ No newline at end of file
From 52ca4a1e89d8e9b433fc5caf8780c99dc231e048 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 29 Mar 2026 17:06:10 +0100
Subject: [PATCH 4/9] Extended the implementation to include referencing
registers, regfiles and address maps
---
src/peakrdl_python/exporter.py | 1 +
src/peakrdl_python/systemrdl_node_hashes.py | 16 ++--
.../templates/addrmap_tb.py.jinja | 4 +-
.../templates/addrmap_udp_property.py.jinja | 22 +++--
tests/testcases/udp_with_referencing.rdl | 89 +++++++++++++++----
5 files changed, 100 insertions(+), 32 deletions(-)
diff --git a/src/peakrdl_python/exporter.py b/src/peakrdl_python/exporter.py
index 641aa48d..1c661d7e 100644
--- a/src/peakrdl_python/exporter.py
+++ b/src/peakrdl_python/exporter.py
@@ -587,6 +587,7 @@ def __export_reg_model_fields(self, *,
context = {
'top_node': top_block,
'systemrdlFieldNode': FieldNode,
+ 'systemrdlRegNode': RegNode,
'systemrdlUserStruct': UserStruct,
'systemrdlUserEnum': UserEnum,
'isinstance': isinstance,
diff --git a/src/peakrdl_python/systemrdl_node_hashes.py b/src/peakrdl_python/systemrdl_node_hashes.py
index 4d45d3d2..db1f0c25 100644
--- a/src/peakrdl_python/systemrdl_node_hashes.py
+++ b/src/peakrdl_python/systemrdl_node_hashes.py
@@ -167,14 +167,18 @@ def __node_hash_components(node: Node,
if desc is not None:
value_to_hash.append(desc)
+ def udp_replace_for_hashing(item):
+ if isinstance(item, list):
+ for child_udp_value in item:
+ udp_replace_for_hashing(child_udp_value)
+ elif isinstance(item, Node):
+ value_to_hash.append('.'.join(item.get_path_segments()))
+ else:
+ value_to_hash.append(item)
+
for udp in get_properties_to_include(node, udp_include_func):
udp_value = node.get_property(udp)
- if isinstance(udp_value, list):
- value_to_hash.append(tuple(udp_value))
- elif isinstance(udp_value, Node):
- value_to_hash.append('.'.join(udp_value.get_path_segments()))
- else:
- value_to_hash.append(udp_value)
+ udp_replace_for_hashing(udp_value)
return value_to_hash
diff --git a/src/peakrdl_python/templates/addrmap_tb.py.jinja b/src/peakrdl_python/templates/addrmap_tb.py.jinja
index 85f71a8d..f5dd7d72 100644
--- a/src/peakrdl_python/templates/addrmap_tb.py.jinja
+++ b/src/peakrdl_python/templates/addrmap_tb.py.jinja
@@ -98,9 +98,9 @@ class {{fq_block_name}}_single_access({{top_node.inst_name}}_TestCase): # type:
{% for property_name in property_list %}
{% set property_value = node.get_property(property_name) %}
{% if isinstance(property_value, list) %}
- self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], [{% for sub_property_value in property_value %}{{ udp_property_entry(sub_property_value) }},{% endfor %}] )
+ self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], [{% for sub_property_value in property_value %}{{ udp_property_entry(sub_property_value, true) }},{% endfor %}] )
{% else %}
- self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ udp_property_entry(property_value) }} )
+ self.assertEqual(self.dut.{{'.'.join(get_python_path_segments(node))}}.udp['{{property_name}}'], {{ udp_property_entry(property_value, true) }} )
{% endif %}
{% endfor %}
{% endif %}
diff --git a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
index 927b4131..3715c66c 100644
--- a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
+++ b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
@@ -16,29 +16,33 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
#}
-{%- macro udp_property_entry(value) %}
+{%- macro udp_property_entry(value, full_qual_resolution) %}
{%- if isinstance(value, systemrdlUserStruct) -%}
{
{%- for sub_name, sub_value in value.members.items() %}
- {{udp_property_dict_entry(sub_name, sub_value)|indent(4)}}
+ {{udp_property_dict_entry(sub_name, sub_value, full_qual_resolution)|indent(4)}}
{%- endfor %}
}
{%- elif isinstance(value, systemrdlUserEnum) -%}
{{ type(value).type_name + '_property_enumcls.' + value.name.upper() }}
{%- elif isinstance(value, str) -%}
"{{ value }}"
- {% elif isinstance(value, systemrdlFieldNode) %}
+ {%- elif isinstance(value, (systemrdlFieldNode, systemrdlRegNode, systemrdlRegfileNode, systemrdlAddrmapNode )) -%}
+ {%- if full_qual_resolution -%}
+ self.dut.{{'.'.join(get_python_path_segments(value))}}
+ {%- else -%}
self._traverse_from_fully_qualified_name({{ value.get_path_segments() }})
+ {%- endif -%}
{%- else -%}
{{ value }}
{%- endif -%}
{%- endmacro %}
-{%- macro udp_property_dict_entry(name, value) %}
+{%- macro udp_property_dict_entry(name, value, full_qual_resolution) %}
{%- if isinstance(value, list) -%}
- '{{name}}' : [ {% for sub_value in value %}{{udp_property_entry(sub_value)|indent(4)}}, {% endfor %}],
+ '{{name}}' : [ {% for sub_value in value %}{{udp_property_entry(sub_value, full_qual_resolution)}}, {% endfor %}],
{%- else -%}
- '{{name}}' : {{ udp_property_entry(value) }},
+ '{{name}}' : {{ udp_property_entry(value, full_qual_resolution) }},
{%- endif %}
{% endmacro %}
@@ -49,9 +53,9 @@ along with this program. If not, see .
@property
def udp(self) -> UDPStruct:
return {
- {% for property_name in property_list %}
- {{udp_property_dict_entry(property_name, node.instance.get_property(property_name))}}
- {% endfor %}
+ {% for property_name in property_list -%}
+ {{udp_property_dict_entry(property_name, node.instance.get_property(property_name), false)|indent(4)}}
+ {%- endfor %}
}
{% endif %}
diff --git a/tests/testcases/udp_with_referencing.rdl b/tests/testcases/udp_with_referencing.rdl
index 5bd8ce02..be51319e 100644
--- a/tests/testcases/udp_with_referencing.rdl
+++ b/tests/testcases/udp_with_referencing.rdl
@@ -12,20 +12,79 @@ property register_pointer {
component = reg;
};
+property register_file_pointer {
+ type = regfile;
+ component = regfile;
+};
+
+property field_parent_pointer {
+ type = reg;
+ component = field;
+};
+
+property register_child_pointer {
+ type = field[];
+ component = reg;
+};
+
+struct addrmap_child {
+ regfile regfile_children[];
+ reg reg_children[];
+ addrmap addrmap_children[];
+};
+
+property addrmap_child_pointer {
+ type = addrmap_child;
+ component = addrmap;
+};
+
+struct regfile_child {
+ regfile regfile_children[];
+ reg reg_children[];
+};
+
+property regfile_child_pointer {
+ type = regfile_child;
+ component = regfile;
+};
+
addrmap udp_with_referencing {
- reg {
- field {
- hw = rw;
- sw = rw;
- } value;
- } view;
-
- reg {
- field {
- hw = rw;
- sw = rw;
- } value;
- } pointer;
-
- view.value->field_pointer = pointer.value;
+
+ reg reg_def {
+ field { fieldwidth=4; } field_a;
+ field { fieldwidth=4; } field_b;
+ field { fieldwidth=4; } field_c;
+ field { fieldwidth=4; } field_d;
+ register_child_pointer = '{ field_a, field_b, field_c, field_d } ;
+ };
+
+ regfile regfile_def {
+ regfile inner_regfile_def {
+ reg_def reg_value;
+ regfile_child_pointer = regfile_child'{ reg_children:'{ reg_value } };
+ };
+ reg_def reg_value;
+ inner_regfile_def inner_regfile_value;
+ regfile_child_pointer = regfile_child'{ reg_children:'{ reg_value }, regfile_children:'{ inner_regfile_value } };
+ };
+
+ addrmap addrmap_def {
+ addrmap inner_addrmap_def {
+ reg_def reg_value;
+ regfile_def regfile_value;
+ addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value } };
+ };
+ reg_def reg_value;
+ regfile_def regfile_value;
+ inner_addrmap_def addrmap_value;
+ addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value }, addrmap_children:'{ addrmap_value } };
+ };
+
+ addrmap_def main;
+ addrmap_def view;
+
+ view.reg_value.field_a->field_pointer = main.reg_value.field_a;
+ view.reg_value.field_a->field_parent_pointer = main.reg_value;
+
+ view.reg_value->register_pointer = main.reg_value;
};
\ No newline at end of file
From 86db404885933db291c09b9db0a32631a831b4d5 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 29 Mar 2026 17:08:48 +0100
Subject: [PATCH 5/9] Fix typing on internal function
---
src/peakrdl_python/systemrdl_node_hashes.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/peakrdl_python/systemrdl_node_hashes.py b/src/peakrdl_python/systemrdl_node_hashes.py
index db1f0c25..2492f0e4 100644
--- a/src/peakrdl_python/systemrdl_node_hashes.py
+++ b/src/peakrdl_python/systemrdl_node_hashes.py
@@ -167,7 +167,7 @@ def __node_hash_components(node: Node,
if desc is not None:
value_to_hash.append(desc)
- def udp_replace_for_hashing(item):
+ def udp_replace_for_hashing(item: Any) -> None:
if isinstance(item, list):
for child_udp_value in item:
udp_replace_for_hashing(child_udp_value)
From 2a3d141df735a6836dc5d74efcaa4896edbbd408 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 29 Mar 2026 18:07:33 +0100
Subject: [PATCH 6/9] Fixed missing context from the register model generation
---
src/peakrdl_python/exporter.py | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/peakrdl_python/exporter.py b/src/peakrdl_python/exporter.py
index 1c661d7e..56c2ff89 100644
--- a/src/peakrdl_python/exporter.py
+++ b/src/peakrdl_python/exporter.py
@@ -415,8 +415,11 @@ def init_line_entry(module_name: str,
context = {
'top_node': top_block,
- 'systemrdlRegNode': RegNode,
'systemrdlFieldNode': FieldNode,
+ 'systemrdlRegNode': RegNode,
+ 'systemrdlRegfileNode': RegfileNode,
+ 'systemrdlAddrmapNode': AddrmapNode,
+ 'systemrdlMemNode': MemNode,
'systemrdlSignalNode': SignalNode,
'systemrdlUserStruct': UserStruct,
'systemrdlUserEnum': UserEnum,
@@ -513,8 +516,11 @@ def init_line_entry(module_name:str,
context = {
'top_node': top_block,
- 'systemrdlMemNode': MemNode,
'systemrdlFieldNode': FieldNode,
+ 'systemrdlRegNode': RegNode,
+ 'systemrdlRegfileNode': RegfileNode,
+ 'systemrdlAddrmapNode': AddrmapNode,
+ 'systemrdlMemNode': MemNode,
'systemrdlSignalNode': SignalNode,
'systemrdlUserStruct': UserStruct,
'systemrdlUserEnum': UserEnum,
@@ -588,6 +594,9 @@ def __export_reg_model_fields(self, *,
'top_node': top_block,
'systemrdlFieldNode': FieldNode,
'systemrdlRegNode': RegNode,
+ 'systemrdlRegfileNode': RegfileNode,
+ 'systemrdlAddrmapNode': AddrmapNode,
+ 'systemrdlMemNode': MemNode,
'systemrdlUserStruct': UserStruct,
'systemrdlUserEnum': UserEnum,
'isinstance': isinstance,
From 0c5f47d9f18d8dd3a75a96f6bfa431bbc21edf17 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 29 Mar 2026 18:14:29 +0100
Subject: [PATCH 7/9] Added support for memory referencing in UDPs
---
.../templates/addrmap_udp_property.py.jinja | 2 +-
tests/testcases/udp_with_referencing.rdl | 11 ++++++++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
index 3715c66c..4681d5cb 100644
--- a/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
+++ b/src/peakrdl_python/templates/addrmap_udp_property.py.jinja
@@ -27,7 +27,7 @@ along with this program. If not, see .
{{ type(value).type_name + '_property_enumcls.' + value.name.upper() }}
{%- elif isinstance(value, str) -%}
"{{ value }}"
- {%- elif isinstance(value, (systemrdlFieldNode, systemrdlRegNode, systemrdlRegfileNode, systemrdlAddrmapNode )) -%}
+ {%- elif isinstance(value, (systemrdlFieldNode, systemrdlRegNode, systemrdlRegfileNode, systemrdlAddrmapNode, systemrdlMemNode)) -%}
{%- if full_qual_resolution -%}
self.dut.{{'.'.join(get_python_path_segments(value))}}
{%- else -%}
diff --git a/tests/testcases/udp_with_referencing.rdl b/tests/testcases/udp_with_referencing.rdl
index be51319e..6e70e058 100644
--- a/tests/testcases/udp_with_referencing.rdl
+++ b/tests/testcases/udp_with_referencing.rdl
@@ -30,6 +30,7 @@ property register_child_pointer {
struct addrmap_child {
regfile regfile_children[];
reg reg_children[];
+ mem mem_children[];
addrmap addrmap_children[];
};
@@ -68,6 +69,13 @@ addrmap udp_with_referencing {
regfile_child_pointer = regfile_child'{ reg_children:'{ reg_value }, regfile_children:'{ inner_regfile_value } };
};
+ mem mem_def {
+ mementries = 32;
+ memwidth = 32;
+
+ reg_def reg_value;
+ };
+
addrmap addrmap_def {
addrmap inner_addrmap_def {
reg_def reg_value;
@@ -76,8 +84,9 @@ addrmap udp_with_referencing {
};
reg_def reg_value;
regfile_def regfile_value;
+ external mem_def mem_value;
inner_addrmap_def addrmap_value;
- addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value }, addrmap_children:'{ addrmap_value } };
+ addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value }, addrmap_children:'{ addrmap_value }, mem_children:'{ mem_value } };
};
addrmap_def main;
From 9b8989e3c8be3cc219d9c62be8494a2856068141 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 5 Apr 2026 11:46:07 +0100
Subject: [PATCH 8/9] Added supprot for UDP pointing to node within an array
---
src/peakrdl_python/lib/base.py | 15 +++++++++++++++
tests/testcases/udp_with_referencing.rdl | 19 +++++++++++++++++--
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/peakrdl_python/lib/base.py b/src/peakrdl_python/lib/base.py
index 90cad9ef..4c570bad 100644
--- a/src/peakrdl_python/lib/base.py
+++ b/src/peakrdl_python/lib/base.py
@@ -26,12 +26,15 @@
from itertools import product
from enum import IntEnum, Enum, auto
import math
+import re
from .callbacks import CallbackSet, CallbackSetLegacy
UDPStruct = dict[str, 'UDPType']
UDPType = Union[str, int, bool, IntEnum, UDPStruct]
+array_instance_re = re.compile(r'(?P[A-Za-z_0-9]*)\[(?P\d+)\]')
+
class Base(ABC):
"""
base class of for all types
@@ -229,6 +232,18 @@ def get_child_by_system_rdl_name(self, name: Any) -> Any:
"""
if not isinstance(name, str):
raise TypeError(f'name must be a string got {type(name)}')
+
+ # check if an array style child pointer
+ array_name_match = array_instance_re.match(name)
+ if array_name_match:
+ root_name = array_name_match.group("root_name")
+ index = int(array_name_match.group("index"))
+ child_array = getattr(self, self.systemrdl_python_child_name_map[root_name])
+ if not isinstance(child_array, NodeArray):
+ raise ValueError('attempting to use array indexing into a non-array '
+ f'node: {root_name} of type:{type(child_array)}')
+ return child_array[index]
+
return getattr(self, self.systemrdl_python_child_name_map[name])
@property
diff --git a/tests/testcases/udp_with_referencing.rdl b/tests/testcases/udp_with_referencing.rdl
index 6e70e058..4f685627 100644
--- a/tests/testcases/udp_with_referencing.rdl
+++ b/tests/testcases/udp_with_referencing.rdl
@@ -49,6 +49,11 @@ property regfile_child_pointer {
component = regfile;
};
+property mem_child_pointer {
+ type = reg[];
+ component = mem;
+};
+
addrmap udp_with_referencing {
reg reg_def {
@@ -74,6 +79,7 @@ addrmap udp_with_referencing {
memwidth = 32;
reg_def reg_value;
+ mem_child_pointer = '{ reg_value } ;
};
addrmap addrmap_def {
@@ -83,10 +89,10 @@ addrmap udp_with_referencing {
addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value } };
};
reg_def reg_value;
- regfile_def regfile_value;
+ regfile_def addrmap_regfile_value;
external mem_def mem_value;
inner_addrmap_def addrmap_value;
- addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ regfile_value }, addrmap_children:'{ addrmap_value }, mem_children:'{ mem_value } };
+ addrmap_child_pointer = addrmap_child'{ reg_children:'{ reg_value }, regfile_children:'{ addrmap_regfile_value }, addrmap_children:'{ addrmap_value }, mem_children:'{ mem_value } };
};
addrmap_def main;
@@ -96,4 +102,13 @@ addrmap udp_with_referencing {
view.reg_value.field_a->field_parent_pointer = main.reg_value;
view.reg_value->register_pointer = main.reg_value;
+
+ reg basic_reg_def {
+ // a register def without any UDPs
+ field { fieldwidth=4; } field_a;
+ };
+
+ basic_reg_def basic_reg_array[3];
+ main.addrmap_value.reg_value -> register_pointer = basic_reg_array[0];
+ main.addrmap_value.regfile_value.reg_value -> register_pointer = basic_reg_array[1];
};
\ No newline at end of file
From ea941261d148f201667eb7b6c46dcc7e33020842 Mon Sep 17 00:00:00 2001
From: krcb197 <34693973+krcb197@users.noreply.github.com>
Date: Sun, 5 Apr 2026 11:55:50 +0100
Subject: [PATCH 9/9] Increase the version number ready for another pre-release
---
src/peakrdl_python/__about__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/peakrdl_python/__about__.py b/src/peakrdl_python/__about__.py
index 74dbc3f7..7fff5899 100644
--- a/src/peakrdl_python/__about__.py
+++ b/src/peakrdl_python/__about__.py
@@ -17,4 +17,4 @@
Variables that describes the peakrdl-python Package
"""
-__version__ = "3.1.0rc2"
+__version__ = "3.1.0rc3"