[topgen] Add countermeasure check for legacy-style generated IPs
See #10071 for reference.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/util/topgen.py b/util/topgen.py
index 5d1d810..585b52e 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -16,6 +16,7 @@
from io import StringIO
from pathlib import Path
from typing import Dict, List, Optional, Tuple
+from itertools import chain
import hjson
import tlgen
@@ -26,6 +27,7 @@
from reggen import access, gen_rtl, window
from reggen.inter_signal import InterSignal
from reggen.ip_block import IpBlock
+from reggen.countermeasure import CounterMeasure
from reggen.lib import check_list
from topgen import get_hjsonobj_xbars
from topgen import intermodule as im
@@ -222,6 +224,27 @@
ipgen_render('rv_plic', topname, params, out_path)
+# TODO: For generated IPs that are generated legacy style (i.e., without IPgen)
+# we have to search both the source and destination RTL directories, since not
+# all files are copied over. This is a workaround which can be removed once
+# all generated IPs have transitioned to IPgen.
+def generate_regfile_from_path(hjson_path: Path,
+ generated_rtl_path: Path,
+ original_rtl_path: Path = None):
+ '''Generate RTL register file from path and check countermeasure labels'''
+ obj = IpBlock.from_path(str(hjson_path), [])
+
+ # If this block has countermeasures, we grep for RTL annotations in
+ # all .sv implementation files and check whether they match up
+ # with what is defined inside the Hjson.
+ sv_files = generated_rtl_path.glob('*.sv')
+ if original_rtl_path is not None:
+ sv_files = chain(sv_files, original_rtl_path.glob('*.sv'))
+ rtl_names = CounterMeasure.search_rtl_files(sv_files)
+ obj.check_cm_annotations(rtl_names, str(hjson_path))
+ gen_rtl.gen_rtl(obj, str(generated_rtl_path))
+
+
def generate_pinmux(top, out_path):
topname = top['name']
@@ -297,6 +320,8 @@
# Template path
tpl_path = Path(
__file__).resolve().parent / '../hw/ip/pinmux/data/pinmux.hjson.tpl'
+ original_rtl_path = Path(
+ __file__).resolve().parent / '../hw/ip/pinmux/rtl'
# Generate register package and RTLs
gencmd = ("// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson "
@@ -332,8 +357,8 @@
with hjson_gen_path.open(mode='w', encoding='UTF-8') as fout:
fout.write(genhdr + gencmd + out)
- gen_rtl.gen_rtl(IpBlock.from_text(out, [], str(hjson_gen_path)),
- str(rtl_path))
+ # Generate reg file
+ generate_regfile_from_path(hjson_gen_path, rtl_path, original_rtl_path)
def generate_clkmgr(top, cfg_path, out_path):
@@ -348,6 +373,7 @@
hjson_tpl = cfg_path / '../ip/clkmgr/data/clkmgr.hjson.tpl'
rtl_tpl = cfg_path / '../ip/clkmgr/data/clkmgr.sv.tpl'
pkg_tpl = cfg_path / '../ip/clkmgr/data/clkmgr_pkg.sv.tpl'
+ original_rtl_path = cfg_path / '../ip/clkmgr/rtl'
hjson_out = data_path / 'clkmgr.hjson'
rtl_out = rtl_path / 'clkmgr.sv'
@@ -383,7 +409,7 @@
fout.write(genhdr + out)
# Generate reg files
- gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_out), []), str(rtl_path))
+ generate_regfile_from_path(hjson_out, rtl_path, original_rtl_path)
# generate pwrmgr
@@ -417,6 +443,7 @@
# So, read template files from ip directory.
tpl_path = Path(__file__).resolve().parent / '../hw/ip/pwrmgr/data'
hjson_tpl_path = tpl_path / 'pwrmgr.hjson.tpl'
+ original_rtl_path = Path(__file__).resolve().parent / '../hw/ip/pwrmgr/rtl'
# Render and write out hjson
out = StringIO()
@@ -440,7 +467,7 @@
fout.write(genhdr + out)
# Generate reg files
- gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_path), []), str(rtl_path))
+ generate_regfile_from_path(hjson_path, rtl_path, original_rtl_path)
# generate rstmgr
@@ -453,6 +480,7 @@
doc_path = out_path / 'ip/rstmgr/data/autogen'
doc_path.mkdir(parents=True, exist_ok=True)
tpl_path = Path(__file__).resolve().parent / '../hw/ip/rstmgr/data'
+ original_rtl_path = Path(__file__).resolve().parent / '../hw/ip/rstmgr/rtl'
# Read template files from ip directory.
tpls = []
@@ -514,7 +542,7 @@
# Generate reg files
hjson_path = outputs[0]
- gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_path), []), str(rtl_path))
+ generate_regfile_from_path(hjson_path, rtl_path, original_rtl_path)
# generate flash
@@ -527,6 +555,8 @@
doc_path = out_path / 'ip/flash_ctrl/data/autogen'
doc_path.mkdir(parents=True, exist_ok=True)
tpl_path = Path(__file__).resolve().parent / '../hw/ip/flash_ctrl/data'
+ original_rtl_path = Path(
+ __file__).resolve().parent / '../hw/ip/flash_ctrl/rtl'
# Read template files from ip directory.
tpls = []
@@ -573,7 +603,7 @@
# Generate reg files
hjson_path = outputs[0]
- gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_path), []), str(rtl_path))
+ generate_regfile_from_path(hjson_path, rtl_path, original_rtl_path)
def generate_top_only(top_only_dict, out_path, topname, alt_hjson_path):
@@ -595,8 +625,7 @@
ip, hjson_path, genrtl_dir))
# Generate reg files
- gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_path), []),
- str(genrtl_dir))
+ generate_regfile_from_path(hjson_path, genrtl_dir)
def generate_top_ral(top: Dict[str, object], name_to_block: Dict[str, IpBlock],