Add ability to generate a HWIF report. #13
This commit is contained in:
@@ -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,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user