// 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.get_regs_flat()
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.wins:
  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.wins:
<%
  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.wins:
    // memories
% endif
% for w in block.wins:
    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:
      ${r.regwen.lower()}.add_locked_reg(${r.name.lower()});
  % endif
% endfor

% if block.wins:

      // create memories
% endif
% for w in block.wins:
<%
  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
