// 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)
%>\
##// [PY-COMMENT]: function to generate typedefs recursively for blocks
<%def name="typedefs(block)">\
% for b in block.blocks:
${typedefs(b)}
% endfor
<%
regs_flat = block.get_regs_flat()
%>\
% 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)};
</%def>\
##// [PY-COMMENT]: function to recursively define all classes
<%def name="construct_classes(block)">\
% for b in block.blocks:
${construct_classes(b)}
% endfor
<%
regs_flat = block.get_regs_flat()
%>\
// Block: ${block.name}
% for r in regs_flat:
<%
  reg_width = block.width
%>\
// Class: ${gen_dv.rcname(block, r)}
class ${gen_dv.rcname(block, r)} extends dv_base_reg;
  // fields
% for f in r.fields:
  rand dv_base_reg_field ${f.name};
% 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();
    // create fields
% for f in r.fields:
<%
  field_size = f.msb - f.lsb + 1
  if f.swaccess.name == "R0W1C":
    field_access = "W1C"
  else:
    field_access = f.swaccess.name

  if f.hwaccess == HwAccess.HRO:
    field_volatile = 0
  else:
    field_volatile = 1
%>\
    ${f.name} = dv_base_reg_field::type_id::create("${f.name}");
    ${f.name}.configure(
      .parent(this),
      .size(${field_size}),
      .lsb_pos(${f.lsb}),
      .access("${field_access}"),
      .volatile(${field_volatile}),
      .reset(${f.resval}),
      .has_reset(1),
      .is_rand(1),
      .individually_accessible(1));
% endfor
  endfunction : build

endclass : ${gen_dv.rcname(block, r)}

% endfor
% for w in block.wins:
<%
  mem_name = w.name.lower()
  mem_right = w.dvrights.upper()
  mem_n_bits = w.n_bits
  mem_size = int((w.limit_addr - w.base_addr) / (mem_n_bits / 8))
%>\
// Class: ${gen_dv.mcname(block, w)}
class ${gen_dv.mcname(block, w)} extends dv_base_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 = "RW"/* TODO:"${mem_right}"*/,
               int              has_coverage = UVM_NO_COVERAGE);
    super.new(name, size, n_bits, access, has_coverage);
  endfunction : new

endclass : ${gen_dv.mcname(block, w)}

% endfor
// Class: ${gen_dv.bcname(block)}
class ${gen_dv.bcname(block)} extends dv_base_reg_block;
% if block.blocks:
  // sub blocks
% endif
% for b in block.blocks:
  rand ${gen_dv.bcname(b)} ${b.name};
% endfor
% if regs_flat:
  // registers
% endif
% for r in regs_flat:
  rand ${gen_dv.rcname(block, r)} ${r.name};
% 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);
    // 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 block.blocks:

    // create sub blocks and add their maps
% endif
% for b in block.blocks:
    ${b.name} = ${gen_dv.bcname(b)}::type_id::create("${b.name}");
    ${b.name}.configure(.parent(this));
    ${b.name}.build(.base_addr(base_addr + ${gen_dv.sv_base_addr(b)}));
    default_map.add_submap(.child_map(${b.name}.default_map),
                           .offset(base_addr + ${gen_dv.sv_base_addr(b)}));
% endfor
% if regs_flat:

    // create registers
% endif
% for r in regs_flat:
<%
  reg_name = r.name
  reg_right = r.dvrights
  reg_width = block.width
  reg_offset =  str(reg_width) + "'h" + "%x" % r.offset
%>\
    ${reg_name} = ${gen_dv.rcname(block, r)}::type_id::create("${reg_name}");
    ${reg_name}.configure(.blk_parent(this));
    ${reg_name}.build();
    default_map.add_reg(.rg(${reg_name}),
                        .offset(${reg_offset}),
                        .rights("${reg_right}"));
% endfor
% if block.wins:

    // create memories
% endif
% for w in block.wins:
<%
  mem_name = w.name.lower()
  mem_right = w.dvrights.upper()
  mem_offset = str(block.width) + "'h" + "%x" % w.base_addr
  mem_n_bits = w.n_bits
  mem_size = int((w.limit_addr - w.base_addr) / (mem_n_bits / 8))
%>\
    ${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)}\
</%def>\

// Forward declare all register/memory/block classes
${typedefs(block)}
${construct_classes(block)}
