@@ -1,6 +1,6 @@
|
||||
from typing import TYPE_CHECKING, Union, Set, Dict, Optional, TextIO, Type, List
|
||||
|
||||
from systemrdl.node import AddrmapNode, SignalNode, FieldNode, RegNode
|
||||
from systemrdl.node import AddrmapNode, SignalNode, FieldNode, RegNode, AddressableNode
|
||||
from systemrdl.rdltypes import PropertyReference, UserEnum
|
||||
|
||||
from ..utils import get_indexed_path
|
||||
@@ -25,7 +25,8 @@ class Hwif:
|
||||
self, exp: 'RegblockExporter', package_name: str,
|
||||
user_enums: List[Type[UserEnum]],
|
||||
in_hier_signal_paths: Set[str], out_of_hier_signals: Dict[str, SignalNode],
|
||||
reuse_typedefs: bool, hwif_report_file: Optional[TextIO]
|
||||
reuse_typedefs: bool, hwif_report_file: Optional[TextIO],
|
||||
data_width: int
|
||||
):
|
||||
self.exp = exp
|
||||
self.package_name = package_name
|
||||
@@ -39,6 +40,8 @@ class Hwif:
|
||||
|
||||
self.hwif_report_file = hwif_report_file
|
||||
|
||||
self.data_width = data_width
|
||||
|
||||
if reuse_typedefs:
|
||||
self._gen_in_cls = InputStructGenerator_TypeScope
|
||||
self._gen_out_cls = OutputStructGenerator_TypeScope
|
||||
@@ -162,6 +165,26 @@ class Hwif:
|
||||
|
||||
raise RuntimeError(f"Unhandled reference to: {obj}")
|
||||
|
||||
def get_external_rd_data(self, node: AddressableNode) -> str:
|
||||
"""
|
||||
Returns the identifier string for an external component's rd_data signal
|
||||
"""
|
||||
path = get_indexed_path(self.top_node, node)
|
||||
return "hwif_in." + path + ".rd_data"
|
||||
|
||||
def get_external_rd_ack(self, node: AddressableNode) -> str:
|
||||
"""
|
||||
Returns the identifier string for an external component's rd_ack signal
|
||||
"""
|
||||
path = get_indexed_path(self.top_node, node)
|
||||
return "hwif_in." + path + ".rd_ack"
|
||||
|
||||
def get_external_wr_ack(self, node: AddressableNode) -> str:
|
||||
"""
|
||||
Returns the identifier string for an external component's wr_ack signal
|
||||
"""
|
||||
path = get_indexed_path(self.top_node, node)
|
||||
return "hwif_in." + path + ".wr_ack"
|
||||
|
||||
def get_implied_prop_input_identifier(self, field: FieldNode, prop: str) -> str:
|
||||
assert prop in {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from typing import TYPE_CHECKING, Optional, List, Type
|
||||
|
||||
from systemrdl.node import FieldNode
|
||||
from systemrdl.node import FieldNode, RegNode, AddrmapNode, MemNode
|
||||
from systemrdl.walker import WalkerAction
|
||||
|
||||
from ..struct_generator import RDLFlatStructGenerator
|
||||
from ..identifier_filter import kw_filter as kwf
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from systemrdl.node import Node, SignalNode, RegNode
|
||||
from systemrdl.node import Node, SignalNode, AddressableNode, RegfileNode
|
||||
from . import Hwif
|
||||
from systemrdl.rdltypes import UserEnum
|
||||
|
||||
@@ -65,6 +66,43 @@ class InputStructGenerator_Hier(HWIFStructGenerator):
|
||||
if path in self.hwif.in_hier_signal_paths:
|
||||
self.add_member(kwf(node.inst_name), node.width)
|
||||
|
||||
def _add_external_block_members(self, node: 'AddressableNode') -> None:
|
||||
self.add_member("rd_ack")
|
||||
self.add_member("rd_data", self.hwif.data_width)
|
||||
self.add_member("wr_ack")
|
||||
|
||||
def enter_Addrmap(self, node: 'AddrmapNode') -> None:
|
||||
super().enter_Addrmap(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Regfile(self, node: 'RegfileNode') -> None:
|
||||
super().enter_Regfile(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]:
|
||||
super().enter_Mem(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]:
|
||||
super().enter_Reg(node)
|
||||
if node.external:
|
||||
width = min(self.hwif.data_width, node.get_property('regwidth'))
|
||||
self.add_member("rd_ack")
|
||||
self.add_member("rd_data", width)
|
||||
self.add_member("wr_ack")
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Field(self, node: 'FieldNode') -> None:
|
||||
type_name = self.get_typdef_name(node)
|
||||
self.push_struct(type_name, kwf(node.inst_name))
|
||||
@@ -120,6 +158,47 @@ class OutputStructGenerator_Hier(HWIFStructGenerator):
|
||||
)
|
||||
return f'{base}__out_t'
|
||||
|
||||
def _add_external_block_members(self, node: 'AddressableNode') -> None:
|
||||
self.add_member("req")
|
||||
self.add_member("addr", (node.size - 1).bit_length())
|
||||
self.add_member("req_is_wr")
|
||||
self.add_member("wr_data", self.hwif.data_width)
|
||||
self.add_member("wr_biten", self.hwif.data_width)
|
||||
|
||||
def enter_Addrmap(self, node: 'AddrmapNode') -> None:
|
||||
super().enter_Addrmap(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Regfile(self, node: 'RegfileNode') -> None:
|
||||
super().enter_Regfile(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]:
|
||||
super().enter_Mem(node)
|
||||
if node.external:
|
||||
self._add_external_block_members(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]:
|
||||
super().enter_Reg(node)
|
||||
if node.external:
|
||||
width = min(self.hwif.data_width, node.get_property('regwidth'))
|
||||
n_subwords = node.get_property("regwidth") // node.get_property("accesswidth")
|
||||
self.add_member("req", n_subwords)
|
||||
self.add_member("req_is_wr")
|
||||
self.add_member("wr_data", width)
|
||||
self.add_member("wr_biten", width)
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Field(self, node: 'FieldNode') -> None:
|
||||
type_name = self.get_typdef_name(node)
|
||||
self.push_struct(type_name, kwf(node.inst_name))
|
||||
@@ -162,6 +241,10 @@ class InputStructGenerator_TypeScope(InputStructGenerator_Hier):
|
||||
else:
|
||||
extra_suffix = ""
|
||||
|
||||
if node.external:
|
||||
# Node generates alternate external signals
|
||||
extra_suffix += "__external"
|
||||
|
||||
return f'{scope_path}__{node.type_name}{extra_suffix}__in_t'
|
||||
|
||||
class OutputStructGenerator_TypeScope(OutputStructGenerator_Hier):
|
||||
@@ -177,6 +260,10 @@ class OutputStructGenerator_TypeScope(OutputStructGenerator_Hier):
|
||||
else:
|
||||
extra_suffix = ""
|
||||
|
||||
if node.external:
|
||||
# Node generates alternate external signals
|
||||
extra_suffix += "__external"
|
||||
|
||||
return f'{scope_path}__{node.type_name}{extra_suffix}__out_t'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user