From ada050bf2ddf5a8f2007702d1d1c8f2c9df28796 Mon Sep 17 00:00:00 2001 From: Alex Mykyta Date: Mon, 7 Nov 2022 23:20:58 -0800 Subject: [PATCH] Add ability to generate a HWIF report. #13 --- src/peakrdl_regblock/__peakrdl__.py | 7 ++++ src/peakrdl_regblock/exporter.py | 14 ++++++++ src/peakrdl_regblock/hwif/__init__.py | 4 ++- src/peakrdl_regblock/hwif/generators.py | 46 +++++++++++++++++++++---- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/peakrdl_regblock/__peakrdl__.py b/src/peakrdl_regblock/__peakrdl__.py index 8a7d308..d75789f 100644 --- a/src/peakrdl_regblock/__peakrdl__.py +++ b/src/peakrdl_regblock/__peakrdl__.py @@ -71,6 +71,12 @@ class Exporter: 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: @@ -84,4 +90,5 @@ class Exporter: reuse_hwif_typedefs=(options.type_style == "lexical"), retime_read_fanin=options.rt_read_fanin, retime_read_response=options.rt_read_response, + generate_hwif_report=options.hwif_report, ) diff --git a/src/peakrdl_regblock/exporter.py b/src/peakrdl_regblock/exporter.py index c03e137..195503e 100644 --- a/src/peakrdl_regblock/exporter.py +++ b/src/peakrdl_regblock/exporter.py @@ -97,6 +97,9 @@ class RegblockExporter: response path sequentially may not result in any meaningful timing improvement. 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 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 package_name = kwargs.pop("package_name", None) or (module_name + "_pkg") # type: str reuse_hwif_typedefs = kwargs.pop("reuse_hwif_typedefs", True) # type: bool + generate_hwif_report = kwargs.pop("generate_hwif_report", False) # type: bool # Pipelining options retime_read_fanin = kwargs.pop("retime_read_fanin", False) # type: bool @@ -129,6 +133,12 @@ class RegblockExporter: scanner = DesignScanner(self) 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 self.cpuif = cpuif_cls( self, @@ -142,6 +152,7 @@ class RegblockExporter: in_hier_signal_paths=scanner.in_hier_signal_paths, out_of_hier_signals=scanner.out_of_hier_signals, reuse_typedefs=reuse_hwif_typedefs, + hwif_report_file=hwif_report_file, ) self.readback = Readback( self, @@ -184,3 +195,6 @@ class RegblockExporter: template = self.jj_env.get_template("module_tmpl.sv") stream = template.stream(context) stream.dump(module_file_path) + + if hwif_report_file: + hwif_report_file.close() diff --git a/src/peakrdl_regblock/hwif/__init__.py b/src/peakrdl_regblock/hwif/__init__.py index f9fdc37..809644e 100644 --- a/src/peakrdl_regblock/hwif/__init__.py +++ b/src/peakrdl_regblock/hwif/__init__.py @@ -23,7 +23,7 @@ class Hwif: def __init__( self, exp: 'RegblockExporter', package_name: str, 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.package_name = package_name @@ -34,6 +34,8 @@ class Hwif: self.in_hier_signal_paths = in_hier_signal_paths self.out_of_hier_signals = out_of_hier_signals + self.hwif_report_file = hwif_report_file + if reuse_typedefs: self._gen_in_cls = InputStructGenerator_TypeScope self._gen_out_cls = OutputStructGenerator_TypeScope diff --git a/src/peakrdl_regblock/hwif/generators.py b/src/peakrdl_regblock/hwif/generators.py index f1f2689..a3c05f8 100644 --- a/src/peakrdl_regblock/hwif/generators.py +++ b/src/peakrdl_regblock/hwif/generators.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional, List from systemrdl.node import FieldNode @@ -9,12 +9,46 @@ if TYPE_CHECKING: from systemrdl.node import Node, SignalNode, RegNode from . import Hwif -class InputStructGenerator_Hier(RDLFlatStructGenerator): - def __init__(self, hwif: 'Hwif') -> None: +class HWIFStructGenerator(RDLFlatStructGenerator): + def __init__(self, hwif: 'Hwif', hwif_name: str) -> None: super().__init__() self.hwif = hwif 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: base = node.get_rel_path( self.top_node.parent, @@ -72,11 +106,9 @@ class InputStructGenerator_Hier(RDLFlatStructGenerator): self.pop_struct() -class OutputStructGenerator_Hier(RDLFlatStructGenerator): +class OutputStructGenerator_Hier(HWIFStructGenerator): def __init__(self, hwif: 'Hwif') -> None: - super().__init__() - self.hwif = hwif - self.top_node = hwif.top_node + super().__init__(hwif, "hwif_out") def get_typdef_name(self, node:'Node') -> str: base = node.get_rel_path(