[topgen] Fix Merge IP shallow copy issue
Problem:
If multiple instances for a module exist in a top, inter_signal_list
is added N times into only last modules.
While merging the ip object read from .hjson file into the top['module']
entry, it just shallow copies the data structure into module which
creates multiple instances of a ip to access same data structure.
Inter-signal list manipulates the data structure while processing, which
happen to move the data structure to last instance.
It now use deepcopy to copy over any list object into top['module']
entries.
Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/util/topgen/intermodule.py b/util/topgen/intermodule.py
index 8d461b1..10637c1 100644
--- a/util/topgen/intermodule.py
+++ b/util/topgen/intermodule.py
@@ -329,7 +329,12 @@
x for x in sig_list if x["name"] == s_name and x["inst_name"] == m_name
]
- return filtered[0] if len(filtered) == 1 else None
+ if len(filtered) == 1:
+ return filtered[0]
+
+ log.error("Found {num} entry/entries for {m_name}.{s_name}:".format(
+ num=len(filtered), m_name=m_name, s_name=s_name))
+ return None
# Validation
diff --git a/util/topgen/merge.py b/util/topgen/merge.py
index 86383d1..cfc970f 100644
--- a/util/topgen/merge.py
+++ b/util/topgen/merge.py
@@ -61,7 +61,8 @@
# available_input_list , available_output_list, available_inout_list
if "available_input_list" in ip:
- ip_module["available_input_list"] = ip["available_input_list"]
+ ip_module["available_input_list"] = deepcopy(
+ ip["available_input_list"])
for i in ip_module["available_input_list"]:
i.pop('desc', None)
i["type"] = "input"
@@ -69,7 +70,8 @@
else:
ip_module["available_input_list"] = []
if "available_output_list" in ip:
- ip_module["available_output_list"] = ip["available_output_list"]
+ ip_module["available_output_list"] = deepcopy(
+ ip["available_output_list"])
for i in ip_module["available_output_list"]:
i.pop('desc', None)
i["type"] = "output"
@@ -77,7 +79,8 @@
else:
ip_module["available_output_list"] = []
if "available_inout_list" in ip:
- ip_module["available_inout_list"] = ip["available_inout_list"]
+ ip_module["available_inout_list"] = deepcopy(
+ ip["available_inout_list"])
for i in ip_module["available_inout_list"]:
i.pop('desc', None)
i["type"] = "inout"
@@ -87,7 +90,7 @@
# interrupt_list
if "interrupt_list" in ip:
- ip_module["interrupt_list"] = ip["interrupt_list"]
+ ip_module["interrupt_list"] = deepcopy(ip["interrupt_list"])
for i in ip_module["interrupt_list"]:
i.pop('desc', None)
i["type"] = "interrupt"
@@ -97,7 +100,7 @@
# alert_list
if "alert_list" in ip:
- ip_module["alert_list"] = ip["alert_list"]
+ ip_module["alert_list"] = deepcopy(ip["alert_list"])
for i in ip_module["alert_list"]:
i.pop('desc', None)
i["type"] = "alert"
@@ -113,7 +116,7 @@
# wkup_list
if "wakeup_list" in ip:
- ip_module["wakeup_list"] = ip["wakeup_list"]
+ ip_module["wakeup_list"] = deepcopy(ip["wakeup_list"])
for i in ip_module["wakeup_list"]:
i.pop('desc', None)
else:
@@ -133,7 +136,7 @@
# inter-module
if "inter_signal_list" in ip:
- ip_module["inter_signal_list"] = ip["inter_signal_list"]
+ ip_module["inter_signal_list"] = deepcopy(ip["inter_signal_list"])
# TODO: validate
@@ -591,13 +594,15 @@
log.info("Adding wakeup from module %s" % m["name"])
for entry in m["wakeup_list"]:
log.info("Adding singal %s" % entry["name"])
- topcfg["wakeups"].append("{module}.{signal}".format(module=m["name"].lower(),
- signal=entry["name"]))
+ topcfg["wakeups"].append("{module}.{signal}".format(
+ module=m["name"].lower(), signal=entry["name"]))
# add wakeup signals to pwrmgr connections
# TBD: What's the best way to not hardcode this signal below?
# We could make this a top.hjson variable and validate it against pwrmgr hjson
topcfg["inter_module"]["connect"]["pwrmgr.wakeups"] = topcfg["wakeups"]
+ log.info("Intermodule signals: {}".format(
+ topcfg["inter_module"]["connect"]))
def amend_pinmux_io(top):