Fix non-synthesizable code generation for nested addrmaps with arrays (#11)

* Initial plan

* Fix non-synthesizable code for nested addrmaps with arrays

Fixed bug where array dimensions were used instead of strides in decode logic.
For nested addrmaps with arrays like inner[4] @ 0x0 += 0x100, the generated
code was incorrectly using the dimension (4) instead of the stride (0x100).
This resulted in non-synthesizable SystemVerilog with incorrect address decoding.

The fix calculates proper strides for each dimension, including support for
multi-dimensional arrays like [2][3] where each dimension has a different stride.

Added comprehensive tests to prevent regression.

Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>

* Improve code comments for stride calculation clarity

Added more detailed comments explaining the stride calculation logic,
including a concrete example showing how strides are calculated for
multi-dimensional arrays.

Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>
This commit is contained in:
Copilot
2025-10-24 10:35:28 -07:00
committed by GitHub
parent 9b6dbc30e2
commit 04971bdb8e
2 changed files with 90 additions and 1 deletions

View File

@@ -15,7 +15,23 @@ class BusDecoderListener(RDLListener):
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
if node.array_dimensions:
assert node.array_stride is not None, "Array stride should be defined for arrayed components"
self._array_stride_stack.extend(node.array_dimensions)
# Calculate stride for each dimension
# For multi-dimensional arrays like [2][3], array_stride gives the stride of the
# rightmost (fastest-changing) dimension. We need to calculate strides for all dimensions.
# Example: for [2][3] with 4-byte elements:
# - i1 (rightmost/fastest): stride = 4 (from array_stride)
# - i0 (leftmost/slowest): stride = 3 * 4 = 12
strides = []
current_stride = node.array_stride
strides.append(current_stride)
# Work backwards from rightmost to leftmost dimension (fastest to slowest changing)
# Each dimension's stride is the product of its size and the previous dimension's stride
for i in range(len(node.array_dimensions) - 1, 0, -1):
current_stride = current_stride * node.array_dimensions[i]
strides.insert(0, current_stride)
self._array_stride_stack.extend(strides)
self._depth += 1