// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
<%!
  from reggen import gen_dv
  from reggen.access import HwAccess, SwRdAccess, SwWrAccess
  from reggen.multi_register import MultiRegister
  from reggen.register import Register
  from typing import Dict

  # Get a list reg and its instance name
  # For single reg, return Dict[reg_inst:reg]
  # For multireg, if it's dv_compact, return Dict[mr.name[idx]:mr.reg],
  # if not, return all the mr.regs with their name
  def get_inst_to_reg_dict(r) -> Dict:
    inst_regs = {} # type: Dict[inst_name:Register]
    if isinstance(r, MultiRegister):
      if r.dv_compact:
        inst_base = r.reg.name.lower()
        for idx, reg in enumerate(r.regs):
          inst_name = f'{inst_base}[{idx}]'
          inst_regs[inst_name] = reg
      else:
        for r0 in r.regs:
          inst_regs[r0.name] = r0
    else:
      inst_regs[r.name.lower()] = r
    return inst_regs
%>\
##
##
## make_ral_pkg
## ============
##
## Generate the RAL package for a device interface.
##
##    dv_base_names     a DvBaseNames object that contains register base class names
##
##    reg_width         an integer giving the width of registers in bits
##
##    reg_block_path    the hierarchical path to the relevant register block in the
##                      design
##
##    rb                a RegBlock object
##
##    esc_if_name       a string giving the full, escaped, interface name. For
##                      a device interface called FOO on block BAR,
##                      this will be bar__foo. For an unnamed interface
##                      on block BAR, this will be just bar.
##
<%def name="make_ral_pkg(dv_base_names, reg_width, reg_block_path, rb, esc_if_name)">\
package ${esc_if_name}_ral_pkg;
${make_ral_pkg_hdr(dv_base_names.pkg, [])}

${make_ral_pkg_fwd_decls(esc_if_name, rb.type_regs, rb.windows)}
% for r in rb.all_regs:
<%
    mr = None
    if isinstance(r, MultiRegister):
      mr = r
      if r.dv_compact:
        regs = [r.reg]
      else:
        regs = r.regs
    else:
      regs = [r]
%>\
  % for idx, reg in enumerate(regs):

${make_ral_pkg_reg_class(dv_base_names.reg, dv_base_names.field, reg_width, esc_if_name,
reg_block_path, reg, mr, idx)}
  % endfor
% endfor
% for window in rb.windows:

${make_ral_pkg_window_class(dv_base_names.mem, esc_if_name, window)}
% endfor

<%
  reg_block_name = gen_dv.bcname(esc_if_name)
%>\
  class ${reg_block_name} extends ${dv_base_names.block};
% if rb.flat_regs:
    // registers
  % for r in rb.all_regs:
<%
      # If it's dv_compact, then create it as an array even when it only contains one item
      count = 0
      if isinstance(r, MultiRegister):
        if r.dv_compact:
          regs = [r.reg]
          count = len(r.regs)
        else:
          regs = r.regs
      else:
        regs = [r]
%>\
    % for r0 in regs:
<%
      reg_type = gen_dv.rcname(esc_if_name, r0)
      inst_name = r0.name.lower()
      inst_decl = f'{inst_name}[{count}]' if count > 0 else inst_name
%>\
    rand ${reg_type} ${inst_decl};
      % if r0.alias_target is not None:
<%
        alias_inst_name = r0.alias_target.lower()
        alias_inst_decl = f'{alias_inst_name}[{count}]' if count > 0 else alias_inst_name
%>\
    rand ${reg_type} ${alias_inst_decl}; // aliases to ${inst_decl}
      % endif
    % endfor
  % endfor
% endif
% if rb.windows:
    // memories
% for window in rb.windows:
    rand ${gen_dv.mcname(esc_if_name, window)} ${gen_dv.miname(window)};
