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>
This commit is contained in:
@@ -3,7 +3,7 @@ from collections import deque
|
||||
from systemrdl.node import AddressableNode
|
||||
from systemrdl.walker import WalkerAction
|
||||
|
||||
from .body import Body, StructBody
|
||||
from .body import StructBody
|
||||
from .design_state import DesignState
|
||||
from .identifier_filter import kw_filter as kwf
|
||||
from .listener import BusDecoderListener
|
||||
@@ -16,30 +16,38 @@ class StructGenerator(BusDecoderListener):
|
||||
) -> None:
|
||||
super().__init__(ds)
|
||||
|
||||
self._stack: deque[Body] = deque()
|
||||
self._stack.append(StructBody("cpuif_sel_t", True, False))
|
||||
self._stack: list[StructBody] = [StructBody("cpuif_sel_t", True, False)]
|
||||
self._struct_defs: list[StructBody] = []
|
||||
self._created_struct_stack: deque[bool] = deque() # Track if we created a struct for each node
|
||||
|
||||
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
||||
action = super().enter_AddressableComponent(node)
|
||||
|
||||
self._skip = False
|
||||
if action == WalkerAction.SkipDescendants:
|
||||
self._skip = True
|
||||
skip = action == WalkerAction.SkipDescendants
|
||||
|
||||
if node.children():
|
||||
# Only create nested struct if we're not skipping and node has addressable children
|
||||
has_addressable_children = any(isinstance(child, AddressableNode) for child in node.children())
|
||||
if has_addressable_children and not skip:
|
||||
# Push new body onto stack
|
||||
body = StructBody(f"cpuif_sel_{node.inst_name}_t", True, False)
|
||||
self._stack.append(body)
|
||||
self._created_struct_stack.append(True)
|
||||
else:
|
||||
self._created_struct_stack.append(False)
|
||||
|
||||
return action
|
||||
|
||||
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
||||
type = "logic"
|
||||
|
||||
if node.children():
|
||||
# Pop the created_struct flag
|
||||
created_struct = self._created_struct_stack.pop()
|
||||
|
||||
# Only pop struct body if we created one
|
||||
if created_struct:
|
||||
body = self._stack.pop()
|
||||
if body and isinstance(body, StructBody) and not self._skip:
|
||||
self._stack.appendleft(body)
|
||||
if body:
|
||||
self._struct_defs.append(body)
|
||||
type = body.name
|
||||
|
||||
name = kwf(node.inst_name)
|
||||
@@ -53,5 +61,8 @@ class StructGenerator(BusDecoderListener):
|
||||
super().exit_AddressableComponent(node)
|
||||
|
||||
def __str__(self) -> str:
|
||||
self._stack[-1] += "logic cpuif_err;"
|
||||
return "\n".join(map(str, self._stack))
|
||||
if "logic cpuif_err;" not in self._stack[-1].lines:
|
||||
self._stack[-1] += "logic cpuif_err;"
|
||||
bodies = [str(body) for body in self._struct_defs]
|
||||
bodies.append(str(self._stack[-1]))
|
||||
return "\n".join(bodies)
|
||||
|
||||
Reference in New Issue
Block a user