[reggen,topgen] Move top-level DV generation from reggen to topgen
After lots of refactoring in this code, we can now split this up
properly and reggen no longer needs the "Top" class (which definitely
felt like it was in the wrong place!)
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/util/reggen/gen_dv.py b/util/reggen/gen_dv.py
index 763d172..d2d054a 100644
--- a/util/reggen/gen_dv.py
+++ b/util/reggen/gen_dv.py
@@ -5,7 +5,7 @@
import logging as log
import os
-from typing import List, Optional, Tuple
+from typing import List
import yaml
@@ -15,7 +15,6 @@
from .ip_block import IpBlock
from .register import Register
-from .top import Top
from .window import Window
@@ -39,15 +38,10 @@
return m.name.lower()
-def sv_base_addr(top: Top, if_name: Tuple[str, Optional[str]]) -> str:
- '''Get the base address of a device interface in SV syntax'''
- return "{}'h{:x}".format(top.regwidth, top.if_addrs[if_name])
-
-
-def _gen_core_file(outdir: str,
- lblock: str,
- dv_base_prefix: str,
- paths: List[str]) -> None:
+def gen_core_file(outdir: str,
+ lblock: str,
+ dv_base_prefix: str,
+ paths: List[str]) -> None:
depends = ["lowrisc:dv:dv_base_reg"]
if dv_base_prefix and dv_base_prefix != "dv_base":
depends.append("lowrisc:dv:{}_reg".format(dv_base_prefix))
@@ -110,31 +104,5 @@
log.error(exceptions.text_error_template().render())
return 1
- _gen_core_file(outdir, lblock, dv_base_prefix, generated)
- return 0
-
-
-def gen_top_dv(top: Top,
- dv_base_prefix: str,
- outdir: str) -> int:
- '''Generate DV RAL model for a Top'''
- # Read template
- lookup = TemplateLookup(directories=[resource_filename('reggen', '.')])
- uvm_reg_tpl = lookup.get_template('top_uvm_reg.sv.tpl')
-
- # Expand template
- try:
- to_write = uvm_reg_tpl.render(top=top,
- dv_base_prefix=dv_base_prefix)
- except: # noqa: E722
- log.error(exceptions.text_error_template().render())
- return 1
-
- # Dump to output file
- dest_path = '{}/chip_ral_pkg.sv'.format(outdir)
- with open(dest_path, 'w') as fout:
- fout.write(to_write)
-
- _gen_core_file(outdir, 'chip', dv_base_prefix, ['chip_ral_pkg.sv'])
-
+ gen_core_file(outdir, lblock, dv_base_prefix, generated)
return 0
diff --git a/util/topgen.py b/util/topgen.py
index 687380b..68b1594 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -20,16 +20,17 @@
from mako.template import Template
import tlgen
-from reggen import access, gen_dv, gen_rtl, window
+from reggen import access, gen_rtl, window
from reggen.inter_signal import InterSignal
from reggen.ip_block import IpBlock
from reggen.lib import check_list
-from reggen.top import Top
from topgen import amend_clocks, get_hjsonobj_xbars
from topgen import intermodule as im
from topgen import lib as lib
from topgen import merge_top, search_ips, validate_top
from topgen.c import TopGenC
+from topgen.gen_dv import gen_dv
+from topgen.top import Top
# Common header for generated files
warnhdr = '''//
@@ -829,7 +830,7 @@
chip = Top(regwidth, name_to_block, inst_to_block, if_addrs, mems, attrs)
# generate the top ral model with template
- return gen_dv.gen_top_dv(chip, dv_base_prefix, str(out_path))
+ return gen_dv(chip, dv_base_prefix, str(out_path))
def _process_top(topcfg, args, cfg_path, out_path, pass_idx):
diff --git a/util/topgen/gen_dv.py b/util/topgen/gen_dv.py
new file mode 100644
index 0000000..5e2beaa
--- /dev/null
+++ b/util/topgen/gen_dv.py
@@ -0,0 +1,46 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+import logging as log
+from typing import Optional, Tuple
+
+from mako import exceptions # type: ignore
+from mako.lookup import TemplateLookup # type: ignore
+from pkg_resources import resource_filename
+
+from reggen.gen_dv import gen_core_file
+
+from .top import Top
+
+
+def sv_base_addr(top: Top, if_name: Tuple[str, Optional[str]]) -> str:
+ '''Get the base address of a device interface in SV syntax'''
+ return "{}'h{:x}".format(top.regwidth, top.if_addrs[if_name])
+
+
+def gen_dv(top: Top,
+ dv_base_prefix: str,
+ outdir: str) -> int:
+ '''Generate DV RAL model for a Top'''
+ # Read template
+ lookup = TemplateLookup(directories=[resource_filename('topgen', '.'),
+ resource_filename('reggen', '.')])
+ uvm_reg_tpl = lookup.get_template('top_uvm_reg.sv.tpl')
+
+ # Expand template
+ try:
+ to_write = uvm_reg_tpl.render(top=top,
+ dv_base_prefix=dv_base_prefix)
+ except: # noqa: E722
+ log.error(exceptions.text_error_template().render())
+ return 1
+
+ # Dump to output file
+ dest_path = '{}/chip_ral_pkg.sv'.format(outdir)
+ with open(dest_path, 'w') as fout:
+ fout.write(to_write)
+
+ gen_core_file(outdir, 'chip', dv_base_prefix, ['chip_ral_pkg.sv'])
+
+ return 0
diff --git a/util/reggen/top.py b/util/topgen/top.py
similarity index 96%
rename from util/reggen/top.py
rename to util/topgen/top.py
index a26dd45..dcdf1ca 100644
--- a/util/reggen/top.py
+++ b/util/topgen/top.py
@@ -6,10 +6,10 @@
from typing import Dict, List, Optional, Tuple, Union
-from .ip_block import IpBlock
-from .params import ReggenParams
-from .reg_block import RegBlock
-from .window import Window
+from reggen.ip_block import IpBlock
+from reggen.params import ReggenParams
+from reggen.reg_block import RegBlock
+from reggen.window import Window
_IFName = Tuple[str, Optional[str]]
_Triple = Tuple[int, str, IpBlock]
diff --git a/util/reggen/top_uvm_reg.sv.tpl b/util/topgen/top_uvm_reg.sv.tpl
similarity index 90%
rename from util/reggen/top_uvm_reg.sv.tpl
rename to util/topgen/top_uvm_reg.sv.tpl
index c8ea5e9..65ad838 100644
--- a/util/reggen/top_uvm_reg.sv.tpl
+++ b/util/topgen/top_uvm_reg.sv.tpl
@@ -4,7 +4,8 @@
// UVM registers auto-generated by `reggen` containing UVM definitions for the entire top-level
<%!
- from reggen import gen_dv
+ from topgen.gen_dv import sv_base_addr
+ from reggen.gen_dv import bcname, mcname, miname
%>
##
## This template is used for chip-wide tests. It expects to be run with the
@@ -78,14 +79,14 @@
esc_if_name = block.name.lower() + if_suffix
if_inst = inst_name + if_suffix
%>\
- rand ${gen_dv.bcname(esc_if_name)} ${if_inst};
+ rand ${bcname(esc_if_name)} ${if_inst};
% endfor
% endfor
% endfor
% if windows:
// memories
% for window in windows:
- rand ${gen_dv.mcname('chip', window)} ${gen_dv.miname(window)};
+ rand ${mcname('chip', window)} ${miname(window)};
% endfor
% endif
@@ -123,16 +124,16 @@
hdl_path = 'tb.dut.top_earlgrey.u_' + inst_name
qual_if_name = (inst_name, if_name)
base_addr = top.if_addrs[qual_if_name]
- sv_base_addr = gen_dv.sv_base_addr(top, qual_if_name)
+ base_addr_txt = sv_base_addr(top, qual_if_name)
%>\
- ${if_inst} = ${gen_dv.bcname(esc_if_name)}::type_id::create("${if_inst}");
+ ${if_inst} = ${bcname(esc_if_name)}::type_id::create("${if_inst}");
${if_inst}.configure(.parent(this));
- ${if_inst}.build(.base_addr(base_addr + ${sv_base_addr}), .csr_excl(csr_excl));
+ ${if_inst}.build(.base_addr(base_addr + ${base_addr_txt}), .csr_excl(csr_excl));
${if_inst}.set_hdl_path_root("${hdl_path}", "BkdrRegPathRtl");
${if_inst}.set_hdl_path_root("${hdl_path}", "BkdrRegPathRtlCommitted");
${if_inst}.set_hdl_path_root("${hdl_path}", "BkdrRegPathRtlShadow");
default_map.add_submap(.child_map(${if_inst}.default_map),
- .offset(base_addr + ${sv_base_addr}));
+ .offset(base_addr + ${base_addr_txt}));
% endfor
% endfor
% endfor