[dv/common] Update ral generation to support IP with multi-instance
Address #4211 and #2482
Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/util/reggen/data.py b/util/reggen/data.py
index b3b1bff..479d5ea 100644
--- a/util/reggen/data.py
+++ b/util/reggen/data.py
@@ -2,6 +2,7 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
+from collections import OrderedDict
from .field_enums import HwAccess, SwAccess, SwRdAccess, SwWrAccess
@@ -216,7 +217,7 @@
class Block():
width = 32
addr_width = 12
- base_addr = 0
+ base_addr = OrderedDict()
name = ""
hier_path = ""
regs = []
@@ -228,7 +229,8 @@
def __init__(self):
self.width = 32
self.addr_width = 12
- self.base_addr = 0
+ # Key is instance name
+ self.base_addr = OrderedDict()
self.name = ""
self.hier_path = ""
self.regs = []
diff --git a/util/reggen/gen_dv.py b/util/reggen/gen_dv.py
index ef2c9fd..75cb8d1 100644
--- a/util/reggen/gen_dv.py
+++ b/util/reggen/gen_dv.py
@@ -35,9 +35,9 @@
return m.name.lower()
-def sv_base_addr(b):
+def sv_base_addr(b, inst):
'''Get the base address of a block in SV syntax'''
- return "{}'h{:x}".format(b.width, b.base_addr)
+ return "{}'h{:x}".format(b.width, b.base_addr[inst])
def gen_dv(obj, outdir):
diff --git a/util/reggen/uvm_reg.sv.tpl b/util/reggen/uvm_reg.sv.tpl
index 7cf17f7..ce5740b 100644
--- a/util/reggen/uvm_reg.sv.tpl
+++ b/util/reggen/uvm_reg.sv.tpl
@@ -171,7 +171,9 @@
// sub blocks
% endif
% for b in block.blocks:
- rand ${gen_dv.bcname(b)} ${b.name};
+ % for inst in b.base_addr.keys():
+ rand ${gen_dv.bcname(b)} ${inst};
+ % endfor
% endfor
% if regs_flat:
// registers
@@ -209,14 +211,16 @@
// create sub blocks and add their maps
% endif
% for b in block.blocks:
- ${b.name} = ${gen_dv.bcname(b)}::type_id::create("${b.name}");
- ${b.name}.configure(.parent(this));
- ${b.name}.build(.base_addr(base_addr + ${gen_dv.sv_base_addr(b)}), .csr_excl(csr_excl));
- ${b.name}.set_hdl_path_root("tb.dut.top_earlgrey.u_${b.name}", "BkdrRegPathRtl");
- ${b.name}.set_hdl_path_root("tb.dut.top_earlgrey.u_${b.name}", "BkdrRegPathRtlCommitted");
- ${b.name}.set_hdl_path_root("tb.dut.top_earlgrey.u_${b.name}", "BkdrRegPathRtlShadow");
- default_map.add_submap(.child_map(${b.name}.default_map),
- .offset(base_addr + ${gen_dv.sv_base_addr(b)}));
+ % for inst, base_addr in b.base_addr.items():
+ ${inst} = ${gen_dv.bcname(b)}::type_id::create("${inst}");
+ ${inst}.configure(.parent(this));
+ ${inst}.build(.base_addr(base_addr + ${gen_dv.sv_base_addr(b, inst)}), .csr_excl(csr_excl));
+ ${inst}.set_hdl_path_root("tb.dut.top_earlgrey.u_${inst}", "BkdrRegPathRtl");
+ ${inst}.set_hdl_path_root("tb.dut.top_earlgrey.u_${inst}", "BkdrRegPathRtlCommitted");
+ ${inst}.set_hdl_path_root("tb.dut.top_earlgrey.u_${inst}", "BkdrRegPathRtlShadow");
+ default_map.add_submap(.child_map(${inst}.default_map),
+ .offset(base_addr + ${gen_dv.sv_base_addr(b, inst)}));
+ % endfor
% endfor
% if regs_flat:
set_hdl_path_root("tb.dut", "BkdrRegPathRtl");
diff --git a/util/topgen.py b/util/topgen.py
index c8c72e8..36d459d 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -800,7 +800,7 @@
top_block.base_addr = 0
top_block.width = int(top["datawidth"])
- # add blocks
+ # add all the IPs into blocks
for ip_obj in ip_objs:
top_block.blocks.append(gen_rtl.json_to_reg(ip_obj))
@@ -818,14 +818,14 @@
mem.n_bits = top_block.width
top_block.wins.append(mem)
- # get sub-block base addresses from top cfg
+ # get sub-block base addresses, instance names from top cfg
for block in top_block.blocks:
for module in top["module"]:
- if block.name == module["name"]:
- block.base_addr = int(module["base_addr"], 0)
- break
+ if block.name == module["type"]:
+ block.base_addr[module["name"]] = int(module["base_addr"], 0)
- top_block.blocks.sort(key=lambda block: block.base_addr)
+ # sort by the base_addr of 1st instance of the block
+ top_block.blocks.sort(key=lambda block: next(iter(block.base_addr))[1])
top_block.wins.sort(key=lambda win: win.base_addr)
# generate the top ral model with template