blob: a4d932ba730f6631ad428e6826427e775cf63a0f [file] [log] [blame]
// 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 data structure
// Do Not Edit directly
<% from reggen import (gen_dv)
%>\
<%def name="construct_classes(block)">\
% for b in block.blocks:
${construct_classes(b)}
% endfor
<%
regs_flat = block.reg_block.flat_regs
hier_path = ""
if (block.hier_path):
hier_path = block.hier_path + "."
%>\
// Block: ${block.name}
package ${block.name}_ral_pkg;
// dep packages
import uvm_pkg::*;
import dv_base_reg_pkg::*;
% if dv_base_prefix != "dv_base":
import ${dv_base_prefix}_reg_pkg::*;
% endif
% for b in block.blocks:
import ${b.name}_ral_pkg::*;
% endfor
// macro includes
`include "uvm_macros.svh"
// Forward declare all register/memory/block classes
% for r in regs_flat:
typedef class ${gen_dv.rcname(block, r)};
% endfor
% for w in block.reg_block.windows:
typedef class ${gen_dv.mcname(block, w)};
% endfor
typedef class ${gen_dv.bcname(block)};
% for r in regs_flat:
<%
reg_width = block.width
reg_name = r.name.lower()
is_ext = 0
reg_shadowed = r.shadowed
%>\
// Class: ${gen_dv.rcname(block, r)}
class ${gen_dv.rcname(block, r)} extends ${dv_base_prefix}_reg;
// fields
% for f in r.fields:
rand ${dv_base_prefix}_reg_field ${f.name.lower()};
% endfor
`uvm_object_utils(${gen_dv.rcname(block, r)})
function new(string name = "${gen_dv.rcname(block, r)}",
int unsigned n_bits = ${reg_width},
int has_coverage = UVM_NO_COVERAGE);
super.new(name, n_bits, has_coverage);
endfunction : new
virtual function void build(csr_excl_item csr_excl = null);
// create fields
% for f in r.fields:
<%
field_size = f.bits.width()
if f.swaccess.key == "r0w1c":
field_access = "W1C"
else:
field_access = f.swaccess.value[1].name
if not f.hwaccess.allows_write():
field_volatile = 0
else:
field_volatile = 1
field_tags = f.tags
if r.hwext or (f.hwaccess.value[1] == HwAccess.NONE and
f.swaccess.swrd() == SwRdAccess.RD and
not f.swaccess.allows_write()):
is_ext = 1
fname = f.name.lower()
if len(r.fields) == 1:
reg_field_name = reg_name
else:
reg_field_name = reg_name + "_" + fname
%>\
${fname} = ${dv_base_prefix}_reg_field::type_id::create("${fname}");
${fname}.configure(
.parent(this),
.size(${field_size}),
.lsb_pos(${f.bits.lsb}),
.access("${field_access}"),
.volatile(${field_volatile}),
.reset(${reg_width}'h${format(f.resval or 0, 'x')}),
.has_reset(1),
.is_rand(1),
.individually_accessible(1));
${fname}.set_original_access("${field_access}");
% if ((f.hwaccess.value[1] == HwAccess.NONE and\
f.swaccess.swrd() == SwRdAccess.RD and\
not f.swaccess.allows_write())):
// constant reg
add_hdl_path_slice("${hier_path}u_reg.${reg_field_name}_qs", ${f.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtl");
% else:
add_hdl_path_slice("${hier_path}u_reg.u_${reg_field_name}.q${"s" if r.hwext else ""}", ${f.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtl");
% endif
% if reg_shadowed and not r.hwext:
add_hdl_path_slice("${hier_path}u_reg.u_${reg_field_name}.committed_reg.q", ${f.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtlCommitted");
add_hdl_path_slice("${hier_path}u_reg.u_${reg_field_name}.shadow_reg.q", ${f.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtlShadow");
% endif
% if field_tags:
// create field tags
% for field_tag in field_tags:
<%
tag = field_tag.split(":")
%>\
% if tag[0] == "excl":
csr_excl.add_excl(${f.name.lower()}.get_full_name(), ${tag[2]}, ${tag[1]});
% endif
% endfor
% endif
% endfor
% if reg_shadowed and r.hwext:
add_update_err_alert("${r.update_err_alert}");
add_storage_err_alert("${r.storage_err_alert}");
<% shadowed_reg_path = "" %>\
% for r_tag in r.tags:
<% tag = r_tag.split(":") %>\
% if tag[0] == "shadowed_reg_path":
<% shadowed_reg_path = tag[1] %>\
% endif
% endfor
% if shadowed_reg_path == "":
print("ERROR: ext shadow_reg does not have tags for shadowed_reg_path!")
% else:
add_hdl_path_slice("${shadowed_reg_path}.committed_reg.q", 0, (${f.bits.lsb} + ${field_size}), 0, "BkdrRegPathRtlCommitted");
add_hdl_path_slice("${shadowed_reg_path}.shadow_reg.q", 0, (${f.bits.lsb} + ${field_size}), 0, "BkdrRegPathRtlShadow");
% endif
% endif
% if is_ext:
set_is_ext_reg(1);
% endif
endfunction : build
endclass : ${gen_dv.rcname(block, r)}
% endfor
% for w in block.reg_block.windows:
<%
mem_name = w.name.lower()
mem_right = w.swaccess.dv_rights()
mem_n_bits = w.validbits
mem_size = w.items
%>\
// Class: ${gen_dv.mcname(block, w)}
class ${gen_dv.mcname(block, w)} extends ${dv_base_prefix}_mem;
`uvm_object_utils(${gen_dv.mcname(block, w)})
function new(string name = "${gen_dv.mcname(block, w)}",
longint unsigned size = ${mem_size},
int unsigned n_bits = ${mem_n_bits},
string access = "${mem_right}",
int has_coverage = UVM_NO_COVERAGE);
super.new(name, size, n_bits, access, has_coverage);
% if w.byte_write:
set_mem_partial_write_support(1);
% endif
endfunction : new
endclass : ${gen_dv.mcname(block, w)}
% endfor
// Class: ${gen_dv.bcname(block)}
class ${gen_dv.bcname(block)} extends ${dv_base_prefix}_reg_block;
% if block.blocks:
// sub blocks
% endif
% for b in block.blocks:
% for inst in b.base_addr.keys():
rand ${gen_dv.bcname(b)} ${inst};
% endfor
% endfor
% if regs_flat:
// registers
% endif
% for r in regs_flat:
rand ${gen_dv.rcname(block, r)} ${r.name.lower()};
% endfor
% if block.reg_block.windows:
// memories
% endif
% for w in block.reg_block.windows:
rand ${gen_dv.mcname(block, w)} ${gen_dv.miname(w)};
% endfor
`uvm_object_utils(${gen_dv.bcname(block)})
function new(string name = "${gen_dv.bcname(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(${block.width//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
% if block.blocks:
// create sub blocks and add their maps
% endif
% for b in block.blocks:
% 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");
set_hdl_path_root("tb.dut", "BkdrRegPathRtlCommitted");
set_hdl_path_root("tb.dut", "BkdrRegPathRtlShadow");
// create registers
% endif
% for r in regs_flat:
<%
reg_name = r.name.lower()
reg_right = r.dv_rights()
reg_width = block.width
reg_offset = str(reg_width) + "'h" + "%x" % r.offset
reg_tags = r.tags
reg_shadowed = r.shadowed
%>\
${reg_name} = ${gen_dv.rcname(block, r)}::type_id::create("${reg_name}");
${reg_name}.configure(.blk_parent(this));
${reg_name}.build(csr_excl);
default_map.add_reg(.rg(${reg_name}),
.offset(${reg_offset}),
.rights("${reg_right}"));
% if reg_shadowed:
${reg_name}.set_is_shadowed();
% endif
% if reg_tags:
// create register tags
% for reg_tag in reg_tags:
<%
tag = reg_tag.split(":")
%>\
% if tag[0] == "excl":
csr_excl.add_excl(${reg_name}.get_full_name(), ${tag[2]}, ${tag[1]});
% endif
% endfor
% endif
% endfor
// assign locked reg to its regwen reg
% for r in regs_flat:
% if r.regwen:
% for reg in regs_flat:
% if r.regwen.lower() == reg.name.lower():
${r.regwen.lower()}.add_lockable_reg_or_fld(${r.name.lower()});
<% break %>\
% elif reg.name.lower() in r.regwen.lower():
% for field in reg.get_field_list():
% if r.regwen.lower() == (reg.name.lower() + "_" + field.name.lower()):
${r.regwen.lower()}.${field.name.lower()}.add_lockable_reg_or_fld(${r.name.lower()});
<% break %>\
% endif
% endfor
% endif
% endfor
% endif
% endfor
% if block.reg_block.windows:
// create memories
% endif
% for w in block.reg_block.windows:
<%
mem_name = w.name.lower()
mem_right = w.swaccess.dv_rights()
mem_offset = str(block.width) + "'h" + "%x" % w.offset
mem_n_bits = w.validbits
mem_size = w.items
%>\
${mem_name} = ${gen_dv.mcname(block, w)}::type_id::create("${mem_name}");
${mem_name}.configure(.parent(this));
default_map.add_mem(.mem(${mem_name}),
.offset(${mem_offset}),
.rights("${mem_right}"));
% endfor
endfunction : build
endclass : ${gen_dv.bcname(block)}
endpackage\
</%def>\
// verilog_lint: waive-start package-filename
${construct_classes(block)}
// verilog_lint: waive-stop package-filename