diff --git a/util/reggen/ip_block.py b/util/reggen/ip_block.py index 2a175211a3aab..934659dfb0811 100644 --- a/util/reggen/ip_block.py +++ b/util/reggen/ip_block.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 '''Code representing an IP block for reggen''' +import logging as log from typing import Dict, List, Optional, Sequence, Set, Tuple import hjson # type: ignore @@ -622,3 +623,40 @@ def check_cm_annotations(self, rtl_names: Dict[str, List[Tuple[str, int]]], return CounterMeasure.check_annotation_list(self.name, hjson_path, rtl_names, self.countermeasures) + + def check_regwens(self) -> bool: + """Checks all regwens are used in at least one other CSR + + This relies on the regwen having the string "REGWEN" in its name. + The uses should be in the "regwen" field of a CSR. + """ + log.debug(f"Checking regwens for IP {self.name}") + status: bool = True + for rb in self.reg_blocks.values(): + rb_name = rb.name if rb.name else "default" + log.debug(f"Register block: {rb_name}") + regwen_names: List[str] = [reg.name for reg in rb.registers + if "REGWEN" in reg.name] + unused_regwens: List[str] = [] + for regwen in regwen_names: + regwen_users = [] + for reg in rb.registers: + if reg.regwen == regwen: + regwen_users.append(reg) + for multi_reg in rb.multiregs: + for reg in multi_reg.regs: + if reg.regwen == regwen: + regwen_users.append(reg) + if not regwen_users: + unused_regwens.append(regwen) + else: + log.debug( + f"Regwen {regwen} in {self.name}'s {rb_name} register " + "block controls the following registers:") + for r in regwen_users: + log.debug(f" {r.name}") + if unused_regwens: + log.error(f"Unused regwen(s) in {self.name} {rb_name} " + f"register block: {', '.join(unused_regwens)}") + status = False + return status diff --git a/util/topgen.py b/util/topgen.py index 9545fdda8beb7..97e6eee12864a 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -1263,6 +1263,7 @@ def _check_countermeasures(completecfg: Dict[str, object], log.debug("Checking countermeasures for %s.", name) success &= name_to_block[name].check_cm_annotations( rtl_names, hjson_path.name) + success &= name_to_block[name].check_regwens() if success: log.info("All Hjson declared countermeasures are implemented in RTL.") else: @@ -1614,8 +1615,9 @@ def main(): # Change verbosity to log.INFO to see an okay confirmation message: # the log level is set to log.ERROR upon start to avoid the chatter # of the regular topgen elaboration. + log_level = log.DEBUG if args.verbose else log.INFO log.basicConfig(format="%(levelname)s: %(message)s", - level=log.INFO, + level=log_level, force=True) okay = _check_countermeasures(completecfg, name_to_block,