% endfor
% endif

    `uvm_object_utils(${reg_block_name})

    function new(string name = "${reg_block_name}",
                 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(${reg_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 rb.flat_regs:
      set_hdl_path_root("tb.dut", "BkdrRegPathRtl");
      set_hdl_path_root("tb.dut", "BkdrRegPathRtlShadow");
      // create registers
  % for r in rb.all_regs:
<%
    r0 = r.reg if isinstance(r, MultiRegister) else r
    reg_type = gen_dv.rcname(esc_if_name, r0)
%>\
    % if isinstance(r, MultiRegister):
      % for idx, reg in enumerate(r.regs):
<%
        if r.dv_compact:
          inst_base = r0.name.lower()
          inst_name = f'{inst_base}[{idx}]'
          if r0.alias_target is not None:
            alias_inst_base = r0.alias_target.lower()
            alias_inst_name = f'{alias_inst_base}[{idx}]'
        else:
          inst_name = reg.name.lower()
          reg_type = gen_dv.rcname(esc_if_name, reg)
          if r0.alias_target is not None:
            alias_inst_name = reg.alias_target.lower()
%>\
${instantiate_register(reg_width, reg_block_path, reg, reg_type, inst_name)}\
        % if reg.alias_target is not None:
      // Assign alias register to generic handle.
      ${alias_inst_name} = ${inst_name};
        % endif
      % endfor
    % else:
${instantiate_register(reg_width, reg_block_path, r, reg_type, r.name.lower())}\
    % endif
    % if r0.alias_target is not None:
<%
    inst_name = r0.name.lower()
    alias_inst_name = r0.alias_target.lower()
%>\
      // Assign alias register to generic handle.
      ${alias_inst_name} = ${inst_name};
    % endif
  % endfor
<%
  any_regwen = False
  for r in rb.flat_regs:
    if r.regwen:
      any_regwen = True
      break
%>\
  % if any_regwen:
      // assign locked reg to its regwen reg
    % for r in rb.all_regs:
      % for inst, reg in get_inst_to_reg_dict(r).items():
${apply_regwen(rb, reg, inst)}\
      % endfor
    % endfor
  % endif
% endif
${make_ral_pkg_window_instances(reg_width, esc_if_name, rb)}
    endfunction : build
  endclass : ${reg_block_name}

endpackage
</%def>\
##
##
## make_ral_pkg_hdr
## ================
##
## Generate the header for a RAL package
##
##    dv_base_reg_pkg_name   a string name for the base reg_pkg type
##
##    deps                   a list of names for packages that should be explicitly
##                           imported
##
<%def name="make_ral_pkg_hdr(dv_base_reg_pkg_name, deps)">\
  // dep packages
  import uvm_pkg::*;
  import dv_base_reg_pkg::*;
% if dv_base_reg_pkg_name != "dv_base_reg_pkg":
  import ${dv_base_reg_pkg_name}::*;
% endif
% for dep in deps:
  import ${dep}::*;
% endfor

  // macro includes
  `include "uvm_macros.svh"\
</%def>\
##
##
## make_ral_pkg_fwd_decls
## ======================
##
## Generate the forward declarations for a RAL package
##
##    esc_if_name      as for make_ral_pkg
##
##    type_regs        a list of Register objects, one for each type that
##                     should be defined. Each MultiRegister will contribute
##                     just one register to the list.
##
##    windows          a list of Window objects
##
<%def name="make_ral_pkg_fwd_decls(esc_if_name, type_regs, windows)">\
  // Forward declare all register/memory/block classes
% for r in type_regs:
  typedef class ${gen_dv.rcname(esc_if_name, r)};
% endfor
% for w in windows:
  typedef class ${gen_dv.mcname(esc_if_name, w)};
% endfor
  typedef class ${gen_dv.bcname(esc_if_name)};\
</%def>\
##
##
## make_ral_pkg_reg_class
## ======================
##
## Generate the classes for a register inside a RAL package
##
##    dv_base_reg_name     a string name for the base register type
##
##    dv_base_field_name   a string name for the base reg_field type
##
##    reg_width            as for make_ral_pkg
##
##    esc_if_name          as for make_ral_pkg
##
##    reg_block_path       as for make_ral_pkg
##
##    reg                  a Register object
##
##    mr                   a MultiRegister object if this reg is from a MultiRegister
##
##    reg_idx              the index location of this reg if this reg is from a MultiRegister,
##                         or zero if not
<%def name="make_ral_pkg_reg_class(dv_base_reg_name, dv_base_field_name, reg_width, esc_if_name,
reg_block_path, reg, mr, reg_idx)">\
<%
  reg_name = reg.name.lower()

  is_ext = reg.hwext
  for field in reg.fields:
    if (field.hwaccess.value[1] == HwAccess.NONE and
        field.swaccess.swrd() == SwRdAccess.RD and
        not field.swaccess.allows_write()):
      is_ext = 1

  class_name = gen_dv.rcname(esc_if_name, reg)
  alias_class_name = gen_dv.alias_rcname(esc_if_name, reg)
