[util] Add alternate hjson paths for reggen_only modules
- Fixes #8207
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/util/topgen.py b/util/topgen.py
index d22a1d1..d7e7adc 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -584,12 +584,19 @@
gen_rtl.gen_rtl(IpBlock.from_path(str(hjson_path), []), str(rtl_path))
-def generate_top_only(top_only_list, out_path, topname):
+def generate_top_only(top_only_dict, out_path, topname, alt_hjson_path):
log.info("Generating top only modules")
- for ip in top_only_list:
- hjson_path = Path(__file__).resolve(
- ).parent / "../hw/top_{}/ip/{}/data/{}.hjson".format(topname, ip, ip)
+ for ip, reggen_only in top_only_dict.items():
+
+ if reggen_only and alt_hjson_path is not None:
+ hjson_dir = Path(alt_hjson_path)
+ else:
+ hjson_dir = Path(__file__).resolve(
+ ).parent / f"../hw/top_{topname}/ip/{ip}/data/"
+
+ hjson_path = hjson_dir / f"{ip}.hjson"
+
genrtl_dir = out_path / "ip/{}/rtl".format(ip)
genrtl_dir.mkdir(parents=True, exist_ok=True)
log.info("Generating top modules {}, hjson: {}, output: {}".format(
@@ -711,11 +718,12 @@
# These modules are NOT generated but belong to a specific top
# and therefore not part of "hw/ip"
- top_only_list = [
- module['type'] for module in topcfg['module']
+ top_only_dict = {
+ module['type']: lib.is_reggen_only(module)
+ for module in topcfg['module']
if lib.is_top_reggen(module)
- ]
- log.info("Filtered list is {}".format(top_only_list))
+ }
+ log.info("Filtered dict is {}".format(top_only_dict))
topname = topcfg["name"]
@@ -724,7 +732,7 @@
ips = search_ips(ip_dir)
# exclude filtered IPs (to use top_${topname} one) and
- exclude_list = generated_list + top_only_list
+ exclude_list = generated_list + list(top_only_dict.keys())
ips = [x for x in ips if not x.parents[1].name in exclude_list]
# Hack alert
@@ -760,9 +768,14 @@
ip_hjson = hjson_dir.parent / ip_relpath / ip / desc_file_relpath / f"{ip}.hjson"
ips.append(ip_hjson)
- for ip in top_only_list:
+ for ip, reggen_only in top_only_dict.items():
log.info("Appending {}".format(ip))
- ip_hjson = hjson_dir.parent / "ip/{}/data/{}.hjson".format(ip, ip)
+
+ if reggen_only and args.hjson_path:
+ ip_hjson = Path(args.hjson_path) / f"{ip}.hjson"
+ else:
+ ip_hjson = hjson_dir.parent / f"ip/{ip}/data/{ip}.hjson"
+
ips.append(ip_hjson)
# load Hjson and pass validate from reggen
@@ -888,7 +901,7 @@
# Generate top only modules
# These modules are not templated, but are not in hw/ip
- generate_top_only(top_only_list, out_path, topname)
+ generate_top_only(top_only_dict, out_path, topname, args.hjson_path)
return completecfg, name_to_block
@@ -905,6 +918,15 @@
help='''Target TOP directory.
Module is created under rtl/. (default: dir(topcfg)/..)
''') # yapf: disable
+ parser.add_argument(
+ '--hjson_path',
+ help='''
+ If defined, topgen uses supplied path to search for ip hjson.
+ This applies only to ip's with the `reggen_only` attribute.
+ If an hjson is located both in the conventional path and the alternate
+ path, the alternate path has priority.
+ '''
+ )
parser.add_argument('--verbose', '-v', action='store_true', help="Verbose")
# Generator options: 'no' series. cannot combined with 'only' series
@@ -990,6 +1012,9 @@
else:
outdir = Path(args.outdir)
+ if args.hjson_path is not None:
+ log.error("Alternate hjson path is {args.hjson_path}")
+
out_path = Path(outdir)
cfg_path = Path(args.topcfg).parents[1]
diff --git a/util/topgen/lib.py b/util/topgen/lib.py
index fe17cad..b56c8d9 100644
--- a/util/topgen/lib.py
+++ b/util/topgen/lib.py
@@ -333,24 +333,22 @@
def is_templated(module):
"""Returns an indication where a particular module is templated
"""
- if "attr" not in module:
- return False
- elif module["attr"] in ["templated"]:
- return True
- else:
- return False
+ return module.get('attr') in ["templated"]
def is_top_reggen(module):
"""Returns an indication where a particular module is NOT templated
and requires top level specific reggen
"""
- if "attr" not in module:
- return False
- elif module["attr"] in ["reggen_top", "reggen_only"]:
- return True
- else:
- return False
+ return module.get('attr') in ["reggen_top", "reggen_only"]
+
+
+def is_reggen_only(module):
+ """Returns an indication where a particular module is NOT templated,
+ requires top level specific reggen and is NOT instantiated in the
+ top
+ """
+ return module.get('attr') == "reggen_only"
def is_inst(module):