tinyriscv/tools/regtool/topgen/top_uvm_reg.sv.tpl

152 lines
5.3 KiB
Smarty

// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// UVM registers auto-generated by `reggen` containing UVM definitions for the entire top-level
<%!
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
## following arguments
##
## top a Top object
##
## dv_base_prefix a string for the base register type. If it is FOO, then
## we will inherit from FOO_reg (assumed to be a subclass
## of uvm_reg).
##
## Like uvm_reg.sv.tpl, we use functions from uvm_reg_base.sv.tpl to define
## per-device-interface code.
##
<%namespace file="uvm_reg_base.sv.tpl" import="*"/>\
##
##
## Waive the package-filename check: we're going to be defining all sorts of
## packages in a single file.
// verilog_lint: waive-start package-filename
##
## Iterate over the device interfaces of blocks in Top, constructing a package
## for each. Sorting items like this guarantees we'll work alphabetically in
## block name.
% for block_name, block in sorted(top.blocks.items()):
% for if_name, rb in block.reg_blocks.items():
<%
if_suffix = '' if if_name is None else '_' + if_name
esc_if_name = block_name.lower() + if_suffix
if_desc = '' if if_name is None else '; interface {}'.format(if_name)
reg_block_path = 'u_reg' + if_suffix
reg_block_path = reg_block_path if block.hier_path is None else block.hier_path + "." + reg_block_path
%>\
// Block: ${block_name.lower()}${if_desc}
${make_ral_pkg(dv_base_prefix, top.regwidth, reg_block_path, rb, esc_if_name)}
% endfor
% endfor
##
##
## Now that we've made the block-level packages, re-instate the
## package-filename check. The only package left is chip_ral_pkg, which should
## match the generated filename.
// verilog_lint: waive-start package-filename
// Block: chip
package chip_ral_pkg;
<%
if_packages = []
for block_name, block in sorted(top.blocks.items()):
for if_name in block.reg_blocks:
if_suffix = '' if if_name is None else '_' + if_name
if_packages.append('{}{}_ral_pkg'.format(block_name.lower(), if_suffix))
windows = top.window_block.windows
%>\
${make_ral_pkg_hdr(dv_base_prefix, if_packages)}
${make_ral_pkg_fwd_decls('chip', [], windows)}
% for window in windows:
${make_ral_pkg_window_class(dv_base_prefix, 'chip', window)}
% endfor
class chip_reg_block extends ${dv_base_prefix}_reg_block;
// sub blocks
% for block_name, block in sorted(top.blocks.items()):
% for inst_name in top.block_instances[block_name.lower()]:
% for if_name, rb in block.reg_blocks.items():
<%
if_suffix = '' if if_name is None else '_' + if_name
esc_if_name = block_name.lower() + if_suffix
if_inst = inst_name + if_suffix
%>\
rand ${bcname(esc_if_name)} ${if_inst};
% endfor
% endfor
% endfor
% if windows:
// memories
% for window in windows:
rand ${mcname('chip', window)} ${miname(window)};
% endfor
% endif
`uvm_object_utils(chip_reg_block)
function new(string name = "chip_reg_block",
int has_coverage = UVM_NO_COVERAGE);
super.new(name, has_coverage);
endfunction : new
virtual function void build(uvm_reg_addr_t base_addr,
csr_excl_item csr_excl = null);
// create default map
this.default_map = create_map(.name("default_map"),
.base_addr(base_addr),
.n_bytes(${top.regwidth//8}),
.endian(UVM_LITTLE_ENDIAN));
if (csr_excl == null) begin
csr_excl = csr_excl_item::type_id::create("csr_excl");
this.csr_excl = csr_excl;
end
// create sub blocks and add their maps
% for block_name, block in sorted(top.blocks.items()):
% for inst_name in top.block_instances[block_name.lower()]:
% for if_name, rb in block.reg_blocks.items():
<%
if_suffix = '' if if_name is None else '_' + if_name
esc_if_name = block_name.lower() + if_suffix
if_inst = inst_name + if_suffix
if top.attrs.get(inst_name) == 'reggen_only':
hdl_path = 'tb.dut.u_' + inst_name
else:
hdl_path = 'tb.dut.top_earlgrey.u_' + inst_name
qual_if_name = (inst_name, if_name)
base_addr = top.if_addrs[qual_if_name]
base_addr_txt = sv_base_addr(top, qual_if_name)
hpr_indent = (len(if_inst) + len('.set_hdl_path_root(')) * ' '
%>\
${if_inst} = ${bcname(esc_if_name)}::type_id::create("${if_inst}");
${if_inst}.configure(.parent(this));
${if_inst}.build(.base_addr(base_addr + ${base_addr_txt}), .csr_excl(csr_excl));
${if_inst}.set_hdl_path_root("${hdl_path}",
${hpr_indent}"BkdrRegPathRtl");
${if_inst}.set_hdl_path_root("${hdl_path}",
${hpr_indent}"BkdrRegPathRtlCommitted");
${if_inst}.set_hdl_path_root("${hdl_path}",
${hpr_indent}"BkdrRegPathRtlShadow");
default_map.add_submap(.child_map(${if_inst}.default_map),
.offset(base_addr + ${base_addr_txt}));
% endfor
% endfor
% endfor
${make_ral_pkg_window_instances(top.regwidth, 'chip', top.window_block)}
endfunction : build
endclass : chip_reg_block
endpackage