Files
PeakRDL-BusDecoder/src/peakrdl_busdecoder/cpuif/fanout_gen.py
Copilot d7481e71ba Fix max_decode_depth to control decoder hierarchy and port generation (#18)
* Initial plan

* Fix max_decode_depth to properly control decoder hierarchy and port generation

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

* Fix test that relied on old depth behavior

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

* Update documentation for max_decode_depth parameter

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

* fix format

* Add variable_depth RDL file and smoke tests for max_decode_depth parameter

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

* Add variable depth tests for APB3 and AXI4-Lite CPUIFs

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

* fix

* fix

* bump

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>
2025-10-28 23:38:54 -07:00

62 lines
1.8 KiB
Python

from collections import deque
from typing import TYPE_CHECKING
from systemrdl.node import AddressableNode
from systemrdl.walker import WalkerAction
from ..body import Body, ForLoopBody
from ..design_state import DesignState
from ..listener import BusDecoderListener
if TYPE_CHECKING:
from .base_cpuif import BaseCpuif
class FanoutGenerator(BusDecoderListener):
def __init__(self, ds: DesignState, cpuif: "BaseCpuif") -> None:
super().__init__(ds)
self._cpuif = cpuif
self._stack: deque[Body] = deque()
self._stack.append(Body())
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
action = super().enter_AddressableComponent(node)
should_generate = action == WalkerAction.SkipDescendants
if not should_generate and self._ds.max_decode_depth == 0:
for child in node.children():
if isinstance(child, AddressableNode):
break
else:
should_generate = True
if not should_generate:
return action
if node.array_dimensions:
for i, dim in enumerate(node.array_dimensions):
fb = ForLoopBody(
"genvar",
f"gi{i}",
dim,
)
self._stack.append(fb)
self._stack[-1] += self._cpuif.fanout(node)
return action
def exit_AddressableComponent(self, node: AddressableNode) -> None:
if node.array_dimensions:
for _ in node.array_dimensions:
b = self._stack.pop()
if not b:
continue
self._stack[-1] += b
super().exit_AddressableComponent(node)
def __str__(self) -> str:
return "\n".join(map(str, self._stack))