[reggen, util] Add support for data integrity passthrough

- When a module has no window or has windows with no integrity passthrough,
  data integrity can be generated at a common location.

- When a module window has data integrity passthrough, the regfile
  registers must separately generate data integrity so as to not
  duplicate.

- When a module has a mix of windows with and without integrity, common
  generation is not possible, and data integrity is selectively generated
  for those windows that do not directly pass them in.

- The only module that is currently impacted is otbn (and soon rom_ctrl)
  Otbn dmem / imem each contain their own integrity, and thus can directly
  pass them through.  The regfile for otbn thus no longer generates data
  integrity at a common location, and instead generates it only for data
  passed through tlul_adapter_reg.  The data integrity for the windows are
  fed through directly.

Signed-off-by: Timothy Chen <timothytim@google.com>

[top] Auto generate files

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/util/topgen.py b/util/topgen.py
index 0b562b1..e14f447 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -790,7 +790,7 @@
     # together with a map of interface addresses.
     inst_to_block = {}  # type: Dict[str, str]
     if_addrs = {}  # type: Dict[Tuple[str, Optional[str]], int],
-    attrs = {} # type: Dict[str, str]
+    attrs = {}  # type: Dict[str, str]
 
     for module in top['module']:
         inst_name = module['name']
@@ -798,7 +798,8 @@
         block = name_to_block[block_name]
         if "attr" in module:
             if module["attr"] not in ['templated', 'reggen_top', 'reggen_only']:
-                raise ValueError('Unsupported value for attr field of {}: {!r}'.format(what, attr))
+                raise ValueError('Unsupported value for attr field of {}: {!r}'.
+                                 format(block_name, module["attr"]))
             attrs[inst_name] = module["attr"]
 
         inst_to_block[inst_name] = block_name
@@ -811,6 +812,8 @@
     for item in list(top.get("memory", [])):
         byte_write = ('byte_write' in item and
                       item["byte_write"].lower() == "true")
+        data_intg_passthru = ('data_intg_passthru' in item and
+                              item["data_intg_passthru"].lower() == "true")
         size_in_bytes = int(item['size'], 0)
         num_regs = size_in_bytes // addrsep
         swaccess = access.SWAccess('top-level memory',
@@ -820,6 +823,7 @@
                                   desc='(generated from top-level)',
                                   unusual=False,
                                   byte_write=byte_write,
+                                  data_intg_passthru=data_intg_passthru,
                                   validbits=regwidth,
                                   items=num_regs,
                                   size_in_bytes=size_in_bytes,
@@ -1135,8 +1139,6 @@
     # Generic Inter-module connection
     im.elab_intermodule(completecfg)
 
-    top_name = completecfg["name"]
-
     # Generate top.gen.hjson right before rendering
     genhjson_dir = out_path / "data/autogen"
     genhjson_dir.mkdir(parents=True, exist_ok=True)