// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Register Top module auto-generated by `reggen`
<%
  from reggen import gen_rtl
  from reggen.access import HwAccess, SwRdAccess, SwWrAccess
  from reggen.lib import get_basename
  from reggen.register import Register
  from reggen.multi_register import MultiRegister
  from reggen.bits import Bits

  alias_impl = "_" + block.alias_impl if block.alias_impl else ""

  num_wins = len(rb.windows)
  num_reg_dsp = 1 if rb.all_regs else 0
  num_dsp  = num_wins + num_reg_dsp
  regs_flat = rb.flat_regs
  max_regs_char = len("{}".format(len(regs_flat) - 1))
  addr_width = rb.get_addr_width()

  # Used for the dev_select_i signal on a tlul_socket_1n with N =
  # num_wins + 1. This needs to be able to represent any value up to
  # N-1.
  steer_msb = ((num_wins).bit_length()) - 1

  lblock = block.name.lower()
  ublock = lblock.upper()

  u_mod_base = mod_base.upper()

  reg2hw_t = gen_rtl.get_iface_tx_type(block, if_name, False)
  hw2reg_t = gen_rtl.get_iface_tx_type(block, if_name, True)

  win_array_decl = f'  [{num_wins}]' if num_wins > 1 else ''

  # Calculate whether we're going to need an AW parameter. We use it if there
  # are any registers (obviously). We also use it if there are any windows that
  # don't start at zero and end at 1 << addr_width (see the "addr_checks"
  # calculation below for where that comes from).
  needs_aw = (bool(regs_flat) or
              num_wins > 1 or
              rb.windows and (
                rb.windows[0].offset != 0 or
                rb.windows[0].size_in_bytes != (1 << addr_width)))


  common_data_intg_gen = 0 if rb.has_data_intg_passthru else 1
  adapt_data_intg_gen = 1 if rb.has_data_intg_passthru else 0
  assert common_data_intg_gen != adapt_data_intg_gen

  # declare a fully asynchronous interface
  reg_clk_expr = "clk_i"
  reg_rst_expr = "rst_ni"
  tl_h2d_expr = "tl_i"
  tl_d2h_expr = "tl_o"
  if rb.async_if:
    tl_h2d_expr = "tl_async_h2d"
    tl_d2h_expr = "tl_async_d2h"
    for clock in rb.clocks.values():
      reg_clk_expr = clock.clock
      reg_rst_expr = clock.reset

  # A map from "register" (which might be a multiregister) to a pair (r0, srs)
  # where r0 is the prototype register and srs is a list of single registers
  # corresponding to the original register.
  r0_srs = {}

  # A big map from field to "finst names". These names are a pair (fld_pfx,
  # name), where fld_pfx is the name used to index into hw2reg / reg2hw
  # structures (something like "my_reg.my_field") and name is the name that
  # gets prefixed onto local signals (something like "my_reg_my_field").
  finst_names = {}

  for r in rb.all_regs:
    if isinstance(r, MultiRegister):
      r0 = r.reg
      srs = r.regs
    else:
      r0 = r
      srs = [r]

    r0_srs[r] = (r0, srs)

    reg_name = r0.name.lower()
    fld_count = 0
    for sr_idx, sr in enumerate(srs):
      sr_name = sr.name.lower()
      for fidx, field in enumerate(sr.fields):
        if isinstance(r, MultiRegister):
          sig_idx = fld_count if r.is_homogeneous() else sr_idx
          fsig_pfx = '{}[{}]'.format(reg_name, sig_idx)
        else:
          fsig_pfx = reg_name

        fld_count += 1

        fld_name = field.name.lower()
        if len(sr.fields) == 1:
          finst_name = sr_name
          fsig_name = fsig_pfx
        else:
          finst_name = sr_name + '_' + fld_name
          if isinstance(r, MultiRegister):
            if r.is_homogeneous():
              fsig_name = fsig_pfx
            else:
              fsig_name = '{}.{}'.format(fsig_pfx, get_basename(fld_name))
          else:
            fsig_name = '{}.{}'.format(fsig_pfx, fld_name)

        finst_names[field] = (fsig_name, finst_name)

%>
`include "prim_assert.sv"

module ${mod_name} (
  input clk_i,
  input rst_ni,
% if rb.has_internal_shadowed_reg():
  input rst_shadowed_ni,
% endif
% for clock in rb.clocks.values():
  input ${clock.clock},
  input ${clock.reset},
% endfor
  input  tlul_pkg::tl_h2d_t tl_i,
  output tlul_pkg::tl_d2h_t tl_o,
% if num_wins != 0:

  // Output port for window
  output tlul_pkg::tl_h2d_t tl_win_o${win_array_decl},
  input  tlul_pkg::tl_d2h_t tl_win_i${win_array_decl},

% endif
  // To HW
% if rb.get_n_bits(["q","qe","re"]):
  output ${lblock}${alias_impl}_reg_pkg::${reg2hw_t} reg2hw, // Write
% endif
% if rb.get_n_bits(["d","de"]):
  input  ${lblock}${alias_impl}_reg_pkg::${hw2reg_t} hw2reg, // Read
% endif

% if rb.has_internal_shadowed_reg():
  output logic shadowed_storage_err_o,
  output logic shadowed_update_err_o,

%endif
  // Integrity check errors
  output logic intg_err_o,

  // Config
  input devmode_i // If 1, explicit error return for unmapped register access
);

  import ${lblock}${alias_impl}_reg_pkg::* ;

% if needs_aw:
  localparam int AW = ${addr_width};
% endif
% if rb.all_regs:
  localparam int DW = ${block.regwidth};
  localparam int DBW = DW/8;                    // Byte Width

  // register signals
  logic           reg_we;
  logic           reg_re;
  logic [AW-1:0]  reg_addr;
  logic [DW-1:0]  reg_wdata;
  logic [DBW-1:0] reg_be;
  logic [DW-1:0]  reg_rdata;
  logic           reg_error;

  logic          addrmiss, wr_err;

  logic [DW-1:0] reg_rdata_next;
  logic reg_busy;

  tlul_pkg::tl_h2d_t tl_reg_h2d;
  tlul_pkg::tl_d2h_t tl_reg_d2h;
% endif

## The clock and reset inputs aren't used if this device interface has no
## registers, only one window and isn't marked asynchronous. In that case, add
## an unused_ signal to avoid lint warnings.
% if not rb.all_regs and num_wins == 1 and not rb.async_if:
  // Add an unloaded flop to make use of clock / reset
  // This is done to specifically address lint complaints of unused clocks/resets
  // Since the flop is unloaded it will be removed during synthesis
  logic unused_reg;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      unused_reg <= '0;
    end else begin
      unused_reg <= tl_i.a_valid;
    end
  end


% endif
% if rb.async_if:
  tlul_pkg::tl_h2d_t tl_async_h2d;
  tlul_pkg::tl_d2h_t tl_async_d2h;
  tlul_fifo_async #(
    .ReqDepth(2),
    .RspDepth(2)
  ) u_if_sync (
    .clk_h_i(clk_i),
    .rst_h_ni(rst_ni),
    .clk_d_i(${reg_clk_expr}),
    .rst_d_ni(${reg_rst_expr}),
    .tl_h_i(tl_i),
    .tl_h_o(tl_o),
    .tl_d_o(${tl_h2d_expr}),
    .tl_d_i(${tl_d2h_expr})
  );
% endif

% if rb.all_regs:
  // incoming payload check
  logic intg_err;
  tlul_cmd_intg_chk u_chk (
    .tl_i(${tl_h2d_expr}),
    .err_o(intg_err)
  );

  // also check for spurious write enables
  logic reg_we_err;
  ## Note that the write-enables are per register.
  ## Hence, we reduce the byte address to a word address here.
  logic [${len(regs_flat)-1}:0] reg_we_check;
  prim_reg_we_check #(
    .OneHotWidth(${len(regs_flat)})
  ) u_prim_reg_we_check (
    .clk_i(${reg_clk_expr}),
    .rst_ni(${reg_rst_expr}),
    .oh_i  (reg_we_check),
    .en_i  (reg_we && !addrmiss),
    .err_o (reg_we_err)
  );

  logic err_q;
  always_ff @(posedge ${reg_clk_expr} or negedge ${reg_rst_expr}) begin
    if (!${reg_rst_expr}) begin
      err_q <= '0;
    end else if (intg_err || reg_we_err) begin
      err_q <= 1'b1;
    end
  end

  // integrity error output is permanent and should be used for alert generation
  // register errors are transactional
  assign intg_err_o = err_q | intg_err | reg_we_err;
% else:
  // Since there are no registers in this block, commands are routed through to windows which
  // can report their own integrity errors.
  assign intg_err_o = 1'b0;
% endif

  // outgoing integrity generation
  tlul_pkg::tl_d2h_t tl_o_pre;
  tlul_rsp_intg_gen #(
    .EnableRspIntgGen(1),
    .EnableDataIntgGen(${common_data_intg_gen})
  ) u_rsp_intg_gen (
    .tl_i(tl_o_pre),
    .tl_o(${tl_d2h_expr})
  );

% if num_dsp <= 1:
  ## Either no windows (and just registers) or no registers and only
  ## one window.
  % if num_wins == 0:
  assign tl_reg_h2d = ${tl_h2d_expr};
  assign tl_o_pre   = tl_reg_d2h;
  % else:
  assign tl_win_o = ${tl_h2d_expr};
  assign tl_o_pre = tl_win_i;
  % endif
% else:
  tlul_pkg::tl_h2d_t tl_socket_h2d [${num_dsp}];
  tlul_pkg::tl_d2h_t tl_socket_d2h [${num_dsp}];

  logic [${steer_msb}:0] reg_steer;

  // socket_1n connection
  % if rb.all_regs:
  assign tl_reg_h2d = tl_socket_h2d[${num_wins}];
  assign tl_socket_d2h[${num_wins}] = tl_reg_d2h;

  % endif
  % for i,t in enumerate(rb.windows):
<%
      win_suff = f'[{i}]' if num_wins > 1 else ''
%>\
  assign tl_win_o${win_suff} = tl_socket_h2d[${i}];
    % if common_data_intg_gen == 0 and rb.windows[i].data_intg_passthru == False:
    ## If there are multiple windows, and not every window has data integrity
    ## passthrough, we must generate data integrity for it here.
  tlul_rsp_intg_gen #(
    .EnableRspIntgGen(0),
    .EnableDataIntgGen(1)
  ) u_win${i}_data_intg_gen (
    .tl_i(tl_win_i${win_suff}),
    .tl_o(tl_socket_d2h[${i}])
  );
    % else:
  assign tl_socket_d2h[${i}] = tl_win_i${win_suff};
    % endif
  % endfor

  // Create Socket_1n
  tlul_socket_1n #(
    .N            (${num_dsp}),
    .HReqPass     (1'b1),
    .HRspPass     (1'b1),
    .DReqPass     ({${num_dsp}{1'b1}}),
    .DRspPass     ({${num_dsp}{1'b1}}),
    .HReqDepth    (4'h0),
    .HRspDepth    (4'h0),
    .DReqDepth    ({${num_dsp}{4'h0}}),
    .DRspDepth    ({${num_dsp}{4'h0}}),
    .ExplicitErrs (1'b0)
  ) u_socket (
    .clk_i  (${reg_clk_expr}),
    .rst_ni (${reg_rst_expr}),
    .tl_h_i (${tl_h2d_expr}),
    .tl_h_o (tl_o_pre),
    .tl_d_o (tl_socket_h2d),
    .tl_d_i (tl_socket_d2h),
    .dev_select_i (reg_steer)
  );

  // Create steering logic
  always_comb begin
    unique case (${f'{tl_h2d_expr}.a_address[AW-1:0]'}) inside
  % for i,w in enumerate(rb.windows):
<%
      base_addr = w.offset
      limit_addr = w.offset + w.size_in_bytes
      assert (limit_addr-1 >= base_addr)
      addr_test = f"[{base_addr}:{limit_addr-1}]"
%>\
      ${addr_test}: begin
        reg_steer = ${i};
      end
  % endfor
      default: begin
        // Default set to register
        reg_steer = ${num_dsp-1};
      end
    endcase

    // Override this in case of an integrity error
    if (intg_err) begin
      reg_steer = ${num_dsp-1};
    end
  end
% endif
% if rb.all_regs:

  tlul_adapter_reg #(
    .RegAw(AW),
    .RegDw(DW),
    .EnableDataIntgGen(${adapt_data_intg_gen})
  ) u_reg_if (
    .clk_i  (${reg_clk_expr}),
    .rst_ni (${reg_rst_expr}),

    .tl_i (tl_reg_h2d),
    .tl_o (tl_reg_d2h),

    .we_o    (reg_we),
    .re_o    (reg_re),
    .addr_o  (reg_addr),
    .wdata_o (reg_wdata),
    .be_o    (reg_be),
    .busy_i  (reg_busy),
    .rdata_i (reg_rdata),
    .error_i (reg_error)
  );

  % if not rb.async_if:
  // cdc oversampling signals
    % for clock in rb.clocks.values():
  <%
    clk_name = clock.clock_base_name
    tgl_expr = clk_name + "_tgl"
    cname = clock.clock
    rname = clock.reset
  %>\
  logic sync_${clk_name}_update;
  prim_sync_reqack u_${tgl_expr} (
    .clk_src_i(${cname}),
    .rst_src_ni(${rname}),
    .clk_dst_i(${reg_clk_expr}),
    .rst_dst_ni(${reg_rst_expr}),
    .req_chk_i(1'b1),
    .src_req_i(1'b1),
    .src_ack_o(),
    .dst_req_o(sync_${clk_name}_update),
    .dst_ack_i(sync_${clk_name}_update)
  );
    % endfor
  % endif

  % if block.expose_reg_if:
  assign reg2hw.reg_if.reg_we    = reg_we;
  assign reg2hw.reg_if.reg_re    = reg_re;
  assign reg2hw.reg_if.reg_addr  = reg_addr;
  assign reg2hw.reg_if.reg_wdata = reg_wdata;
  assign reg2hw.reg_if.reg_be    = reg_be;

  % endif
  assign reg_rdata = reg_rdata_next ;
  assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;

  // Define SW related signals
  // Format: <reg>_<field>_{wd|we|qs}
  //        or <reg>_{wd|we|qs} if field == 1 or 0
  % for r in regs_flat:
${reg_sig_decl(r)}\
    % for f in r.fields:
<%
        fld_suff = '_' + f.name.lower() if len(r.fields) > 1 else ''
        sig_name = r.name.lower() + fld_suff
%>\
${field_sig_decl(f, sig_name, r.hwext, r.shadowed, r.async_clk)}\
    % endfor
  % endfor
  % if len(rb.clocks.values()) > 0:
  // Define register CDC handling.
  // CDC handling is done on a per-reg instead of per-field boundary.
  % endif
  % for r in regs_flat:
    % if r.async_clk:
<%
  base_name = r.async_clk.clock_base_name
  r_name = r.name.lower()
  src_we_expr = f"{r_name}_we" if r.needs_we() else "'0"
  src_wd_expr = f"reg_wdata[{r.get_width()-1}:0]" if r.needs_we() else "'0"
  src_re_expr = f"{r_name}_re" if r.needs_re() else "'0"
  src_regwen_expr = f"{r.regwen.lower()}_qs" if r.regwen else "'0"
  dst_we_expr = f"{base_name}_{r_name}_we" if r.needs_we() else ""
  dst_wd_expr = f"{base_name}_{r_name}_wdata" if r.needs_we() else ""
  dst_re_expr = f"{base_name}_{r_name}_re" if r.needs_re() else ""
  dst_regwen_expr = f"{base_name}_{r_name}_regwen" if r.regwen else ""
%>
      % if len(r.fields) > 1:
        % for f in r.fields:
          % if f.swaccess.allows_read():
  logic ${str_arr_sv(f.bits)} ${base_name}_${r_name}_${f.name.lower()}_qs_int;
          % endif
        % endfor
      % else:
        % if r.fields[0].swaccess.allows_read():
  logic ${str_arr_sv(r.fields[0].bits)} ${base_name}_${r_name}_qs_int;
        % endif
      % endif
  logic [${r.get_width()-1}:0] ${base_name}_${r_name}_d;
      % if r.needs_we():
  logic [${r.get_width()-1}:0] ${base_name}_${r_name}_wdata;
  logic ${base_name}_${r_name}_we;
  logic unused_${base_name}_${r_name}_wdata;
      % endif
      % if r.needs_re():
  logic ${base_name}_${r_name}_re;
      % endif
      % if r.regwen:
  logic ${base_name}_${r_name}_regwen;
      % endif

  always_comb begin
    ${base_name}_${r_name}_d = '0;
      % if len(r.fields) > 1:
        % for f in r.fields:
          % if f.swaccess.allows_read():
    ${base_name}_${r_name}_d[${str_bits_sv(f.bits)}] = ${base_name}_${r_name}_${f.name.lower()}_qs_int;
          % endif
        % endfor
      % else:
          % if f.swaccess.allows_read():
    ${base_name}_${r_name}_d = ${base_name}_${r_name}_qs_int;
          % endif
      % endif
  end

  prim_reg_cdc #(
    .DataWidth(${r.get_width()}),
    .ResetVal(${r.get_width()}'h${format(r.resval, "x")}),
    .BitMask(${r.get_width()}'h${r.bitmask()})
  ) u_${r_name}_cdc (
    .clk_src_i    (${reg_clk_expr}),
    .rst_src_ni   (${reg_rst_expr}),
    .clk_dst_i    (${r.async_clk.clock}),
    .rst_dst_ni   (${r.async_clk.reset}),
    .src_update_i (sync_${r.async_clk.clock_base_name}_update),
    .src_regwen_i (${src_regwen_expr}),
    .src_we_i     (${src_we_expr}),
    .src_re_i     (${src_re_expr}),
    .src_wd_i     (${src_wd_expr}),
    .src_busy_o   (${r_name}_busy),
    .src_qs_o     (${r_name}_qs), // for software read back
    .dst_d_i      (${base_name}_${r_name}_d),
    .dst_we_o     (${dst_we_expr}),
    .dst_re_o     (${dst_re_expr}),
    .dst_regwen_o (${dst_regwen_expr}),
    .dst_wd_o     (${dst_wd_expr})
  );
      % if r.needs_we():
  assign unused_${base_name}_${r_name}_wdata =
      ^${base_name}_${r_name}_wdata;
      % endif
    % endif
  % endfor

  // Register instances
  % for r in rb.all_regs:
<%
      r0, srs = r0_srs[r]
      reg_name = r0.name.lower()
%>\
    % for sr_idx, sr in enumerate(srs):
<%
        sr_name = sr.name.lower()

        if isinstance(r, MultiRegister):
          reg_hdr = (f'  // Subregister {sr_idx} of Multireg {reg_name}\n' +
                     f'  // R[{sr_name}]: V({sr.hwext})')
        else:
          reg_hdr = (f'  // R[{sr_name}]: V({sr.hwext})')
        clk_expr = sr.async_clk.clock if sr.async_clk else reg_clk_expr
        rst_expr = sr.async_clk.reset if sr.async_clk else reg_rst_expr
%>\
${reg_hdr}
      % if sr.needs_qe():
  logic ${sr_name}_qe;
  logic [${len(sr.fields)-1}:0] ${sr_name}_flds_we;
        % if sr.hwext:
  assign ${sr_name}_qe = &${sr_name}_flds_we;
        % else:
  prim_flop #(
    .Width(1),
    .ResetValue(0)
  ) u_${reg_name}${sr_idx}_qe (
    .clk_i(${clk_expr}),
    .rst_ni(${rst_expr}),
    .d_i(&${sr_name}_flds_we),
    .q_o(${sr_name}_qe)
  );
        % endif
      % endif
<%
  # We usually use the REG_we signal, but use REG_re for RC fields
  # (which get updated on a read, not a write)
  clk_base_name = f"{sr.async_clk.clock_base_name}_" if sr.async_clk else ""
  we_suffix = 're' if field.swaccess.swrd() == SwRdAccess.RC else 'we'
  we_signal = f'{clk_base_name}{sr.name.lower()}_{we_suffix}'

  if sr.async_clk and sr.regwen:
    we_expr = f'{we_signal} & {clk_base_name}{sr.name.lower()}_regwen'
  elif sr.regwen:
    we_expr = f'{we_signal} & {sr.regwen.lower()}_qs'
  else:
    we_expr = we_signal

  we_expr_regwen_gated = f'{clk_base_name}{sr.name.lower()}_gated_{we_suffix}'
%>\
  ## Only create this helper signal if there actually is a REGWEN gate.
  ## Otherwise the WE signal is connected directly to the register.
  % if sr.regwen and sr.needs_we():
  // Create REGWEN-gated WE signal
  logic ${we_expr_regwen_gated};
<%
    # Wrap the assignment if the statement is too long
    assignment = f'assign {we_expr_regwen_gated} = {we_expr};'
    if len(assignment) > 100-2:
      assignment = f'assign {we_expr_regwen_gated} =\n    {we_expr};'
%>\
  ${assignment}
  % endif
      % for fidx, field in enumerate(sr.fields):
<%
          fld_name = field.name.lower()
          fsig_name, finst_name = finst_names[field]
%>\
        % if len(sr.fields) > 1:
  //   F[${fld_name}]: ${field.bits.msb}:${field.bits.lsb}
        % endif
${finst_gen(sr, field, finst_name, fsig_name, fidx)}
      % endfor

    % endfor
  % endfor

  logic [${len(regs_flat)-1}:0] addr_hit;
  always_comb begin
    addr_hit = '0;
    % for i,r in enumerate(regs_flat):
    addr_hit[${"{}".format(i).rjust(max_regs_char)}] = (reg_addr == ${ublock}_${r.name.upper()}_OFFSET);
    % endfor
  end

  assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;

  % if regs_flat:
<%
    # We want to signal wr_err if reg_be (the byte enable signal) is true for
    # any bytes that aren't supported by a register. That's true if a
    # addr_hit[i] and a bit is set in reg_be but not in *_PERMIT[i].

    wr_err_terms = ['(addr_hit[{idx}] & (|({mod}_PERMIT[{idx}] & ~reg_be)))'
                    .format(idx=str(i).rjust(max_regs_char),
                            mod=u_mod_base)
                    for i in range(len(regs_flat))]
    wr_err_expr = (' |\n' + (' ' * 15)).join(wr_err_terms)
%>\
  // Check sub-word write is permitted
  always_comb begin
    wr_err = (reg_we &
              (${wr_err_expr}));
  end
  % else:
  assign wr_error = 1'b0;
  % endif\


  // Generate write-enables
  % for i, r in enumerate(regs_flat):
${reg_enable_gen(r, i)}\
    % if len(r.fields) == 1:
${field_wd_gen(r.fields[0], r.name.lower(), r.hwext, r.shadowed, r.async_clk, r.name, i)}\
    % else:
      % for f in r.fields:
${field_wd_gen(f, r.name.lower() + "_" + f.name.lower(), r.hwext, r.shadowed, r.async_clk, r.name, i)}\
      % endfor
    % endif
  % endfor

  // Assign write-enables to checker logic vector.
  always_comb begin
    reg_we_check = '0;
    % for i, r in enumerate(regs_flat):
<%
    # The WE checking logic does NOT protect RC fields.
    if r.needs_we():
      # In case this is an asynchronous register, the WE signal is taken from
      # the CDC primitive input. This could be enhanced in the future to provide
      # more protection for asynchronous registers.
      if r.async_clk or not r.regwen:
        we_expr = f'{r.name.lower()}_we'
      else:
        we_expr = f'{r.name.lower()}_gated_we'
    else:
      we_expr = "1'b0"

    assignment = f'reg_we_check[{i}] = {we_expr};'

    # Wrap the assignment if the statement is too long
    if len(assignment) > 100-4:
      assignment = f'reg_we_check[{i}] =\n        {we_expr};'
%>\
    ${assignment}
    % endfor
  end

  // Read data return
  always_comb begin
    reg_rdata_next = '0;
    unique case (1'b1)
  % for i, r in enumerate(regs_flat):
    % if r.async_clk:
      addr_hit[${i}]: begin
        reg_rdata_next = DW'(${r.name.lower()}_qs);
      end
    % elif len(r.fields) == 1:
      addr_hit[${i}]: begin
${rdata_gen(r.fields[0], r.name.lower())}\
      end

    % else:
      addr_hit[${i}]: begin
      % for f in r.fields:
${rdata_gen(f, r.name.lower() + "_" + f.name.lower())}\
      % endfor
      end

    % endif
  % endfor
      default: begin
        reg_rdata_next = '1;
      end
    endcase
  end

  // shadow busy
  logic shadow_busy;
  % if rb.has_internal_shadowed_reg():
  logic rst_done;
  logic shadow_rst_done;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      rst_done <= '0;
    end else begin
      rst_done <= 1'b1;
    end
  end

  always_ff @(posedge clk_i or negedge rst_shadowed_ni) begin
    if (!rst_shadowed_ni) begin
      shadow_rst_done <= '0;
    end else begin
      shadow_rst_done <= 1'b1;
    end
  end

  // both shadow and normal resets have been released
  assign shadow_busy = ~(rst_done & shadow_rst_done);
  % else:
  assign shadow_busy = 1'b0;
  % endif

  % if rb.has_internal_shadowed_reg():
  // Collect up storage and update errors
<%
    shadowed_field_pfxs = []
    for r in rb.all_regs:
      r0, srs = r0_srs[r]

      if not (r0.shadowed and not r0.hwext):
        continue

      for sr in srs:
        for field in sr.fields:
          _, pfx = finst_names[field]
          shadowed_field_pfxs.append(pfx)
%>\
  assign shadowed_storage_err_o = |{
  % for pfx in shadowed_field_pfxs:
    ${pfx}_storage_err${"" if loop.last else ","}
  % endfor
  };
  assign shadowed_update_err_o = |{
  % for pfx in shadowed_field_pfxs:
    ${pfx}_update_err${"" if loop.last else ","}
  % endfor
  };

  % endif
  // register busy
<%
  async_busy_signals = {}
  for i, r in enumerate(regs_flat):
    if r.async_clk:
      async_busy_signals[i] = r.name.lower() + "_busy"
%>\
  % if rb.async_if or not async_busy_signals:
  assign reg_busy = shadow_busy;
  % else:
  logic reg_busy_sel;
  assign reg_busy = reg_busy_sel | shadow_busy;
  always_comb begin
    reg_busy_sel = '0;
    unique case (1'b1)
    % for i, busy_signal in async_busy_signals.items():
      addr_hit[${i}]: begin
        reg_busy_sel = ${busy_signal};
      end
    % endfor
      default: begin
        reg_busy_sel  = '0;
      end
    endcase
  end

  % endif
% endif

  // Unused signal tieoff
% if rb.all_regs:

  // wdata / byte enable are not always fully used
  // add a blanket unused statement to handle lint waivers
  logic unused_wdata;
  logic unused_be;
  assign unused_wdata = ^reg_wdata;
  assign unused_be = ^reg_be;
% else:
  // devmode_i is not used if there are no registers
  logic unused_devmode;
  assign unused_devmode = ^devmode_i;
% endif
% if rb.all_regs:

  // Assertions for Register Interface
  `ASSERT_PULSE(wePulse, reg_we, ${reg_clk_expr}, !${reg_rst_expr})
  `ASSERT_PULSE(rePulse, reg_re, ${reg_clk_expr}, !${reg_rst_expr})

  `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, ${reg_clk_expr}, !${reg_rst_expr})

  `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), ${reg_clk_expr}, !${reg_rst_expr})

  // this is formulated as an assumption such that the FPV testbenches do disprove this
  // property by mistake
  //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis)

% endif
endmodule
<%def name="str_bits_sv(bits)">\
% if bits.msb != bits.lsb:
${bits.msb}:${bits.lsb}\
% else:
${bits.msb}\
% endif
</%def>\
<%def name="str_arr_sv(bits)">\
% if bits.msb != bits.lsb:
[${bits.msb-bits.lsb}:0] \
% endif
</%def>\
<%def name="reg_sig_decl(reg)">\
  % if reg.needs_re():
  logic ${reg.name.lower()}_re;
  % endif
  % if reg.needs_we():
  logic ${reg.name.lower()}_we;
  % endif
  % if reg.async_clk:
  logic [${reg.get_width()-1}:0] ${reg.name.lower()}_qs;
  logic ${reg.name.lower()}_busy;
  % endif
</%def>\
<%def name="field_sig_decl(field, sig_name, hwext, shadowed, async_clk)">\
  % if not async_clk and field.swaccess.allows_read():
  logic ${str_arr_sv(field.bits)}${sig_name}_qs;
  % endif
  % if not async_clk and field.swaccess.allows_write():
  logic ${str_arr_sv(field.bits)}${sig_name}_wd;
  % endif
  % if shadowed and not hwext:
  logic ${sig_name}_storage_err;
  logic ${sig_name}_update_err;
  % endif
</%def>\
<%def name="finst_gen(reg, field, finst_name, fsig_name, fidx)">\
<%

    clk_base_name = f"{reg.async_clk.clock_base_name}_" if reg.async_clk else ""
    reg_name = reg.name.lower()
    clk_expr = reg.async_clk.clock if reg.async_clk else reg_clk_expr
    rst_expr = reg.async_clk.reset if reg.async_clk else reg_rst_expr
    re_expr = f'{clk_base_name}{reg_name}_re' if field.swaccess.allows_read() or reg.shadowed else "1'b0"

    # software inputs to field instance, write enable, read enable, write data
    if field.swaccess.allows_write():
      # We usually use the REG_we signal, but use REG_re for RC fields
      # (which get updated on a read, not a write)
      we_suffix = 're' if field.swaccess.swrd() == SwRdAccess.RC else 'we'
      # If this is a REGWEN gated field, need to use the gated WE signal.
      gated_suffix = '_gated' if reg.regwen else ''
      we_expr = f'{clk_base_name}{reg_name}{gated_suffix}_{we_suffix}'

      # when async, pick from the cdc handled data
      wd_expr = f'{finst_name}_wd'
      if reg.async_clk:
        if field.bits.msb == field.bits.lsb:
          bit_sel = f'{field.bits.msb}'
        else:
          bit_sel = f'{field.bits.msb}:{field.bits.lsb}'
        wd_expr = f'{clk_base_name}{reg_name}_wdata[{bit_sel}]'

    else:
      we_expr = "1'b0"
      wd_expr = "'0"

    # hardware inputs to field instance
    if field.hwaccess.allows_write():
      de_expr = f'hw2reg.{fsig_name}.de'
      d_expr = f'hw2reg.{fsig_name}.d'
    else:
      de_expr = "1'b0"
      d_expr = "'0"

    # field instance outputs
    qre_expr = f'reg2hw.{fsig_name}.re' if reg.hwre or reg.shadowed else ""

    if field.hwaccess.allows_read():
      qe_expr = f'{reg_name}_flds_we[{fidx}]' if reg.needs_qe() else ''
      qe_reg_expr = f'reg2hw.{fsig_name}.qe'
      q_expr = f'reg2hw.{fsig_name}.q'
    else:
      qe_expr = ''
      q_expr = ''

    # when async, the outputs are aggregated first by the cdc module
    async_suffix = '_int' if reg.async_clk else ''
    qs_expr = f'{clk_base_name}{finst_name}_qs{async_suffix}' if field.swaccess.allows_read() else ''

%>\
  % if reg.hwext:       ## if hwext, instantiate prim_subreg_ext
<%
    subreg_block = "prim_subreg_ext"
%>\
  ${subreg_block} #(
    .DW    (${field.bits.width()})
  ) u_${finst_name} (
    .re     (${re_expr}),
    .we     (${we_expr}),
    .wd     (${wd_expr}),
    .d      (${d_expr}),
    .qre    (${qre_expr}),
    .qe     (${qe_expr}),
    .q      (${q_expr}),
    .qs     (${qs_expr})
  );
  % else:
<%
      # This isn't a field in a hwext register. Instantiate prim_subreg,
      # prim_subreg_shadow or constant assign.

      resval_expr = f"{field.bits.width()}'h{field.resval or 0:x}"
      is_const_reg = not (field.hwaccess.allows_read() or
                          field.hwaccess.allows_write() or
                          field.swaccess.allows_write() or
                          field.swaccess.swrd() != SwRdAccess.RD)

      subreg_block = 'prim_subreg' + ('_shadow' if reg.shadowed else '')
%>\
    % if is_const_reg:
  // constant-only read
  assign ${finst_name}_qs = ${resval_expr};
    % else:
      % if reg.async_clk and reg.shadowed:
  logic async_${finst_name}_err_update;
  logic async_${finst_name}_err_storage;

  // storage error is persistent and can be sampled at any time
  prim_flop_en #(
    .Width(1),
    .ResetValue('0)
  ) u_${finst_name}_err_storage_sync (
    .clk_i,
    .rst_ni,
    .en_i(sync_${clk_base_name}update),
    .d_i(async_${finst_name}_err_storage),
    .q_o(${finst_name}_storage_err)
  );

  // update error is transient and must be immediately captured
  prim_pulse_sync u_${finst_name}_err_update_sync (
    .clk_src_i(${reg.async_clk.clock}),
    .rst_src_ni(${reg.async_clk.reset}),
    .src_pulse_i(async_${finst_name}_err_update),
    .clk_dst_i(clk_i),
    .rst_dst_ni(rst_ni),
    .dst_pulse_o(${finst_name}_update_err)
  );
      % endif
  ${subreg_block} #(
    .DW      (${field.bits.width()}),
    .SwAccess(prim_subreg_pkg::SwAccess${field.swaccess.value[1].name.upper()}),
    .RESVAL  (${resval_expr})
  ) u_${finst_name} (
    .clk_i   (${clk_expr}),
    .rst_ni  (${rst_expr}),
      % if reg.shadowed and not reg.hwext:
    .rst_shadowed_ni (rst_shadowed_ni),
      % endif

    // from register interface
      % if reg.shadowed:
    .re     (${re_expr}),
      % endif
    .we     (${we_expr}),
    .wd     (${wd_expr}),

    // from internal hardware
    .de     (${de_expr}),
    .d      (${d_expr}),

    // to internal hardware
    .qe     (${qe_expr}),
    .q      (${q_expr}),

    // to register interface (read)
      % if not reg.shadowed:
    .qs     (${qs_expr})
      % else:
    .qs     (${qs_expr}),

    // Shadow register phase. Relevant for hwext only.
    .phase  (),

    // Shadow register error conditions
        % if reg.async_clk:
    .err_update  (async_${finst_name}_err_update),
    .err_storage (async_${finst_name}_err_storage)
        % else:
    .err_update  (${finst_name}_update_err),
    .err_storage (${finst_name}_storage_err)
        % endif
      % endif
  );
    % endif  ## end non-constant prim_subreg
  % endif
  % if field.hwaccess.allows_read() and field.hwqe:
  assign ${qe_reg_expr} = ${reg_name}_qe;
  % endif
</%def>\
<%def name="reg_enable_gen(reg, idx)">\
  % if reg.needs_re():
  assign ${reg.name.lower()}_re = addr_hit[${idx}] & reg_re & !reg_error;
  % endif
  % if reg.needs_we():
  assign ${reg.name.lower()}_we = addr_hit[${idx}] & reg_we & !reg_error;
  % endif
</%def>\
<%def name="field_wd_gen(field, sig_name, hwext, shadowed, async_clk, reg_name, idx)">\
<%
    needs_wd = field.swaccess.allows_write()
    space = '\n' if needs_wd or needs_re else ''
%>\
${space}\
% if needs_wd and not async_clk:
  % if field.swaccess.swrd() == SwRdAccess.RC:
  assign ${sig_name}_wd = '1;
  % else:
  assign ${sig_name}_wd = reg_wdata[${str_bits_sv(field.bits)}];
  % endif
% endif
</%def>\
<%def name="rdata_gen(field, sig_name, rd_name='reg_rdata_next')">\
% if field.swaccess.allows_read():
        ${rd_name}[${str_bits_sv(field.bits)}] = ${sig_name}_qs;
% else:
        ${rd_name}[${str_bits_sv(field.bits)}] = '0;
% endif
</%def>\
<%def name="reg_cdc_gen(field, sig_name, hwext, shadowed, idx)">\
<%
    needs_wd = field.swaccess.allows_write()
    space = '\n' if needs_wd or needs_re else ''
%>\
${space}\
% if needs_wd:
  % if field.swaccess.swrd() == SwRdAccess.RC:
  assign ${sig_name}_wd = '1;
  % else:
  assign ${sig_name}_wd = reg_wdata[${str_bits_sv(field.bits)}];
  % endif
% endif
</%def>\