%>\
  class ${class_name} extends ${dv_base_reg_name};
    // fields
<%
  suffix = ""
  start_idx = 0
  add_style_waive = False
  compact_field_inst_name = ""
  compact_alias_field_inst_name = ""

  if mr is None:
      fields = reg.fields
  else:
    if not mr.compact:
      fields = mr.reg.fields
    else:
      fields = mr.regs[reg_idx].fields
      compact_field_inst_name = mr.reg.fields[0].name.lower()
      compact_alias_field_inst_name = mr.reg.fields[0].alias_target
      if mr.dv_compact:
        # The dv_compact flag means that the fields of the multi-reg divide equally into registers.
        # In this case, there's an array of registers and make_ral_pkg_reg_class() gets called once
        # to define that array's type, using the fields of the first register in the replication.
        assert reg_idx == 0
        if len(fields) > 1:
          suffix = f'[{len(fields)}]'
      else:
        # In this case, the multi-register is "compact", so there might be multiple copies of its
        # single field in each generated register. But dv_compact is false, which probably means
        # that the fields didn't divide equally into a whole number of registers. In this case, we
        # are generating a different class for each output register and should spit out fields
        # accordingly. Note that we generate an array, even if len(fields) = 1. If that happens, we
        # know we're on the last generated register, so want to keep everything uniform.
        num_fields_per_reg = 32 // fields[0].bits.width()
        start_idx = num_fields_per_reg * reg_idx
        end_idx = start_idx + len(fields) - 1
        suffix = f'[{start_idx}:{end_idx}]'
        if start_idx == 0:
          add_style_waive = True
%>\
% if add_style_waive:
    // verilog_lint: waive unpacked-dimensions-range-ordering
% endif
% if compact_field_inst_name:
    rand ${dv_base_field_name} ${compact_field_inst_name}${suffix};
%     if compact_alias_field_inst_name:
    rand ${dv_base_field_name} ${compact_alias_field_inst_name.lower()}${suffix};
%     endif
% else:
%   for f in fields:
    rand ${dv_base_field_name} ${f.name.lower()};
%     if f.alias_target is not None:
    rand ${dv_base_field_name} ${f.alias_target.lower()}; // aliases to ${f.name.lower()}
