Add ability to generate a HWIF report. #13

This commit is contained in:
Alex Mykyta
2022-11-07 23:20:58 -08:00
parent 32f102263b
commit ada050bf2d
4 changed files with 63 additions and 8 deletions

View File

@@ -71,6 +71,12 @@ class Exporter:
The 'hier' style uses component's hierarchy as the struct type name. [lexical] The 'hier' style uses component's hierarchy as the struct type name. [lexical]
""" """
) )
arg_group.add_argument(
"--hwif-report",
action="store_true",
default=False,
help="Generate a HWIF report file"
)
def do_export(self, top_node: 'AddrmapNode', options: 'argparse.Namespace') -> None: def do_export(self, top_node: 'AddrmapNode', options: 'argparse.Namespace') -> None:
@@ -84,4 +90,5 @@ class Exporter:
reuse_hwif_typedefs=(options.type_style == "lexical"), reuse_hwif_typedefs=(options.type_style == "lexical"),
retime_read_fanin=options.rt_read_fanin, retime_read_fanin=options.rt_read_fanin,
retime_read_response=options.rt_read_response, retime_read_response=options.rt_read_response,
generate_hwif_report=options.hwif_report,
) )

View File

@@ -97,6 +97,9 @@ class RegblockExporter:
response path sequentially may not result in any meaningful timing improvement. response path sequentially may not result in any meaningful timing improvement.
Enabling this option will increase read transfer latency by 1 clock cycle. Enabling this option will increase read transfer latency by 1 clock cycle.
generate_hwif_report: bool
If set, generates a hwif report that can help understand the structure
of the hwif_in and hwif_out structures.
""" """
# If it is the root node, skip to top addrmap # If it is the root node, skip to top addrmap
if isinstance(node, RootNode): if isinstance(node, RootNode):
@@ -109,6 +112,7 @@ class RegblockExporter:
module_name = kwargs.pop("module_name", None) or kwf(self.top_node.inst_name) # type: str module_name = kwargs.pop("module_name", None) or kwf(self.top_node.inst_name) # type: str
package_name = kwargs.pop("package_name", None) or (module_name + "_pkg") # type: str package_name = kwargs.pop("package_name", None) or (module_name + "_pkg") # type: str
reuse_hwif_typedefs = kwargs.pop("reuse_hwif_typedefs", True) # type: bool reuse_hwif_typedefs = kwargs.pop("reuse_hwif_typedefs", True) # type: bool
generate_hwif_report = kwargs.pop("generate_hwif_report", False) # type: bool
# Pipelining options # Pipelining options
retime_read_fanin = kwargs.pop("retime_read_fanin", False) # type: bool retime_read_fanin = kwargs.pop("retime_read_fanin", False) # type: bool
@@ -129,6 +133,12 @@ class RegblockExporter:
scanner = DesignScanner(self) scanner = DesignScanner(self)
scanner.do_scan() scanner.do_scan()
if generate_hwif_report:
path = os.path.join(output_dir, f"{module_name}_hwif.rpt")
hwif_report_file = open(path, "w")
else:
hwif_report_file = None
# Construct exporter components # Construct exporter components
self.cpuif = cpuif_cls( self.cpuif = cpuif_cls(
self, self,
@@ -142,6 +152,7 @@ class RegblockExporter:
in_hier_signal_paths=scanner.in_hier_signal_paths, in_hier_signal_paths=scanner.in_hier_signal_paths,
out_of_hier_signals=scanner.out_of_hier_signals, out_of_hier_signals=scanner.out_of_hier_signals,
reuse_typedefs=reuse_hwif_typedefs, reuse_typedefs=reuse_hwif_typedefs,
hwif_report_file=hwif_report_file,
) )
self.readback = Readback( self.readback = Readback(
self, self,
@@ -184,3 +195,6 @@ class RegblockExporter:
template = self.jj_env.get_template("module_tmpl.sv") template = self.jj_env.get_template("module_tmpl.sv")
stream = template.stream(context) stream = template.stream(context)
stream.dump(module_file_path) stream.dump(module_file_path)
if hwif_report_file:
hwif_report_file.close()

View File

@@ -23,7 +23,7 @@ class Hwif:
def __init__( def __init__(
self, exp: 'RegblockExporter', package_name: str, self, exp: 'RegblockExporter', package_name: str,
in_hier_signal_paths: Set[str], out_of_hier_signals: Dict[str, SignalNode], in_hier_signal_paths: Set[str], out_of_hier_signals: Dict[str, SignalNode],
reuse_typedefs: bool reuse_typedefs: bool, hwif_report_file: int
): ):
self.exp = exp self.exp = exp
self.package_name = package_name self.package_name = package_name
@@ -34,6 +34,8 @@ class Hwif:
self.in_hier_signal_paths = in_hier_signal_paths self.in_hier_signal_paths = in_hier_signal_paths
self.out_of_hier_signals = out_of_hier_signals self.out_of_hier_signals = out_of_hier_signals
self.hwif_report_file = hwif_report_file
if reuse_typedefs: if reuse_typedefs:
self._gen_in_cls = InputStructGenerator_TypeScope self._gen_in_cls = InputStructGenerator_TypeScope
self._gen_out_cls = OutputStructGenerator_TypeScope self._gen_out_cls = OutputStructGenerator_TypeScope

View File

@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Optional, List
from systemrdl.node import FieldNode from systemrdl.node import FieldNode
@@ -9,12 +9,46 @@ if TYPE_CHECKING:
from systemrdl.node import Node, SignalNode, RegNode from systemrdl.node import Node, SignalNode, RegNode
from . import Hwif from . import Hwif
class InputStructGenerator_Hier(RDLFlatStructGenerator): class HWIFStructGenerator(RDLFlatStructGenerator):
def __init__(self, hwif: 'Hwif') -> None: def __init__(self, hwif: 'Hwif', hwif_name: str) -> None:
super().__init__() super().__init__()
self.hwif = hwif self.hwif = hwif
self.top_node = hwif.top_node self.top_node = hwif.top_node
self.hwif_report_stack = [hwif_name]
def push_struct(self, type_name: str, inst_name: str, array_dimensions: Optional[List[int]] = None) -> None:
super().push_struct(type_name, inst_name, array_dimensions)
if array_dimensions:
array_suffix = "".join([f"[0:{dim-1}]" for dim in array_dimensions])
segment = inst_name + array_suffix
else:
segment = inst_name
self.hwif_report_stack.append(segment)
def pop_struct(self) -> None:
super().pop_struct()
self.hwif_report_stack.pop()
def add_member(self, name: str, width: int = 1) -> None:
super().add_member(name, width)
if width > 1:
suffix = f"[{width-1}:0]"
else:
suffix = ""
path = ".".join(self.hwif_report_stack)
if self.hwif.hwif_report_file:
self.hwif.hwif_report_file.write(f"{path}.{name}{suffix}\n")
#-------------------------------------------------------------------------------
class InputStructGenerator_Hier(HWIFStructGenerator):
def __init__(self, hwif: 'Hwif') -> None:
super().__init__(hwif, "hwif_in")
def get_typdef_name(self, node:'Node') -> str: def get_typdef_name(self, node:'Node') -> str:
base = node.get_rel_path( base = node.get_rel_path(
self.top_node.parent, self.top_node.parent,
@@ -72,11 +106,9 @@ class InputStructGenerator_Hier(RDLFlatStructGenerator):
self.pop_struct() self.pop_struct()
class OutputStructGenerator_Hier(RDLFlatStructGenerator): class OutputStructGenerator_Hier(HWIFStructGenerator):
def __init__(self, hwif: 'Hwif') -> None: def __init__(self, hwif: 'Hwif') -> None:
super().__init__() super().__init__(hwif, "hwif_out")
self.hwif = hwif
self.top_node = hwif.top_node
def get_typdef_name(self, node:'Node') -> str: def get_typdef_name(self, node:'Node') -> str:
base = node.get_rel_path( base = node.get_rel_path(