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

  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
%>
`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}_reg_pkg::${reg2hw_t} reg2hw, // Write
% endif
% if rb.get_n_bits(["d","de"]):
  input  ${lblock}_reg_pkg::${hw2reg_t} hw2reg, // Read
% endif

  // Integrity check errors
  output logic intg_err_o,

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

  import ${lblock}_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)
  );

  logic intg_err_q;
  always_ff @(posedge ${reg_clk_expr} or negedge ${reg_rst_expr}) begin
    if (!${reg_rst_expr}) begin
      intg_err_q <= '0;
    end else if (intg_err) begin
      intg_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 = intg_err_q | intg_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:
<%
      if isinstance(r, MultiRegister):
        r0 = r.reg
        srs = r.regs
      else:
        r0 = r
        srs = [r]

      reg_name = r0.name.lower()
      fld_count = 0
%>\
    % 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})')
%>\
${reg_hdr}
      % for field in 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)
%>\
        % if len(sr.fields) > 1:
  //   F[${fld_name}]: ${field.bits.msb}:${field.bits.lsb}
        % endif
${finst_gen(sr, field, finst_name, fsig_name)}
      % 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\

  % 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

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

  // register busy
  % if rb.async_if:
  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, r in enumerate(regs_flat):
      % if r.async_clk:
      addr_hit[${i}]: begin
        reg_busy_sel = ${r.name.lower() + "_busy"};
      end
      % endif
    % 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
</%def>\
<%def name="finst_gen(reg, field, finst_name, fsig_name)">\
<%

    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'
      we_signal = f'{clk_base_name}{reg_name}_{we_suffix}'

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

      # 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'reg2hw.{fsig_name}.qe' if field.hwqe else ''
      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(reg2hw.${fsig_name}.err_storage)
  );

  // 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(reg2hw.${fsig_name}.err_update)
  );
      % 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  (reg2hw.${fsig_name}.err_update),
    .err_storage (reg2hw.${fsig_name}.err_storage)
        % endif
      % endif
  );
    % endif  ## end non-constant prim_subreg
  % 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_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="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>\
