[topgen] Add a function to find other side ports
The function that finds the other side of port connected through
inter-module signal is useful.
The `find_otherside_modules()` receives top-level cfg Hjson and the
current module instance name, signal name. Then it searches every
connections and returns a list of module name, signal name pairs if
exists.
This commit is related to #3040 #2464
Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
Co-authored-by: Eunchan Kim <eunchan@google.com>
Co-authored-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/util/topgen/intermodule.py b/util/topgen/intermodule.py
index 10637c1..2390457 100644
--- a/util/topgen/intermodule.py
+++ b/util/topgen/intermodule.py
@@ -6,7 +6,7 @@
import re
from collections import OrderedDict
from enum import Enum
-from typing import Dict, Tuple
+from typing import Dict, Tuple, List
from reggen.validate import check_int
from topgen import lib
@@ -223,22 +223,19 @@
OrderedDict([('package', sig["package"]),
('struct', sig["struct"] + "_req"),
('signame', sig_name + "_req"),
- ('width', sig["width"]),
- ('type', sig["type"]),
+ ('width', sig["width"]), ('type', sig["type"]),
('default', sig["default"])]))
definitions.append(
OrderedDict([('package', sig["package"]),
('struct', sig["struct"] + "_rsp"),
('signame', sig_name + "_rsp"),
- ('width', sig["width"]),
- ('type', sig["type"]),
+ ('width', sig["width"]), ('type', sig["type"]),
('default', sig["default"])]))
else: # if sig["type"] == "uni":
definitions.append(
OrderedDict([('package', sig["package"]),
('struct', sig["struct"]), ('signame', sig_name),
- ('width', sig["width"]),
- ('type', sig["type"]),
+ ('width', sig["width"]), ('type', sig["type"]),
('default', sig["default"])]))
if "external" not in topcfg["inter_module"]:
@@ -390,6 +387,49 @@
return error
+def find_otherside_modules(topcfg: OrderedDict, m,
+ s) -> List[Tuple[str, str, str]]:
+ """Find far-end port based on given module and signal name
+ """
+ signame = "{}.{}".format(m, s)
+ for req, rsps in topcfg["inter_module"]["connect"].items():
+ if req.startswith(signame):
+ # return rsps after splitting module instance name and the port
+ result = []
+ for rsp in rsps:
+ rsp_m, rsp_s, rsp_i = filter_index(rsp)
+ result.append(('connect', rsp_m, rsp_s))
+ return result
+
+ for rsp in rsps:
+ if signame == rsp:
+ req_m, req_s, req_i = filter_index(req)
+ return [('connect', req_m, req_s)]
+
+ # If reaches here, no matching results in 'connect'
+ # so search 'top' or 'external'
+
+ # todo: something here
+ # check special cases
+ pairs = {
+ ('main', 'tl_corei'): ('rv_core_ibex', 'tl_i'),
+ ('main', 'tl_cored'): ('rv_core_ibex', 'tl_d'),
+ ('main', 'tl_dm_sba'): ('dm_top', 'tl_h'),
+ ('main', 'tl_debug_mem'): ('dm_top', 'tl_d')
+ }
+ for sig in topcfg["inter_signal"]["signals"]:
+ pairs[(sig['inst_name'], sig['name'])] = ('', sig['top_signame'])
+
+ pair = pairs.get((m, s))
+ if pair is not None:
+ return [('top', pair[0], pair[1])]
+
+ # if reaches here, it means either the format is wrong, or floating port.
+ log.error("`find_otherside_modules()`: "
+ "No such signal {}.{} exists.".format(m, s))
+ return []
+
+
def check_intermodule(topcfg: Dict, prefix: str) -> int:
if "inter_module" not in topcfg:
return 0