152 lines
5.3 KiB
Smarty
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
|