From 543bf2be9af55e6639d762cd74ba8116843b5d30 Mon Sep 17 00:00:00 2001 From: Alex Mykyta Date: Tue, 4 Nov 2025 23:05:50 -0800 Subject: [PATCH] Remove dangerous usage of non-public parts of the systemrdl-compiler API --- pyproject.toml | 4 ++-- src/peakrdl_regblock/dereferencer.py | 2 +- src/peakrdl_regblock/exporter.py | 2 +- .../field_logic/generators.py | 2 +- src/peakrdl_regblock/hwif/__init__.py | 8 +++---- src/peakrdl_regblock/scan_design.py | 4 ++-- src/peakrdl_regblock/udps/fixedpoint.py | 2 +- src/peakrdl_regblock/udps/signed.py | 4 ++-- src/peakrdl_regblock/validate_design.py | 22 +++++++++---------- .../implementation_generator.py | 2 +- .../write_buffering/template.sv | 2 +- 11 files changed, 26 insertions(+), 28 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index db6f4f1..a50292d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,8 @@ name = "peakrdl-regblock" dynamic = ["version"] requires-python = ">=3.7" dependencies = [ - "systemrdl-compiler ~= 1.29", - "Jinja2>=2.11", + "systemrdl-compiler ~= 1.30", + "Jinja2 >= 2.11", ] authors = [ diff --git a/src/peakrdl_regblock/dereferencer.py b/src/peakrdl_regblock/dereferencer.py index d80e6ed..edcff5a 100644 --- a/src/peakrdl_regblock/dereferencer.py +++ b/src/peakrdl_regblock/dereferencer.py @@ -70,7 +70,7 @@ class Dereferencer: # No reset value defined! obj.env.msg.warning( f"Field '{obj.inst_name}' is a constant but does not have a known value (missing reset). Assigning it a value of X.", - obj.inst.inst_src_ref + obj.inst_src_ref, ) return "'X" diff --git a/src/peakrdl_regblock/exporter.py b/src/peakrdl_regblock/exporter.py index 221935d..ba4d2d6 100644 --- a/src/peakrdl_regblock/exporter.py +++ b/src/peakrdl_regblock/exporter.py @@ -315,7 +315,7 @@ class DesignState: # Assume 32-bits msg.warning( "Addrmap being exported only contains external components. Unable to infer the CPUIF bus width. Assuming 32-bits.", - self.top_node.inst.def_src_ref + self.top_node.def_src_ref ) self.cpuif_data_width = 32 diff --git a/src/peakrdl_regblock/field_logic/generators.py b/src/peakrdl_regblock/field_logic/generators.py index c19ee25..281ecb2 100644 --- a/src/peakrdl_regblock/field_logic/generators.py +++ b/src/peakrdl_regblock/field_logic/generators.py @@ -227,7 +227,7 @@ class FieldLogicGenerator(RDLForLoopGenerator): "Field has multiple conflicting properties that unconditionally set its state:\n" f" * {conditional.unconditional_explanation}\n" f" * {unconditional.unconditional_explanation}", - node.inst.inst_src_ref + node.inst_src_ref ) unconditional = conditional else: diff --git a/src/peakrdl_regblock/hwif/__init__.py b/src/peakrdl_regblock/hwif/__init__.py index 54b92a5..74b3e7c 100644 --- a/src/peakrdl_regblock/hwif/__init__.py +++ b/src/peakrdl_regblock/hwif/__init__.py @@ -51,16 +51,14 @@ class Hwif: def get_extra_package_params(self) -> str: lines = [""] - - for param in self.top_node.inst.parameters: - value = param.get_value() + for name, value in self.top_node.parameters.items(): if isinstance(value, int): lines.append( - f"localparam {param.name} = {SVInt(value)};" + f"localparam {name} = {SVInt(value)};" ) elif isinstance(value, str): lines.append( - f"localparam {param.name} = {value};" + f"localparam {name} = {value};" ) return "\n".join(lines) diff --git a/src/peakrdl_regblock/scan_design.py b/src/peakrdl_regblock/scan_design.py index 961b5e7..e1482d8 100644 --- a/src/peakrdl_regblock/scan_design.py +++ b/src/peakrdl_regblock/scan_design.py @@ -53,7 +53,7 @@ class DesignScanner(RDLListener): if self.top_node.get_property('bridge'): self.msg.error( "Regblock generator does not support exporting bridge address maps", - self.top_node.inst.property_src_ref.get('bridge', self.top_node.inst.inst_src_ref) + self.top_node.property_src_ref.get('bridge', self.top_node.inst_src_ref), ) RDLWalker().walk(self.top_node, self) @@ -117,5 +117,5 @@ class DesignScanner(RDLListener): f"Field '{node.inst_name}' includes parity check logic, but " "its reset value was not defined. Will result in an undefined " "value on the module's 'parity_error' output.", - self.top_node.inst.property_src_ref.get('paritycheck', self.top_node.inst.inst_src_ref) + self.top_node.property_src_ref.get('paritycheck', self.top_node.inst_src_ref) ) diff --git a/src/peakrdl_regblock/udps/fixedpoint.py b/src/peakrdl_regblock/udps/fixedpoint.py index cf47534..ea129e4 100644 --- a/src/peakrdl_regblock/udps/fixedpoint.py +++ b/src/peakrdl_regblock/udps/fixedpoint.py @@ -16,7 +16,7 @@ class _FixedpointWidth(UDPDefinition): fracwidth = node.get_property("fracwidth") assert intwidth is not None assert fracwidth is not None - prop_ref = node.inst.property_src_ref.get(self.name) + prop_ref = node.property_src_ref.get(self.name, node.inst_src_ref) # incompatible with "counter" fields if node.get_property("counter"): diff --git a/src/peakrdl_regblock/udps/signed.py b/src/peakrdl_regblock/udps/signed.py index b342986..55e29bd 100644 --- a/src/peakrdl_regblock/udps/signed.py +++ b/src/peakrdl_regblock/udps/signed.py @@ -16,14 +16,14 @@ class IsSigned(UDPDefinition): if value and node.get_property("counter"): self.msg.error( "The property is_signed=true is not supported for counter fields.", - node.inst.property_src_ref["is_signed"] + node.property_src_ref.get("is_signed", node.inst_src_ref) ) # incompatible with "encode" fields if value and node.get_property("encode") is not None: self.msg.error( "The property is_signed=true is not supported for fields encoded as an enum.", - node.inst.property_src_ref["is_signed"] + node.property_src_ref.get("is_signed", node.inst_src_ref) ) def get_unassigned_default(self, node: "Node") -> Any: diff --git a/src/peakrdl_regblock/validate_design.py b/src/peakrdl_regblock/validate_design.py index 7b8e9f8..1ce14f2 100644 --- a/src/peakrdl_regblock/validate_design.py +++ b/src/peakrdl_regblock/validate_design.py @@ -49,7 +49,7 @@ class DesignValidator(RDLListener): if isinstance(value, PropertyReference): src_ref = value.src_ref else: - src_ref = node.inst.property_src_ref.get(prop_name, node.inst.inst_src_ref) + src_ref = node.property_src_ref.get(prop_name, node.inst_src_ref) self.msg.error( "Property is assigned a reference that points to a component not internal to the regblock being exported.", src_ref @@ -65,7 +65,7 @@ class DesignValidator(RDLListener): "Only cpuif_reset signals that are instantiated in the top-level " "addrmap or above will be honored. Any cpuif_reset signals nested " "within children of the addrmap being exported will be ignored.", - node.inst.inst_src_ref + node.inst_src_ref ) def enter_AddressableComponent(self, node: 'AddressableNode') -> None: @@ -75,13 +75,13 @@ class DesignValidator(RDLListener): self.msg.error( "Unaligned registers are not supported. Address offset of " f"instance '{node.inst_name}' must be a multiple of {alignment}", - node.inst.inst_src_ref + node.inst_src_ref ) if node.is_array and (node.array_stride % alignment) != 0: # type: ignore # is_array implies stride is not none self.msg.error( "Unaligned registers are not supported. Address stride of " f"instance array '{node.inst_name}' must be a multiple of {alignment}", - node.inst.inst_src_ref + node.inst_src_ref ) if not isinstance(node, RegNode): @@ -102,7 +102,7 @@ class DesignValidator(RDLListener): if node.get_property('sharedextbus'): self.msg.error( "This exporter does not support enabling the 'sharedextbus' property yet.", - node.inst.property_src_ref.get('sharedextbus', node.inst.inst_src_ref) + node.property_src_ref.get('sharedextbus', node.inst_src_ref) ) def enter_Reg(self, node: 'RegNode') -> None: @@ -117,7 +117,7 @@ class DesignValidator(RDLListener): f"Multi-word registers that have an accesswidth ({accesswidth}) " "that are inconsistent with this regblock's CPU bus width " f"({self.exp.cpuif.data_width}) are not supported.", - node.inst.inst_src_ref + node.inst_src_ref ) @@ -138,7 +138,7 @@ class DesignValidator(RDLListener): " multiple software-accessible subwords. Consider enabling" " write double-buffering.\n" "For more details, see: https://peakrdl-regblock.readthedocs.io/en/latest/udps/write_buffering.html", - node.inst.inst_src_ref + node.inst_src_ref ) if node.get_property('onread') is not None and not node.parent.get_property('buffer_reads'): @@ -150,7 +150,7 @@ class DesignValidator(RDLListener): " access its value correctly. Consider enabling read" " double-buffering. \n" "For more details, see: https://peakrdl-regblock.readthedocs.io/en/latest/udps/read_buffering.html", - node.inst.inst_src_ref + node.inst_src_ref ) # Check for unsynthesizable reset @@ -166,7 +166,7 @@ class DesignValidator(RDLListener): if is_async_reset: self.msg.error( "A field that uses an asynchronous reset cannot use a dynamic reset value. This is not synthesizable.", - node.inst.inst_src_ref + node.inst_src_ref ) @@ -195,7 +195,7 @@ class DesignValidator(RDLListener): self.msg.error( f"Address offset +0x{node.raw_address_offset:x} of instance '{node.inst_name}' is not a power of 2 multiple of its size 0x{node.size:x}. " f"This is required by the regblock exporter if a component {err_suffix}.", - node.inst.inst_src_ref + node.inst_src_ref ) if node.is_array: assert node.array_stride is not None @@ -203,5 +203,5 @@ class DesignValidator(RDLListener): self.msg.error( f"Address stride of instance array '{node.inst_name}' is not a power of 2" f"This is required by the regblock exporter if a component {err_suffix}.", - node.inst.inst_src_ref + node.inst_src_ref ) diff --git a/src/peakrdl_regblock/write_buffering/implementation_generator.py b/src/peakrdl_regblock/write_buffering/implementation_generator.py index ec2a640..a3dbc06 100644 --- a/src/peakrdl_regblock/write_buffering/implementation_generator.py +++ b/src/peakrdl_regblock/write_buffering/implementation_generator.py @@ -35,7 +35,7 @@ class WBufLogicGenerator(RDLForLoopGenerator): n_subwords = regwidth // accesswidth for i in range(n_subwords): strobe = strb_prefix + f"[{i}]" - if node.inst.is_msb0_order: + if node.is_msb0_order: bslice = f"[{regwidth - (accesswidth * i) - 1}: {regwidth - (accesswidth * (i+1))}]" else: bslice = f"[{(accesswidth * (i + 1)) - 1}:{accesswidth * i}]" diff --git a/src/peakrdl_regblock/write_buffering/template.sv b/src/peakrdl_regblock/write_buffering/template.sv index 78bbf46..6b1f7df 100644 --- a/src/peakrdl_regblock/write_buffering/template.sv +++ b/src/peakrdl_regblock/write_buffering/template.sv @@ -15,7 +15,7 @@ always_ff {{get_always_ff_event(cpuif.reset)}} begin {%- for segment in segments %} if({{segment.strobe}} && decoded_req_is_wr) begin {{wbuf_prefix}}.pending <= '1; - {%- if node.inst.is_msb0_order %} + {%- if node.is_msb0_order %} {{wbuf_prefix}}.data{{segment.bslice}} <= ({{wbuf_prefix}}.data{{segment.bslice}} & ~decoded_wr_biten_bswap) | (decoded_wr_data_bswap & decoded_wr_biten_bswap); {{wbuf_prefix}}.biten{{segment.bslice}} <= {{wbuf_prefix}}.biten{{segment.bslice}} | decoded_wr_biten_bswap; {%- else %}