// 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;
<%
  clk_lc_found = False;
  for clock in rb.clocks.values():
    if clock.clock == "clk_lc_i":
      clk_lc_found = True;
    endif
  endfor
%>\
% if clk_lc_found:
  always_ff @(posedge clk_lc_i or negedge rst_lc_ni) begin
    if (!rst_lc_ni) begin
% else:
  always_ff @(posedge ${reg_clk_expr} or negedge ${reg_rst_expr}) begin
    if (!${reg_rst_expr}) begin
% endif    
      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
    reg_steer =
  % for i,w in enumerate(rb.windows):
<%
      steer_width = steer_msb + 1
      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}]"
%>\
        ${f'{tl_h2d_expr}.a_address[AW-1:0]'} inside {${addr_test}} ? ${steer_width}'d${i} :
  % endfor
        // Default set to register
        ${steer_width}'d${num_dsp-1};

    // Override this in case of an integrity error
    if (intg_err) begin
      reg_steer = ${steer_width}'d${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),

    .en_ifetch_i(prim_mubi_pkg::MuBi4False),
    .intg_error_o(),

    .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)
  );

  // cdc oversampling signals

  % 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()
  comb_name = f"{base_name}_{r_name}"
  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"{comb_name}_we" if r.needs_we() else ""
  dst_wd_expr = f"{comb_name}_wdata" if r.needs_we() else ""
  dst_re_expr = f"{comb_name}_re" if r.needs_re() else ""
  dst_regwen_expr = f"{comb_name}_regwen" if r.regwen else ""
  dst_qe_expr = f"{comb_name}_qe" if r.is_hw_writable() else "'0"
  dst_wr_req = "1" if r.is_hw_writable() else "0"
  dst_ds_expr = f"{comb_name}_ds" if r.is_hw_writable() else "'0"
  reset_val = format(r.resval, "x")
  reset_val_expr = f"{r.get_width()}'h{reset_val}"
%>
      % if len(r.fields) > 1:
        % for f in r.fields:
          % if r.is_hw_writable():
  logic ${str_arr_sv(f.bits)} ${comb_name}_${f.name.lower()}_ds_int;
          % endif
          % if f.swaccess.allows_read():
  logic ${str_arr_sv(f.bits)} ${comb_name}_${f.name.lower()}_qs_int;
          % endif
        % endfor
      % else:
          % if r.is_hw_writable():
  logic ${str_arr_sv(r.fields[0].bits)} ${comb_name}_ds_int;
          % endif
        % if r.fields[0].swaccess.allows_read():
  logic ${str_arr_sv(r.fields[0].bits)} ${comb_name}_qs_int;
        % endif
      % endif
      % if r.is_hw_writable():
  logic [${r.get_width()-1}:0] ${comb_name}_ds;
  logic ${dst_qe_expr};
      % endif
  logic [${r.get_width()-1}:0] ${comb_name}_qs;
      % if r.needs_we():
  logic [${r.get_width()-1}:0] ${comb_name}_wdata;
  logic ${dst_we_expr};
  logic unused_${comb_name}_wdata;
      % endif
      % if r.needs_re():
  logic ${dst_re_expr};
      % endif
      % if r.regwen:
  logic ${dst_regwen_expr};
      % endif

  ## Since prim_reg_cdc operates at the level of the register, the registers
  ## hw writability is used to determine whether the ds is needed.
  always_comb begin
    ${comb_name}_qs = ${reset_val_expr};
    % if r.is_hw_writable():
    ${comb_name}_ds = ${reset_val_expr};
    % endif
      % if len(r.fields) > 1:
        % for f in r.fields:
          % if r.is_hw_writable() and f.swaccess.allows_read():
    ${comb_name}_ds[${str_bits_sv(f.bits)}] = ${comb_name}_${f.name.lower()}_ds_int;
          % endif
          % if f.swaccess.allows_read():
    ${comb_name}_qs[${str_bits_sv(f.bits)}] = ${comb_name}_${f.name.lower()}_qs_int;
          % endif
        % endfor
      % else:
          % if r.is_hw_writable() and r.fields[0].swaccess.allows_read():
    ${comb_name}_ds = ${comb_name}_ds_int;
          % endif
          % if r.fields[0].swaccess.allows_read():
    ${comb_name}_qs = ${comb_name}_qs_int;
          % endif
      % endif
  end

  prim_reg_cdc #(
    .DataWidth(${r.get_width()}),
    .ResetVal(${reset_val_expr}),
    .BitMask(${r.get_width()}'h${r.bitmask()}),
    .DstWrReq(${dst_wr_req})
  ) 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_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_update_i (${dst_qe_expr}),
    .dst_ds_i     (${dst_ds_expr}),
    .dst_qs_i     (${comb_name}_qs),
    .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_${comb_name}_wdata =
      ^${comb_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;
      % endif
      % if sr.needs_int_qe():
  logic [${len(sr.fields)-1}:0] ${sr_name}_flds_we;
      % endif
      % if sr.needs_qe() and sr.hwext:
  assign ${sr_name}_qe = &${sr_name}_flds_we;
      % elif sr.needs_qe():
  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
<%
  # 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}_{we_suffix}'

  if sr.async_clk and sr.regwen:
    we_expr = f'{we_signal} & {clk_base_name}{sr_name}_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}_gated_{we_suffix}'
%>\
  % if sr.async_clk and sr.is_hw_writable():
  assign ${clk_base_name}${sr_name}_qe = |${sr_name}_flds_we;
  % endif
  ## 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 reg.needs_int_qe() or field.hwaccess.allows_read():
      qe_expr = f'{reg_name}_flds_we[{fidx}]' if reg.needs_int_qe() else ''
    else:
      qe_expr = ''

    if field.hwaccess.allows_read():
      qe_reg_expr = f'reg2hw.{fsig_name}.qe'
      q_expr = f'reg2hw.{fsig_name}.q'
    else:
      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 ''
    ds_expr = f'{clk_base_name}{finst_name}_ds{async_suffix}' if reg.async_clk and reg.is_hw_writable() 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}),
    .ds     (${ds_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_2sync #(
    .Width(1),
    .ResetValue('0)
  ) u_${finst_name}_err_storage_sync (
    .clk_i,
    .rst_ni,
    .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} (
      % if reg.sync_clk:
    // sync clock and reset required for this register
    .clk_i   (${reg.sync_clk.clock}),
    .rst_ni  (${reg.sync_clk.reset}),
      % else:
    .clk_i   (${clk_expr}),
    .rst_ni  (${rst_expr}),
      % endif
      % 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}),
    .ds     (${ds_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>\
