apb4 if working?
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import overload
|
||||||
|
|
||||||
from systemrdl.node import AddressableNode
|
from systemrdl.node import AddressableNode
|
||||||
|
|
||||||
from ...utils import get_indexed_path
|
from ...utils import get_indexed_path
|
||||||
@@ -10,11 +12,11 @@ class APB4Cpuif(BaseCpuif):
|
|||||||
|
|
||||||
def _port_declaration(self, child: AddressableNode) -> str:
|
def _port_declaration(self, child: AddressableNode) -> str:
|
||||||
base = f"apb4_intf.master m_apb_{child.inst_name}"
|
base = f"apb4_intf.master m_apb_{child.inst_name}"
|
||||||
if not child.is_array:
|
if child.array_dimensions is None:
|
||||||
return base
|
return base
|
||||||
if child.current_idx is not None:
|
if child.current_idx is not None:
|
||||||
return f"{base}_{'_'.join(map(str, child.current_idx))} [N_{child.inst_name.upper()}S]"
|
return f"{base}_{'_'.join(map(str, child.current_idx))} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
||||||
return f"{base} [N_{child.inst_name.upper()}S]"
|
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port_declaration(self) -> str:
|
def port_declaration(self) -> str:
|
||||||
@@ -24,38 +26,50 @@ class APB4Cpuif(BaseCpuif):
|
|||||||
|
|
||||||
return ",\n".join(slave_ports + master_ports)
|
return ",\n".join(slave_ports + master_ports)
|
||||||
|
|
||||||
def signal(
|
@overload
|
||||||
self,
|
def signal(self, signal: str, node: None = None, indexer: None = None) -> str: ...
|
||||||
signal: str,
|
@overload
|
||||||
node: AddressableNode | None = None,
|
def signal(self, signal: str, node: AddressableNode, indexer: str) -> str: ...
|
||||||
) -> str:
|
def signal(self, signal: str, node: AddressableNode | None = None, indexer: str | None = None) -> str:
|
||||||
if node is None:
|
if node is None or indexer is None:
|
||||||
# Node is none, so this is a slave signal
|
# Node is none, so this is a slave signal
|
||||||
return f"s_apb.{signal}"
|
return f"s_apb.{signal}"
|
||||||
|
|
||||||
# Master signal
|
# Master signal
|
||||||
return f"m_apb_{node.inst_name}.{signal}"
|
return f"m_apb_{get_indexed_path(node.parent, node, indexer, skip_kw_filter=True)}.{signal}"
|
||||||
|
|
||||||
def fanout(self, node: AddressableNode) -> str:
|
def fanout(self, node: AddressableNode) -> str:
|
||||||
fanout: dict[str, str] = {}
|
fanout: dict[str, str] = {}
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PSEL"] = (
|
fanout[self.signal("PSEL", node, "gi")] = (
|
||||||
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node)}|cpuif_rd_sel.{get_indexed_path(self.exp.ds.top_node, node)}"
|
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[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PSEL"] = self.signal("PSEL")
|
fanout[self.signal("PENABLE", node, "gi")] = self.signal("PENABLE")
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PWRITE"] = (
|
fanout[self.signal("PWRITE", node, "gi")] = (
|
||||||
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
f"cpuif_wr_sel.{get_indexed_path(self.exp.ds.top_node, node, 'gi')}"
|
||||||
)
|
)
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PADDR"] = self.signal("PADDR")
|
fanout[self.signal("PADDR", node, "gi")] = self.signal("PADDR")
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PPROT"] = self.signal("PPROT")
|
fanout[self.signal("PPROT", node, "gi")] = self.signal("PPROT")
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PWDATA"] = "cpuif_wr_data"
|
fanout[self.signal("PWDATA", node, "gi")] = "cpuif_wr_data"
|
||||||
fanout[f"m_apb_{get_indexed_path(node.parent, node, 'gi')}.PSTRB"] = "cpuif_wr_byte_en"
|
fanout[self.signal("PSTRB", node, "gi")] = "cpuif_wr_byte_en"
|
||||||
|
|
||||||
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
|
return "\n".join(map(lambda kv: f"assign {kv[0]} = {kv[1]};", fanout.items()))
|
||||||
|
|
||||||
def fanin(self, node: AddressableNode) -> str:
|
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||||
fanin: dict[str, str] = {}
|
fanin: dict[str, str] = {}
|
||||||
fanin["cpuif_rd_data"] = self.signal("PRDATA", node)
|
if node is None:
|
||||||
fanin["cpuif_rd_ack"] = self.signal("PREADY", node)
|
fanin["cpuif_rd_ack"] = "'0"
|
||||||
fanin["cpuif_rd_err"] = self.signal("PSLVERR", node)
|
fanin["cpuif_rd_err"] = "'0"
|
||||||
|
else:
|
||||||
|
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()))
|
||||||
|
|
||||||
|
def readback(self, node: AddressableNode | None = None) -> str:
|
||||||
|
fanin: dict[str, str] = {}
|
||||||
|
if node is None:
|
||||||
|
fanin["cpuif_rd_data"] = "'0"
|
||||||
|
else:
|
||||||
|
fanin["cpuif_rd_data"] = self.signal("PRDATA", node, "i")
|
||||||
|
|
||||||
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
return "\n".join(map(lambda kv: f"{kv[0]} = {kv[1]};", fanin.items()))
|
||||||
|
|||||||
@@ -6,19 +6,24 @@
|
|||||||
assert_bad_data_width: assert($bits({{cpuif.signal("PWDATA")}}) == {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH)
|
assert_bad_data_width: assert($bits({{cpuif.signal("PWDATA")}}) == {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH)
|
||||||
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits({{cpuif.signal("PWDATA")}}), {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH);
|
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits({{cpuif.signal("PWDATA")}}), {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH);
|
||||||
end
|
end
|
||||||
|
assert_wr_sel: assert (@(posedge {{cpuif.signal("PCLK")}}) {{cpuif.signal("PSEL")}} && {{cpuif.signal("PWRITE")}} |-> ##1 ({{cpuif.signal("PREADY")}} || {{cpuif.signal("PSLVERR")}}))
|
||||||
|
else $error("APB4 Slave port SEL implies that cpuif_wr_sel must be one-hot encoded");
|
||||||
`endif
|
`endif
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
assign cpuif_req = {{cpuif.signal("PSELx")}};
|
assign cpuif_req = {{cpuif.signal("PSEL")}};
|
||||||
assign cpuif_wr_en = {{cpuif.signal("PWRITE")}};
|
assign cpuif_wr_en = {{cpuif.signal("PWRITE")}};
|
||||||
assign cpuif_rd_en = !{{cpuif.signal("PWRITE")}};
|
assign cpuif_rd_en = !{{cpuif.signal("PWRITE")}};
|
||||||
|
|
||||||
|
assign cpuif_wr_addr = {{cpuif.signal("PADDR")}};
|
||||||
|
assign cpuif_rd_addr = {{cpuif.signal("PADDR")}};
|
||||||
|
|
||||||
assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
|
assign cpuif_wr_data = {{cpuif.signal("PWDATA")}};
|
||||||
assign cpuif_wr_byte_en = {{cpuif.signal("PSTRB")}};
|
assign cpuif_wr_byte_en = {{cpuif.signal("PSTRB")}};
|
||||||
|
|
||||||
assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
|
assign {{cpuif.signal("PRDATA")}} = cpuif_rd_data;
|
||||||
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
|
assign {{cpuif.signal("PREADY")}} = cpuif_rd_ack;
|
||||||
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err;
|
assign {{cpuif.signal("PSLVERR")}} = cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Fanout CPU Bus interface signals
|
// Fanout CPU Bus interface signals
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import jinja2 as jj
|
import jinja2 as jj
|
||||||
from systemrdl.node import AddressableNode
|
from systemrdl.node import AddressableNode
|
||||||
from systemrdl.walker import RDLSteerableWalker
|
|
||||||
|
|
||||||
from ..listener import BusDecoderListener
|
|
||||||
from ..utils import clog2, get_indexed_path, is_pow2, roundup_pow2
|
from ..utils import clog2, get_indexed_path, is_pow2, roundup_pow2
|
||||||
from .fanin_gen import FaninGenerator
|
from .fanin_gen import FaninGenerator
|
||||||
from .fanout_gen import FanoutGenerator
|
from .fanout_gen import FanoutGenerator
|
||||||
@@ -55,7 +53,7 @@ class BaseCpuif:
|
|||||||
the module's definition
|
the module's definition
|
||||||
"""
|
"""
|
||||||
array_parameters = [
|
array_parameters = [
|
||||||
f"parameter N_{child.inst_name.upper()}S = {child.n_elements}"
|
f"localparam N_{child.inst_name.upper()}S = {child.n_elements}"
|
||||||
for child in self.addressable_children
|
for child in self.addressable_children
|
||||||
if self.check_is_array(child)
|
if self.check_is_array(child)
|
||||||
]
|
]
|
||||||
@@ -88,7 +86,7 @@ class BaseCpuif:
|
|||||||
jj_env.filters["roundup_pow2"] = roundup_pow2 # type: ignore
|
jj_env.filters["roundup_pow2"] = roundup_pow2 # type: ignore
|
||||||
jj_env.filters["address_slice"] = self.get_address_slice # type: ignore
|
jj_env.filters["address_slice"] = self.get_address_slice # type: ignore
|
||||||
jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i") # type: ignore
|
jj_env.filters["get_path"] = lambda x: get_indexed_path(self.exp.ds.top_node, x, "i") # type: ignore
|
||||||
jj_env.filters["walk"] = self.walk # type: ignore
|
jj_env.filters["walk"] = self.exp.walk # type: ignore
|
||||||
|
|
||||||
context = { # type: ignore
|
context = { # type: ignore
|
||||||
"cpuif": self,
|
"cpuif": self,
|
||||||
@@ -106,14 +104,11 @@ class BaseCpuif:
|
|||||||
|
|
||||||
return f"({cpuif_addr} - 'h{addr:x})[{clog2(size) - 1}:0]"
|
return f"({cpuif_addr} - 'h{addr:x})[{clog2(size) - 1}:0]"
|
||||||
|
|
||||||
def walk(self, listener_cls: type[BusDecoderListener], **kwargs: Any) -> str: # noqa: ANN401
|
|
||||||
walker = RDLSteerableWalker()
|
|
||||||
listener = listener_cls(self.exp.ds, **kwargs)
|
|
||||||
walker.walk(self.exp.ds.top_node, listener, skip_top=True)
|
|
||||||
return str(listener)
|
|
||||||
|
|
||||||
def fanout(self, node: AddressableNode) -> str:
|
def fanout(self, node: AddressableNode) -> str:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def fanin(self, node: AddressableNode) -> str:
|
def fanin(self, node: AddressableNode | None = None) -> str:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def readback(self, node: AddressableNode | None = None) -> str:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ from typing import TYPE_CHECKING
|
|||||||
from systemrdl.node import AddressableNode
|
from systemrdl.node import AddressableNode
|
||||||
from systemrdl.walker import WalkerAction
|
from systemrdl.walker import WalkerAction
|
||||||
|
|
||||||
from ..body import Body, CombinationalBody, ForLoopBody
|
from ..body import Body, CombinationalBody, ForLoopBody, IfBody
|
||||||
from ..design_state import DesignState
|
from ..design_state import DesignState
|
||||||
from ..listener import BusDecoderListener
|
from ..listener import BusDecoderListener
|
||||||
|
from ..utils import get_indexed_path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .base_cpuif import BaseCpuif
|
from .base_cpuif import BaseCpuif
|
||||||
@@ -18,7 +19,10 @@ class FaninGenerator(BusDecoderListener):
|
|||||||
self._cpuif = cpuif
|
self._cpuif = cpuif
|
||||||
|
|
||||||
self._stack: deque[Body] = deque()
|
self._stack: deque[Body] = deque()
|
||||||
self._stack.append(CombinationalBody())
|
cb = CombinationalBody()
|
||||||
|
cb += cpuif.fanin()
|
||||||
|
cb += cpuif.readback()
|
||||||
|
self._stack.append(cb)
|
||||||
|
|
||||||
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
||||||
action = super().enter_AddressableComponent(node)
|
action = super().enter_AddressableComponent(node)
|
||||||
@@ -32,7 +36,19 @@ class FaninGenerator(BusDecoderListener):
|
|||||||
)
|
)
|
||||||
self._stack.append(fb)
|
self._stack.append(fb)
|
||||||
|
|
||||||
self._stack[-1] += self._cpuif.fanin(node)
|
if action == WalkerAction.Continue:
|
||||||
|
ifb = IfBody()
|
||||||
|
with ifb.cm(
|
||||||
|
f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)} || cpuif_wr_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}"
|
||||||
|
) as b:
|
||||||
|
b += self._cpuif.fanin(node)
|
||||||
|
self._stack[-1] += ifb
|
||||||
|
|
||||||
|
ifb = IfBody()
|
||||||
|
with ifb.cm(f"cpuif_rd_sel.{get_indexed_path(self._cpuif.exp.ds.top_node, node)}") as b:
|
||||||
|
b += self._cpuif.readback(node)
|
||||||
|
self._stack[-1] += ifb
|
||||||
|
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ class FanoutGenerator(BusDecoderListener):
|
|||||||
)
|
)
|
||||||
self._stack.append(fb)
|
self._stack.append(fb)
|
||||||
|
|
||||||
|
if action == WalkerAction.Continue:
|
||||||
self._stack[-1] += self._cpuif.fanout(node)
|
self._stack[-1] += self._cpuif.fanout(node)
|
||||||
|
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
||||||
|
|||||||
@@ -39,17 +39,20 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|||||||
# Initial Stack Conditions
|
# Initial Stack Conditions
|
||||||
self._decode_stack.append(IfBody())
|
self._decode_stack.append(IfBody())
|
||||||
|
|
||||||
def cpuif_addr_predicate(self, node: AddressableNode) -> list[str]:
|
def cpuif_addr_predicate(self, node: AddressableNode, total_size: bool = True) -> list[str]:
|
||||||
# Generate address bounds
|
# Generate address bounds
|
||||||
addr_width = self._ds.addr_width
|
addr_width = self._ds.addr_width
|
||||||
l_bound = SVInt(
|
l_bound = SVInt(
|
||||||
node.raw_absolute_address,
|
node.raw_absolute_address,
|
||||||
addr_width,
|
addr_width,
|
||||||
)
|
)
|
||||||
|
if total_size:
|
||||||
u_bound = l_bound + SVInt(node.total_size, addr_width)
|
u_bound = l_bound + SVInt(node.total_size, addr_width)
|
||||||
|
else:
|
||||||
|
u_bound = l_bound + SVInt(node.size, addr_width)
|
||||||
|
|
||||||
array_stack = list(self._array_stride_stack)
|
array_stack = list(self._array_stride_stack)
|
||||||
if node.array_dimensions:
|
if total_size and node.array_dimensions:
|
||||||
array_stack = array_stack[: -len(node.array_dimensions)]
|
array_stack = array_stack[: -len(node.array_dimensions)]
|
||||||
|
|
||||||
# Handle arrayed components
|
# Handle arrayed components
|
||||||
@@ -79,7 +82,6 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|||||||
conditions: list[str] = []
|
conditions: list[str] = []
|
||||||
conditions.extend(self.cpuif_addr_predicate(node))
|
conditions.extend(self.cpuif_addr_predicate(node))
|
||||||
conditions.extend(self.cpuif_prot_predicate(node))
|
conditions.extend(self.cpuif_prot_predicate(node))
|
||||||
|
|
||||||
condition = " && ".join(f"({c})" for c in conditions)
|
condition = " && ".join(f"({c})" for c in conditions)
|
||||||
|
|
||||||
# Generate condition string and manage stack
|
# Generate condition string and manage stack
|
||||||
@@ -111,12 +113,14 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|||||||
return
|
return
|
||||||
|
|
||||||
ifb = self._decode_stack.pop()
|
ifb = self._decode_stack.pop()
|
||||||
if ifb:
|
if not ifb and isinstance(ifb, IfBody):
|
||||||
|
conditions: list[str] = []
|
||||||
|
conditions.extend(self.cpuif_addr_predicate(node, total_size=False))
|
||||||
|
condition = " && ".join(f"({c})" for c in conditions)
|
||||||
|
|
||||||
|
with ifb.cm(condition) as b:
|
||||||
|
b += f"{self._flavor.cpuif_select}.{get_indexed_path(self._ds.top_node, node)} = 1'b1;"
|
||||||
self._decode_stack[-1] += ifb
|
self._decode_stack[-1] += ifb
|
||||||
else:
|
|
||||||
self._decode_stack[-1] += (
|
|
||||||
f"{self._flavor.cpuif_select}.{get_indexed_path(self._ds.top_node, node)} = 1'b1;"
|
|
||||||
)
|
|
||||||
|
|
||||||
for _ in node.array_dimensions:
|
for _ in node.array_dimensions:
|
||||||
b = self._decode_stack.pop()
|
b = self._decode_stack.pop()
|
||||||
@@ -135,6 +139,6 @@ class DecodeLogicGenerator(BusDecoderListener):
|
|||||||
body = self._decode_stack[-1]
|
body = self._decode_stack[-1]
|
||||||
if isinstance(body, IfBody):
|
if isinstance(body, IfBody):
|
||||||
with body.cm(...) as b:
|
with body.cm(...) as b:
|
||||||
b += f"{self._flavor.cpuif_select}.bad_addr = 1'b1;"
|
b += f"{self._flavor.cpuif_select}.cpuif_err = 1'b1;"
|
||||||
|
|
||||||
return str(body)
|
return str(body)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
from systemrdl.node import AddressableNode, RegNode
|
from systemrdl.node import AddressableNode
|
||||||
from systemrdl.walker import RDLListener, WalkerAction
|
from systemrdl.walker import RDLListener, WalkerAction
|
||||||
|
|
||||||
from .design_state import DesignState
|
from .design_state import DesignState
|
||||||
@@ -10,13 +10,16 @@ class BusDecoderListener(RDLListener):
|
|||||||
def __init__(self, ds: DesignState) -> None:
|
def __init__(self, ds: DesignState) -> None:
|
||||||
self._array_stride_stack: deque[int] = deque() # Tracks nested array strides
|
self._array_stride_stack: deque[int] = deque() # Tracks nested array strides
|
||||||
self._ds = ds
|
self._ds = ds
|
||||||
|
self._depth = 0
|
||||||
|
|
||||||
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
||||||
if node.array_dimensions:
|
if node.array_dimensions:
|
||||||
assert node.array_stride is not None, "Array stride should be defined for arrayed components"
|
assert node.array_stride is not None, "Array stride should be defined for arrayed components"
|
||||||
self._array_stride_stack.extend(node.array_dimensions)
|
self._array_stride_stack.extend(node.array_dimensions)
|
||||||
|
|
||||||
if isinstance(node, RegNode):
|
self._depth += 1
|
||||||
|
|
||||||
|
if self._depth > 1:
|
||||||
return WalkerAction.SkipDescendants
|
return WalkerAction.SkipDescendants
|
||||||
return WalkerAction.Continue
|
return WalkerAction.Continue
|
||||||
|
|
||||||
@@ -25,5 +28,7 @@ class BusDecoderListener(RDLListener):
|
|||||||
for _ in node.array_dimensions:
|
for _ in node.array_dimensions:
|
||||||
self._array_stride_stack.pop()
|
self._array_stride_stack.pop()
|
||||||
|
|
||||||
|
self._depth -= 1
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ class StructGenerator(BusDecoderListener):
|
|||||||
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
def enter_AddressableComponent(self, node: AddressableNode) -> WalkerAction | None:
|
||||||
action = super().enter_AddressableComponent(node)
|
action = super().enter_AddressableComponent(node)
|
||||||
|
|
||||||
|
self._skip = False
|
||||||
|
if action == WalkerAction.SkipDescendants:
|
||||||
|
self._skip = True
|
||||||
|
|
||||||
if node.children():
|
if node.children():
|
||||||
# Push new body onto stack
|
# Push new body onto stack
|
||||||
body = StructBody(f"cpuif_sel_{node.inst_name}_t", True, True)
|
body = StructBody(f"cpuif_sel_{node.inst_name}_t", True, True)
|
||||||
@@ -34,7 +38,7 @@ class StructGenerator(BusDecoderListener):
|
|||||||
|
|
||||||
if node.children():
|
if node.children():
|
||||||
body = self._stack.pop()
|
body = self._stack.pop()
|
||||||
if body and isinstance(body, StructBody):
|
if body and isinstance(body, StructBody) and not self._skip:
|
||||||
self._stack.appendleft(body)
|
self._stack.appendleft(body)
|
||||||
type = body.name
|
type = body.name
|
||||||
|
|
||||||
@@ -42,11 +46,12 @@ class StructGenerator(BusDecoderListener):
|
|||||||
|
|
||||||
if node.array_dimensions:
|
if node.array_dimensions:
|
||||||
for dim in node.array_dimensions:
|
for dim in node.array_dimensions:
|
||||||
name += f"[{dim}]"
|
name = f"[{dim - 1}:0]{name}"
|
||||||
|
|
||||||
self._stack[-1] += f"{type} {name};"
|
self._stack[-1] += f"{type} {name};"
|
||||||
|
|
||||||
super().exit_AddressableComponent(node)
|
super().exit_AddressableComponent(node)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
|
self._stack[-1] += "logic cpuif_err;"
|
||||||
return "\n".join(map(str, self._stack))
|
return "\n".join(map(str, self._stack))
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ from systemrdl.rdltypes.references import PropertyReference
|
|||||||
from .identifier_filter import kw_filter as kwf
|
from .identifier_filter import kw_filter as kwf
|
||||||
|
|
||||||
|
|
||||||
def get_indexed_path(top_node: Node, target_node: Node, indexer: str = "i") -> str:
|
def get_indexed_path(
|
||||||
|
top_node: Node, target_node: Node, indexer: str = "i", skip_kw_filter: bool = False
|
||||||
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Get the relative path from top_node to target_node, replacing any unknown
|
Get the relative path from top_node to target_node, replacing any unknown
|
||||||
array indexes with incrementing iterators (i0, i1, ...).
|
array indexes with incrementing iterators (i0, i1, ...).
|
||||||
@@ -30,6 +32,7 @@ def get_indexed_path(top_node: Node, target_node: Node, indexer: str = "i") -> s
|
|||||||
def kw_filter_repl(m: Match[str]) -> str:
|
def kw_filter_repl(m: Match[str]) -> str:
|
||||||
return kwf(m.group(0))
|
return kwf(m.group(0))
|
||||||
|
|
||||||
|
if not skip_kw_filter:
|
||||||
path = re.sub(r"\w+", kw_filter_repl, path)
|
path = re.sub(r"\w+", kw_filter_repl, path)
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|||||||
Reference in New Issue
Block a user