[topgen] Use OrderedDicts in more places
In Python 3.5, dicts are not ordered. This causes issues when
regenerating output generated by iterating over a dict, which happens
frequently in topgen.
This commit comprehensively spreads the use of OrderedDict in topgen
such that we can re-generate tops in CI (which uses python 3.5) without
issues.
Signed-off-by: Sam Elliott <selliott@lowrisc.org>
diff --git a/hw/ip/clkmgr/data/clkmgr_pkg.sv.tpl b/hw/ip/clkmgr/data/clkmgr_pkg.sv.tpl
index 5944585..bc90f85 100644
--- a/hw/ip/clkmgr/data/clkmgr_pkg.sv.tpl
+++ b/hw/ip/clkmgr/data/clkmgr_pkg.sv.tpl
@@ -3,6 +3,8 @@
// SPDX-License-Identifier: Apache-2.0
<%
+from collections import OrderedDict
+
clks_attr = cfg['clocks']
grps = clks_attr['groups']
num_hints = len(hint_clks)
@@ -19,7 +21,15 @@
};
typedef struct packed {
-% for clk in {**ft_clks, **hint_clks, **rg_clks, **sw_clks}:
+<%
+# Merge Clock Dicts together
+all_clocks = OrderedDict()
+all_clocks.update(ft_clks)
+all_clocks.update(hint_clks)
+all_clocks.update(rg_clks)
+all_clocks.update(sw_clks)
+%>\
+% for clk in all_clocks:
logic ${clk};
% endfor
diff --git a/hw/top_earlgrey/data/tb__xbar_connect.sv.tpl b/hw/top_earlgrey/data/tb__xbar_connect.sv.tpl
index 63f6d9b..dd0f9f7 100644
--- a/hw/top_earlgrey/data/tb__xbar_connect.sv.tpl
+++ b/hw/top_earlgrey/data/tb__xbar_connect.sv.tpl
@@ -9,18 +9,18 @@
top_hier = 'tb.dut.top_' + top["name"] + '.'
clk_hier = top_hier + top["clocks"]["hier_paths"]["top"]
-clk_src = {}
+clk_src = OrderedDict()
for xbar in top["xbar"]:
for clk, src in xbar["clock_srcs"].items():
clk_src[clk] = src
-clk_freq = {}
+clk_freq = OrderedDict()
for clock in top["clocks"]["srcs"]:
if clock["name"] in clk_src.values():
clk_freq[clock["name"]] = clock["freq"]
-hosts = {}
-devices = {}
+hosts = OrderedDict()
+devices = OrderedDict()
for xbar in top["xbar"]:
for node in xbar["nodes"]:
if node["type"] == "host" and not node["xbar"]:
diff --git a/hw/top_earlgrey/data/top_earlgrey.h.tpl b/hw/top_earlgrey/data/top_earlgrey.h.tpl
index 0dd2064..09b1be2 100644
--- a/hw/top_earlgrey/data/top_earlgrey.h.tpl
+++ b/hw/top_earlgrey/data/top_earlgrey.h.tpl
@@ -86,6 +86,8 @@
<%!
+from collections import OrderedDict
+
def camelcase(str):
"""Turns a string from 'snake_case' to 'CamelCase'."""
return "".join([part.capitalize() for part in str.split("_")])
@@ -107,7 +109,7 @@
%>\
## This dictionary will be used in the C implementation to generate
## `top_${top["name"]}_plic_interrupt_for_peripheral`.
-<% c_gen_info["interrupt_id_map"] = {} %>\
+<% c_gen_info["interrupt_id_map"] = OrderedDict() %>\
/**
* PLIC Interrupt source peripheral enumeration.
*
diff --git a/hw/top_earlgrey/data/xbar_env_pkg__params.sv.tpl b/hw/top_earlgrey/data/xbar_env_pkg__params.sv.tpl
index 885135f..cb90d6e 100644
--- a/hw/top_earlgrey/data/xbar_env_pkg__params.sv.tpl
+++ b/hw/top_earlgrey/data/xbar_env_pkg__params.sv.tpl
@@ -5,6 +5,8 @@
// xbar_env_pkg__params generated by `topgen.py` tool
<%
+ from collections import OrderedDict
+
def is_device_a_xbar(dev_name):
for xbar in top["xbar"]:
if xbar["name"] == dev_name:
@@ -26,7 +28,7 @@
return edge_devices
# find device xbar and assign all its device nodes to it: "peri" -> "uart, gpio, ..."
- xbar_device_dict = {}
+ xbar_device_dict = OrderedDict()
for xbar in top["xbar"]:
for n in xbar["nodes"]:
@@ -34,7 +36,7 @@
xbar_device_dict[n["name"]] = get_xbar_edge_nodes(n["name"])
# create the mapping: host with the corresponding devices map
- host_dev_map = {}
+ host_dev_map = OrderedDict()
for host, devices in top["xbar"][0]["connections"].items():
dev_list = []
for dev in devices:
diff --git a/util/topgen.py b/util/topgen.py
index 338d869..08f5e74 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -498,36 +498,36 @@
# This includes two groups of clocks
# Clocks fed from the always-on source
# Clocks fed to the powerup group
- ft_clks = {
- clk: src
+ ft_clks = OrderedDict([
+ (clk, src)
for grp in grps for (clk, src) in grp['clocks'].items()
if src_aon_attr[src] or grp['name'] == 'powerup'
- }
+ ])
# root-gate clocks
- rg_clks = {
- clk: src
+ rg_clks = OrderedDict([
+ (clk, src)
for grp in grps for (clk, src) in grp['clocks'].items()
if grp['name'] != 'powerup' and grp['sw_cg'] == 'no' and
not src_aon_attr[src]
- }
+ ])
# direct sw control clocks
- sw_clks = {
- clk: src
+ sw_clks = OrderedDict([
+ (clk, src)
for grp in grps for (clk, src) in grp['clocks'].items()
if grp['sw_cg'] == 'yes' and not src_aon_attr[src]
- }
+ ])
# sw hint clocks
- hint_clks = {
- clk: src
+ hint_clks = OrderedDict([
+ (clk, src)
for grp in grps for (clk, src) in grp['clocks'].items()
if grp['sw_cg'] == 'hint' and not src_aon_attr[src]
- }
+ ])
- out = StringIO()
for idx, tpl in enumerate(tpls):
+ out = ""
with tpl.open(mode='r', encoding='UTF-8') as fin:
tpl = Template(fin.read())
try:
diff --git a/util/topgen/merge.py b/util/topgen/merge.py
index cfc970f..f2e8442 100644
--- a/util/topgen/merge.py
+++ b/util/topgen/merge.py
@@ -450,7 +450,7 @@
for src in clks_attr['srcs']:
if 'derived' not in src:
src['derived'] = "no"
- src['params'] = {}
+ src['params'] = OrderedDict()
# Default assignments
for group in clks_attr['groups']:
@@ -518,7 +518,7 @@
def amend_resets(top):
"""Add a path variable to reset declaration
"""
- reset_paths = {}
+ reset_paths = OrderedDict()
for reset in top["resets"]: