// 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)}

      // Create functional coverage for comportable IP-specific specialized registers.
      // This function can only be called if it is a root block to get the correct gating condition
      // and avoid creating duplicated cov.
      if (this.get_parent() == null && en_dv_reg_cov) create_cov();
    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}.set_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>\
