diff --git a/src/peakrdl_regblock/__peakrdl__.py b/src/peakrdl_regblock/__peakrdl__.py index a9f7f26..c67bdb5 100644 --- a/src/peakrdl_regblock/__peakrdl__.py +++ b/src/peakrdl_regblock/__peakrdl__.py @@ -61,7 +61,7 @@ class Exporter(ExporterSubcommandPlugin): return cpuifs - def add_exporter_arguments(self, arg_group: 'argparse.ArgumentParser') -> None: + def add_exporter_arguments(self, arg_group: 'argparse._ActionsContainer') -> None: cpuifs = self.get_cpuifs() arg_group.add_argument( diff --git a/src/peakrdl_regblock/addr_decode.py b/src/peakrdl_regblock/addr_decode.py index df01bda..1390192 100644 --- a/src/peakrdl_regblock/addr_decode.py +++ b/src/peakrdl_regblock/addr_decode.py @@ -136,7 +136,8 @@ class DecodeLogicGenerator(RDLForLoopGenerator): def enter_AddressableComponent(self, node: 'AddressableNode') -> Optional[WalkerAction]: super().enter_AddressableComponent(node) - if node.is_array: + if node.array_dimensions: + assert node.array_stride is not None # Collect strides for each array dimension current_stride = node.array_stride strides = [] @@ -211,7 +212,7 @@ class DecodeLogicGenerator(RDLForLoopGenerator): def exit_AddressableComponent(self, node: 'AddressableNode') -> None: super().exit_AddressableComponent(node) - if not node.is_array: + if not node.array_dimensions: return for _ in node.array_dimensions: diff --git a/src/peakrdl_regblock/exporter.py b/src/peakrdl_regblock/exporter.py index 6c1ea06..b2c5f29 100644 --- a/src/peakrdl_regblock/exporter.py +++ b/src/peakrdl_regblock/exporter.py @@ -27,20 +27,21 @@ if TYPE_CHECKING: from systemrdl.rdltypes import UserEnum class RegblockExporter: + hwif: Hwif + cpuif: CpuifBase + address_decode: AddressDecode + field_logic: FieldLogic + readback: Readback + write_buffering: WriteBuffering + read_buffering: ReadBuffering + dereferencer: Dereferencer + ds: 'DesignState' + def __init__(self, **kwargs: Any) -> None: # Check for stray kwargs if kwargs: raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'") - self.hwif = None # type: Hwif - self.cpuif = None # type: CpuifBase - self.address_decode = None # type: AddressDecode - self.field_logic = None # type: FieldLogic - self.readback = None # type: Readback - self.write_buffering = None # type: WriteBuffering - self.read_buffering = None # type: ReadBuffering - self.dereferencer = None # type: Dereferencer - self.ds = None # type: DesignState loader = jj.ChoiceLoader([ jj.FileSystemLoader(os.path.dirname(__file__)), diff --git a/src/peakrdl_regblock/field_logic/bases.py b/src/peakrdl_regblock/field_logic/bases.py index 9dd47f5..9237821 100644 --- a/src/peakrdl_regblock/field_logic/bases.py +++ b/src/peakrdl_regblock/field_logic/bases.py @@ -99,6 +99,7 @@ class NextStateConditional: .next = .load_next = '1; """ + raise NotImplementedError def get_extra_combo_signals(self, field: 'FieldNode') -> List[SVLogic]: """ diff --git a/src/peakrdl_regblock/field_logic/hw_write.py b/src/peakrdl_regblock/field_logic/hw_write.py index 0ab3860..1efbf44 100644 --- a/src/peakrdl_regblock/field_logic/hw_write.py +++ b/src/peakrdl_regblock/field_logic/hw_write.py @@ -46,7 +46,7 @@ class WEWrite(AlwaysWrite): def is_match(self, field: 'FieldNode') -> bool: return ( field.is_hw_writable - and field.get_property('we') + and bool(field.get_property('we')) ) def get_predicate(self, field: 'FieldNode') -> str: @@ -64,7 +64,7 @@ class WELWrite(AlwaysWrite): def is_match(self, field: 'FieldNode') -> bool: return ( field.is_hw_writable - and field.get_property('wel') + and bool(field.get_property('wel')) ) def get_predicate(self, field: 'FieldNode') -> str: diff --git a/src/peakrdl_regblock/field_logic/sw_onwrite.py b/src/peakrdl_regblock/field_logic/sw_onwrite.py index 31cdca5..6397364 100644 --- a/src/peakrdl_regblock/field_logic/sw_onwrite.py +++ b/src/peakrdl_regblock/field_logic/sw_onwrite.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING, List, Optional from systemrdl.rdltypes import OnWriteType @@ -10,7 +10,7 @@ if TYPE_CHECKING: # TODO: implement sw=w1 "write once" fields class _OnWrite(NextStateConditional): - onwritetype = None # type: OnWriteType + onwritetype: Optional[OnWriteType] = None def is_match(self, field: 'FieldNode') -> bool: return field.is_sw_writable and field.get_property('onwrite') == self.onwritetype diff --git a/src/peakrdl_regblock/forloop_generator.py b/src/peakrdl_regblock/forloop_generator.py index 647c3b7..7ff0f4e 100644 --- a/src/peakrdl_regblock/forloop_generator.py +++ b/src/peakrdl_regblock/forloop_generator.py @@ -82,7 +82,7 @@ class RDLForLoopGenerator(ForLoopGenerator, RDLListener): return self.finish() def enter_AddressableComponent(self, node: 'AddressableNode') -> Optional[WalkerAction]: - if not node.is_array: + if not node.array_dimensions: return None for dim in node.array_dimensions: @@ -90,7 +90,7 @@ class RDLForLoopGenerator(ForLoopGenerator, RDLListener): return None def exit_AddressableComponent(self, node: 'AddressableNode') -> Optional[WalkerAction]: - if not node.is_array: + if not node.array_dimensions: return None for _ in node.array_dimensions: diff --git a/src/peakrdl_regblock/hwif/__init__.py b/src/peakrdl_regblock/hwif/__init__.py index 3583afe..3298f50 100644 --- a/src/peakrdl_regblock/hwif/__init__.py +++ b/src/peakrdl_regblock/hwif/__init__.py @@ -33,12 +33,12 @@ class Hwif: self.hwif_report_file = hwif_report_file - if self.ds.reuse_hwif_typedefs: - self._gen_in_cls = InputStructGenerator_TypeScope - self._gen_out_cls = OutputStructGenerator_TypeScope - else: + if not self.ds.reuse_hwif_typedefs: self._gen_in_cls = InputStructGenerator_Hier self._gen_out_cls = OutputStructGenerator_Hier + else: + self._gen_in_cls = InputStructGenerator_TypeScope + self._gen_out_cls = OutputStructGenerator_TypeScope @property def ds(self) -> 'DesignState': @@ -158,6 +158,7 @@ class Hwif: path = get_indexed_path(self.top_node, obj) return "hwif_in." + path elif isinstance(obj, PropertyReference): + assert isinstance(obj.node, FieldNode) return self.get_implied_prop_input_identifier(obj.node, obj.name) raise RuntimeError(f"Unhandled reference to: {obj}") @@ -210,6 +211,7 @@ class Hwif: # not sure when anything would call this function with a prop ref # when dereferencer's get_value is more useful here assert obj.node.get_property(obj.name) + assert isinstance(obj.node, (RegNode, FieldNode)) return self.get_implied_prop_output_identifier(obj.node, obj.name) raise RuntimeError(f"Unhandled reference to: {obj}") diff --git a/src/peakrdl_regblock/scan_design.py b/src/peakrdl_regblock/scan_design.py index 9e0768b..c3bea91 100644 --- a/src/peakrdl_regblock/scan_design.py +++ b/src/peakrdl_regblock/scan_design.py @@ -24,6 +24,7 @@ class DesignScanner(RDLListener): return self.ds.top_node def _get_out_of_hier_field_reset(self) -> None: + current_node: Optional[Node] current_node = self.top_node.parent while current_node is not None: for signal in current_node.signals(): diff --git a/src/peakrdl_regblock/struct_generator.py b/src/peakrdl_regblock/struct_generator.py index b727707..7b13f23 100644 --- a/src/peakrdl_regblock/struct_generator.py +++ b/src/peakrdl_regblock/struct_generator.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Optional, List import textwrap from collections import OrderedDict -from systemrdl.walker import RDLListener, RDLWalker +from systemrdl.walker import RDLListener, RDLWalker, WalkerAction from .identifier_filter import kw_filter as kwf @@ -140,32 +140,41 @@ class RDLStructGenerator(StructGenerator, RDLListener): return self.finish() - def enter_Addrmap(self, node: 'AddrmapNode') -> None: + def enter_Addrmap(self, node: 'AddrmapNode') -> Optional[WalkerAction]: self.push_struct(kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Addrmap(self, node: 'AddrmapNode') -> None: + def exit_Addrmap(self, node: 'AddrmapNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Regfile(self, node: 'RegfileNode') -> None: + def enter_Regfile(self, node: 'RegfileNode') -> Optional[WalkerAction]: self.push_struct(kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Regfile(self, node: 'RegfileNode') -> None: + def exit_Regfile(self, node: 'RegfileNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Mem(self, node: 'MemNode') -> None: + def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: self.push_struct(kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Mem(self, node: 'MemNode') -> None: + def exit_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Reg(self, node: 'RegNode') -> None: + def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: self.push_struct(kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Reg(self, node: 'RegNode') -> None: + def exit_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Field(self, node: 'FieldNode') -> None: + def enter_Field(self, node: 'FieldNode') -> Optional[WalkerAction]: self.add_member(kwf(node.inst_name), node.width) + return WalkerAction.Continue #------------------------------------------------------------------------------- @@ -228,33 +237,42 @@ class RDLFlatStructGenerator(FlatStructGenerator, RDLListener): return self.finish() - def enter_Addrmap(self, node: 'AddrmapNode') -> None: + def enter_Addrmap(self, node: 'AddrmapNode') -> Optional[WalkerAction]: type_name = self.get_typdef_name(node) self.push_struct(type_name, kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Addrmap(self, node: 'AddrmapNode') -> None: + def exit_Addrmap(self, node: 'AddrmapNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Regfile(self, node: 'RegfileNode') -> None: + def enter_Regfile(self, node: 'RegfileNode') -> Optional[WalkerAction]: type_name = self.get_typdef_name(node) self.push_struct(type_name, kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Regfile(self, node: 'RegfileNode') -> None: + def exit_Regfile(self, node: 'RegfileNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Mem(self, node: 'MemNode') -> None: + def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: type_name = self.get_typdef_name(node) self.push_struct(type_name, kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Mem(self, node: 'MemNode') -> None: + def exit_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Reg(self, node: 'RegNode') -> None: + def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: type_name = self.get_typdef_name(node) self.push_struct(type_name, kwf(node.inst_name), node.array_dimensions) + return WalkerAction.Continue - def exit_Reg(self, node: 'RegNode') -> None: + def exit_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: self.pop_struct() + return WalkerAction.Continue - def enter_Field(self, node: 'FieldNode') -> None: + def enter_Field(self, node: 'FieldNode') -> Optional[WalkerAction]: self.add_member(kwf(node.inst_name), node.width) + return WalkerAction.Continue diff --git a/src/peakrdl_regblock/utils.py b/src/peakrdl_regblock/utils.py index 1de18d4..b9d7a7f 100644 --- a/src/peakrdl_regblock/utils.py +++ b/src/peakrdl_regblock/utils.py @@ -1,5 +1,5 @@ import re -from typing import Match, Union +from typing import Match, Union, Optional from systemrdl.rdltypes.references import PropertyReference from systemrdl.node import Node, AddrmapNode @@ -45,6 +45,7 @@ def ref_is_internal(top_node: AddrmapNode, ref: Union[Node, PropertyReference]) For the sake of this exporter, root signals are treated as internal. """ + current_node: Optional[Node] if isinstance(ref, Node): current_node = ref elif isinstance(ref, PropertyReference): diff --git a/src/peakrdl_regblock/validate_design.py b/src/peakrdl_regblock/validate_design.py index 9a15917..9135c14 100644 --- a/src/peakrdl_regblock/validate_design.py +++ b/src/peakrdl_regblock/validate_design.py @@ -76,7 +76,7 @@ class DesignValidator(RDLListener): f"instance '{node.inst_name}' must be a multiple of {alignment}", node.inst.inst_src_ref ) - if node.is_array and (node.array_stride % alignment) != 0: + if node.is_array and (node.array_stride % alignment) != 0: # type: ignore # is_array implies stride is not none self.msg.error( "Unaligned registers are not supported. Address stride of " f"instance array '{node.inst_name}' must be a multiple of {alignment}", @@ -189,6 +189,7 @@ class DesignValidator(RDLListener): node.inst.inst_src_ref ) if node.is_array: + assert node.array_stride is not None if not is_pow2(node.array_stride): self.msg.error( f"Address stride of instance array '{node.inst_name}' is not a power of 2" diff --git a/tests/mypy.ini b/tests/mypy.ini index ea6803e..052d30e 100644 --- a/tests/mypy.ini +++ b/tests/mypy.ini @@ -1,6 +1,4 @@ [mypy] -#ignore_missing_imports = True -#strict_optional = False disallow_incomplete_defs = True disallow_untyped_defs = True warn_unused_configs = True