%     endif
%   endfor
% endif

    `uvm_object_utils(${class_name})

    function new(string       name = "${class_name}",
                 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);
% if alias_class_name is not None:
      set_alias_name("${alias_class_name}");
% endif\
      // create fields
% for idx, field in enumerate(fields):
<%
    alias_reg_field_name = ""
    if compact_field_inst_name:
      reg_field_name = compact_field_inst_name
      if compact_alias_field_inst_name:
        alias_reg_field_name = compact_alias_field_inst_name
      # If len(fields) > 1, we define generated reg fields as an array and we need an index to
      # refer to the field object
      # If start_idx > 0, the fields cross more than one register, we define an array for the
      # fields even when the last register only contains one field.
      if len(fields) > 1 or start_idx > 0:
        reg_field_name = reg_field_name + f'[{idx + start_idx}]'
        if compact_alias_field_inst_name:
          alias_reg_field_name = alias_reg_field_name + f'[{idx + start_idx}]'
    else:
      reg_field_name = field.name.lower()
      if field.alias_target is not None:
        alias_reg_field_name = field.alias_target.lower()
%>\
${_create_reg_field(dv_base_field_name, reg_width, reg_block_path, reg.shadowed, reg.hwext,
reg_field_name, field)}\
  % if field.alias_target is not None:
      ${alias_reg_field_name} = ${reg_field_name}; // assign to generic handle
  % endif
% endfor
% if is_ext:
      set_is_ext_reg(1);
% endif
    endfunction : build
  endclass : ${class_name}\
</%def>\
##
##
## _create_reg_field
## =================
##
## Generate the code that creates a uvm_reg_field object for a field
## in a register.
##
##    dv_base_reg_field_name   as for make_ral_pkg_reg_class
##
##    reg_width                as for make_ral_pkg
##
##    reg_block_path           as for make_ral_pkg
##
##    shadowed                 true if the field's register is shadowed
##
##    hwext                    true if the field's register is hwext
##
##    reg_field_name           a string with the name to give the field in the HDL
##
##    field                    a Field object
<%def name="_create_reg_field(dv_base_reg_field_name, reg_width, reg_block_path, shadowed, hwext,
reg_field_name, field)">\
<%
  field_size = field.bits.width()
  field_access = field.swaccess.dv_rights()

  if not field.hwaccess.allows_write():
    field_volatile = 0
  else:
    field_volatile = 1
  field_tags = field.tags

  fname = reg_field_name
  type_id_indent = ' ' * (len(fname) + 4)
%>\
      ${fname} = (${dv_base_reg_field_name}::
      ${type_id_indent}type_id::create("${field.name.lower()}"));
      ${fname}.configure(
        .parent(this),
        .size(${field_size}),
        .lsb_pos(${field.bits.lsb}),
        .access("${field_access}"),
        .volatile(${field_volatile}),
        .reset(${reg_width}'h${format(field.resval or 0, 'x')}),
        .has_reset(1),
        .is_rand(1),
        .individually_accessible(1));

% if field.alias_target is not None:
      ${fname}.set_alias_name("${field.alias_target.lower()}");
% endif
      ${fname}.set_original_access("${field_access}");
% if field.mubi:
      ${fname}.create_mubi_cov(.mubi_width(${field_size}));
% 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(${fname}.get_full_name(), ${tag[2]}, ${tag[1]});
%       endif
%     endfor
%   endif
</%def>\
##
##
## make_ral_pkg_window_class
## =========================
##
## Generate the classes for a window inside a RAL package
##
##    dv_base_window_name   a string name for the base windoe type
##
##    esc_if_name           as for make_ral_pkg
##
##    window                a Window object
<%def name="make_ral_pkg_window_class(dv_base_window_name, esc_if_name, window)">\
<%
  mem_name = window.name.lower()
  mem_right = window.swaccess.dv_rights()
  mem_n_bits = window.validbits
  mem_size = window.items

  class_name = gen_dv.mcname(esc_if_name, window)
%>\
  class ${class_name} extends ${dv_base_window_name};

    `uvm_object_utils(${class_name})

    function new(string           name = "${class_name}",
                 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 window.byte_write:
      set_mem_partial_write_support(1);
%     endif
%     if window.data_intg_passthru:
      set_data_intg_passthru(1);
%     endif
    endfunction : new

  endclass : ${class_name}
</%def>\
##
##
## make_ral_pkg_window_instances
## =============================
##
## Generate the classes for a window inside a RAL package
##
##    reg_width        as for make_ral_pkg
##
##    esc_if_name      as for make_ral_pkg
##
##    rb               a RegBlock object
##
<%def name="make_ral_pkg_window_instances(reg_width, esc_if_name, rb)">\
% if rb.windows:

      // create memories
%  for w in rb.windows:
<%
      mem_name = w.name.lower()
      mem_right = w.swaccess.dv_rights()
      mem_offset = "{}'h{:x}".format(reg_width, w.offset)
      mem_n_bits = w.validbits
      mem_size = w.items
%>\
      ${mem_name} =
          ${gen_dv.mcname(esc_if_name, 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
% endif
</%def>\
##
##
## instantiate_register
## ====================
##
## Actually instantiate a register in a register block
##
##    reg_width        an integer giving the width of registers in bits
##
##    reg_block_path   as for make_ral_pkg
##
##    reg              the Register to instantiate
##
##    reg_type         a string giving the type name (a subclass of
##                     uvm_register) to instantiate.
##
##    reg_inst         a string giving the field of the uvm_reg_block that
##                     should be set to this new register. For single
##                     registers, this will just be the register name. For
##                     elements of multi-registers, it will be the name of an
##                     array item.
##
<%def name="instantiate_register(reg_width, reg_block_path, reg, reg_type, reg_inst)">\
<%
      reg_name = reg.name.lower()
      reg_offset = "{}'h{:x}".format(reg_width, reg.offset)

      inst_id_indent = ' ' * (len(reg_inst) + 4)
%>\
      ${reg_inst} = (${reg_type}::
      ${inst_id_indent}type_id::create("${reg_name}"));
      ${reg_inst}.configure(.blk_parent(this));
      ${reg_inst}.build(csr_excl);
      default_map.add_reg(.rg(${reg_inst}),
                          .offset(${reg_offset}));
% if reg.shadowed:
      % if reg.update_err_alert:
      ${reg_inst}.add_update_err_alert("${reg.update_err_alert}");
      % endif

      % if reg.storage_err_alert:
      ${reg_inst}.add_storage_err_alert("${reg.storage_err_alert}");
      % endif

  % if reg.hwext:
    % for field in reg.fields:
<%
      shadowed_reg_path = ''
      for tag in field.tags:
        parts = tag.split(':')
        if parts[0] == 'shadowed_reg_path':
          shadowed_reg_path = parts[1]

      if not shadowed_reg_path:
        print("ERROR: ext shadow_reg does not have tags for shadowed_reg_path for each field!")
        assert 0
%>\
      ${reg_inst}.add_hdl_path_slice(
          "${shadowed_reg_path}.committed_reg.q",
          ${field.bits.lsb}, ${field.bits.width()}, 0, "BkdrRegPathRtl");
      ${reg_inst}.add_hdl_path_slice(
          "${shadowed_reg_path}.shadow_reg.q",
          ${field.bits.lsb}, ${field.bits.width()}, 0, "BkdrRegPathRtlShadow");
    % endfor
  % endif
% endif
% for field in reg.fields:
<%
    field_size = field.bits.width()
    if len(reg.fields) == 1:
      reg_field_name = reg_name
    else:
      reg_field_name = reg_name + "_" + field.name.lower()

    ##if reg.async_name and not reg.hwext:
    ##  reg_field_name += ".u_subreg"
%>\
%   if ((field.hwaccess.value[1] == HwAccess.NONE and\
       field.swaccess.swrd() == SwRdAccess.RD and\
       not field.swaccess.allows_write())):
      // constant reg
      ${reg_inst}.add_hdl_path_slice(
          "${reg_block_path}.${reg_field_name}_qs",
          ${field.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtl");
%   elif not reg.shadowed:
      ${reg_inst}.add_hdl_path_slice(
          "${reg_block_path}.u_${reg_field_name}.q${"s" if reg.hwext else ""}",
          ${field.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtl");
%   endif
%   if reg.shadowed and not reg.hwext:
      ${reg_inst}.add_hdl_path_slice(
          "${reg_block_path}.u_${reg_field_name}.committed_reg.q",
          ${field.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtl");
      ${reg_inst}.add_hdl_path_slice(
          "${reg_block_path}.u_${reg_field_name}.shadow_reg.q",
          ${field.bits.lsb}, ${field_size}, 0, "BkdrRegPathRtlShadow");
%   endif
% endfor

%     if reg.shadowed:
      ${reg_inst}.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_inst}.get_full_name(), ${tag[2]}, ${tag[1]});
%         endif
%       endfor
%     endif
</%def>\
##
##
## apply_regwen
## ============
##
## Apply a regwen to a register
##
##    rb               the register block
##
##    reg              the Register that needs apply regwens
##
##    reg_inst         a string giving the field of the uvm_reg_block that
##                     should be updated. For single registers, this will just
##                     be the register name. For elements of multi-registers,
##                     it will be the name of an array item.
##
<%def name="apply_regwen(rb, reg, reg_inst)">\
% if reg.regwen is None:
<% return "" %>\
% endif
% for wen in rb.all_regs:
%   for wen_inst, wen_reg in get_inst_to_reg_dict(wen).items():
%     if reg.regwen.lower() == wen_reg.name.lower():
      ${wen_inst}.add_lockable_reg_or_fld(${reg_inst});
<% return "" %>\
%     elif wen_reg.name.lower() in reg.regwen.lower():
%       for field in wen_reg.get_field_list():
%         if reg.regwen.lower() == (wen_reg.name.lower() + "_" + field.name.lower()):
      ${wen_inst}.${field.name.lower()}.add_lockable_reg_or_fld(${reg_inst});
<% return "" %>\
%         endif
%       endfor
%     endif
%   endfor
% endfor
</%def>\
