diff --git a/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py b/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py index 357c46b..17ec392 100644 --- a/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py +++ b/src/peakrdl_busdecoder/cpuif/apb4/apb4_cpuif_flat.py @@ -35,17 +35,17 @@ class APB4CpuifFlat(BaseCpuif): def fanout(self, node: AddressableNode) -> str: fanout: dict[str, str] = {} - fanout[self.signal("PSEL", node)] = ( - f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}" + fanout[self.signal("PSEL", node, "gi")] = ( + f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}" ) - fanout[self.signal("PENABLE", node)] = self.signal("PENABLE") - fanout[self.signal("PWRITE", node)] = ( - f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'i')}" + fanout[self.signal("PENABLE", node, "gi")] = self.signal("PENABLE") + fanout[self.signal("PWRITE", node, "gi")] = ( + f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}" ) - fanout[self.signal("PADDR", node)] = self.signal("PADDR") - fanout[self.signal("PPROT", node)] = self.signal("PPROT") - fanout[self.signal("PWDATA", node)] = "cpuif_wr_data" - fanout[self.signal("PSTRB", node)] = "cpuif_wr_byte_en" + fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR") + fanout[self.signal("PPROT", node, "gi")] = self.signal("PPROT") + fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data" + fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en" return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items())) @@ -55,8 +55,8 @@ class APB4CpuifFlat(BaseCpuif): fanin["cpuif_rd_ack"] = "'0" fanin["cpuif_rd_err"] = "'0" else: - fanin["cpuif_rd_ack"] = self.signal("PREADY", node) - fanin["cpuif_rd_err"] = self.signal("PSLVERR", node) + fanin["cpuif_rd_ack"] = self.signal("PREADY", node, "i") + fanin["cpuif_rd_err"] = self.signal("PSLVERR", node, "i") return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items())) @@ -65,6 +65,6 @@ class APB4CpuifFlat(BaseCpuif): if node is None: fanin["cpuif_rd_data"] = "'0" else: - fanin["cpuif_rd_data"] = self.signal("PRDATA", node) + fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i") return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items())) diff --git a/src/peakrdl_busdecoder/cpuif/interface.py b/src/peakrdl_busdecoder/cpuif/interface.py index 8971aa8..6c27451 100644 --- a/src/peakrdl_busdecoder/cpuif/interface.py +++ b/src/peakrdl_busdecoder/cpuif/interface.py @@ -1,10 +1,13 @@ """Interface abstraction for handling flat and non-flat signal declarations.""" +import re from abc import ABC, abstractmethod from typing import TYPE_CHECKING from systemrdl.node import AddressableNode +from ..utils import get_indexed_path + if TYPE_CHECKING: from .base_cpuif import BaseCpuif @@ -93,7 +96,6 @@ class SVInterface(Interface): indexer: str | int | None = None, ) -> str: """Generate SystemVerilog interface signal reference.""" - from ..utils import get_indexed_path # SVInterface only supports string indexers (loop variable names like "i", "gi") if indexer is not None and not isinstance(indexer, str): @@ -166,6 +168,13 @@ class FlatInterface(Interface): # Is an array if indexer is not None: + if isinstance(indexer, str): + indexed_path = get_indexed_path(node.parent, node, indexer, skip_kw_filter=True) + pattern = r"\[.*?\]" + indexes = re.findall(pattern, indexed_path) + + return f"{base}_{signal}{''.join(indexes)}" + return f"{base}_{signal}[{indexer}]" return f"{base}_{signal}[N_{node.inst_name.upper()}S]" diff --git a/src/peakrdl_busdecoder/decode_logic_gen.py b/src/peakrdl_busdecoder/decode_logic_gen.py index 90ff59f..3180f6e 100644 --- a/src/peakrdl_busdecoder/decode_logic_gen.py +++ b/src/peakrdl_busdecoder/decode_logic_gen.py @@ -70,7 +70,9 @@ class DecodeLogicGenerator(BusDecoderListener): # Avoid generating a redundant >= 0 comparison, which triggers Verilator warnings. if not (l_bound.value == 0 and len(l_bound_comp) == 1): predicates.append(lower_expr) - predicates.append(upper_expr) + # Avoid generating a redundant full-width < max comparison, which triggers Verilator warnings. + if not (u_bound.value == (1 << addr_width) and len(u_bound_comp) == 1): + predicates.append(upper_expr) return predicates diff --git a/src/peakrdl_busdecoder/sv_int.py b/src/peakrdl_busdecoder/sv_int.py index bd77d9c..140cd31 100644 --- a/src/peakrdl_busdecoder/sv_int.py +++ b/src/peakrdl_busdecoder/sv_int.py @@ -7,7 +7,7 @@ class SVInt: self.width = width if width is not None: - self.width = max(width, self.value.bit_length()) + self.width = width # assert (width is None) or (self.value.bit_length() <= width), "Value does not fit in specified width" def __str__(self) -> str: @@ -46,7 +46,7 @@ class SVInt: def __eq__(self, other: object) -> bool: if not isinstance(other, SVInt): return NotImplemented - return self.value == other.value and self.width == other.width - + return self.value == other.value and self.width == other.width + def __hash__(self) -> int: - return hash((self.value, self.width)) \ No newline at end of file + return hash((self.value, self.width))