// 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
% for r in block.regs:
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
// Block: ${block.name}
% for r in block.regs:
<%
  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 block.regs:
  // registers
% endif
% for r in block.regs:
  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 block.regs:

    // create registers
% endif
% for r in block.regs:
<%
  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)}
