[topgen] Pass alias register paths into topgen for top RAL generation

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/dv/tools/ralgen/ralgen.py b/hw/dv/tools/ralgen/ralgen.py
index 72ab424..68dd28d 100755
--- a/hw/dv/tools/ralgen/ralgen.py
+++ b/hw/dv/tools/ralgen/ralgen.py
@@ -52,18 +52,18 @@
     if ip_hjson:
         ral_spec = root_dir / ip_hjson
         cmd = util_path / "regtool.py"
+        args = [cmd, "-s", "-t", os.getcwd(), ral_spec]
         if alias_hjson:
-            ral_alias = root_dir / alias_hjson
-            args = [cmd, "-s", "-a", ral_alias, "-t", os.getcwd(), ral_spec]
-        else:
-            args = [cmd, "-s", "-t", os.getcwd(), ral_spec]
+            args += ["--alias", root_dir / alias_hjson]
     else:
         ral_spec = root_dir / top_hjson
         cmd = util_path / "topgen.py"
         args = [cmd, "-r", "-o", os.getcwd(), "-t", ral_spec]
         if hjson_path:
             args += ["--hjson-path", root_dir / hjson_path]
-
+        if alias_hjson:
+            for alias in alias_hjson:
+                args += ["--alias-files", root_dir / alias]
     if dv_base_names:
         args += ["--dv-base-names"] + dv_base_names
 
diff --git a/util/topgen.py b/util/topgen.py
index 7f7d608..0b8ba08 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -470,10 +470,12 @@
     # Generate reg files
     generate_regfile_from_path(hjson_path, rtl_path, original_rtl_path)
 
+
 def get_rst_ni(top):
     rstmgrs = [m for m in top['module'] if m['type'] == 'rstmgr']
     return rstmgrs[0]["reset_connections"]
 
+
 # generate rstmgr
 def generate_rstmgr(topcfg, out_path):
     log.info("Generating rstmgr")
@@ -639,7 +641,6 @@
 def generate_top_ral(top: Dict[str, object], name_to_block: Dict[str, IpBlock],
                      dv_base_names: List[str], out_path: str):
     # construct top ral block
-
     regwidth = int(top["datawidth"])
     assert regwidth % 8 == 0
     addrsep = regwidth // 8
@@ -871,6 +872,22 @@
         assert lblock not in name_to_block
         name_to_block[lblock] = block
 
+    # Read in alias files one-by-one, peek inside to figure out which IP block
+    # they belong to and apply the alias file to that IP block.
+    if args.alias_files:
+        for alias in args.alias_files:
+            with open(alias, 'r', encoding='utf-8') as handle:
+                raw = hjson.loads(handle.read(), use_decimal=True)
+                if 'alias_target' not in raw:
+                    raise ValueError('Missing alias_target key '
+                                     'in alias file {}.'.format(alias))
+                alias_target = raw['alias_target'].lower()
+                if alias_target not in name_to_block:
+                    raise ValueError('Alias target {} is not defined.'
+                                     .format(alias_target))
+                where = 'alias file at {}'.format(alias)
+                name_to_block[alias_target].alias_from_raw(False, raw, where)
+
     connect_clocks(topcfg, name_to_block)
 
     # Read the crossbars under the top directory
@@ -998,6 +1015,16 @@
         action="store_true",
         help="If set, the tool generates top level RAL model for DV")
     parser.add_argument(
+        "--alias-files",
+        nargs="+",
+        type=Path,
+        default=None,
+        help="""
+          If defined, topgen uses supplied alias hjson file(s) to override the
+          generic register definitions when building the RAL model. This
+          argument is only relevant in conjunction with the `--top_ral` switch.
+        """)
+    parser.add_argument(
         "--dv-base-names",
         nargs="+",
         help="Names or prefix for the DV register classes from which "