[top] Align FPGA, Verilator and DV tops

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/top_earlgrey/data/clocks.xdc b/hw/top_earlgrey/data/clocks.xdc
index 2c6c90b..c82c5cf 100644
--- a/hw/top_earlgrey/data/clocks.xdc
+++ b/hw/top_earlgrey/data/clocks.xdc
@@ -22,8 +22,10 @@
 create_generated_clock -name clk_io_div4 -source [get_pin ${u_pll}/CLKOUT0] -divide_by 4 [get_pin ${u_div4}/u_clk_div_buf/gen_xilinx.u_impl_xilinx/bufg_i/O]
 
 ## JTAG and SPI clocks
-create_clock -add -name jtag_tck    -period 100.00 -waveform {0 5} [get_nets jtag_tck_buf]
+create_clock -add -name lc_jtag_tck -period 100.00 -waveform {0 5} [get_pin top_*/u_pinmux_aon/u_pinmux_strap_sampling/u_pinmux_jtag_buf_lc/prim_clock_buf_tck/gen_xilinx.u_impl_xilinx/bufg_i/O]
+create_clock -add -name rv_jtag_tck -period 100.00 -waveform {0 5} [get_pin top_*/u_pinmux_aon/u_pinmux_strap_sampling/u_pinmux_jtag_buf_rv/prim_clock_buf_tck/gen_xilinx.u_impl_xilinx/bufg_i/O]
 create_clock -add -name clk_spi_in  -period 100.00 -waveform {0 5} [get_pin top_*/u_spi_device/u_clk_spi_in_buf/gen_xilinx.u_impl_xilinx/bufg_i/O]
 create_clock -add -name clk_spi_out -period 100.00 -waveform {0 5} [get_pin top_*/u_spi_device/u_clk_spi_out_buf/gen_xilinx.u_impl_xilinx/bufg_i/O]
 
-set_clock_groups -group ${clks_10_unbuf} -group ${clks_48_unbuf} -group ${clks_aon_unbuf} -group clk_io_div2 -group clk_io_div4 -group jtag_tck -group clk_spi_in -group clk_spi_out -asynchronous
+set_clock_groups -group ${clks_10_unbuf} -group ${clks_48_unbuf} -group ${clks_aon_unbuf} -group clk_io_div2 -group clk_io_div4 -group lc_jtag_tck -group rv_jtag_tck -group clk_spi_in -group clk_spi_out -asynchronous
+
diff --git a/hw/top_earlgrey/dv/tb/tb.sv b/hw/top_earlgrey/dv/tb/tb.sv
index 6f630f7..fe596a8 100644
--- a/hw/top_earlgrey/dv/tb/tb.sv
+++ b/hw/top_earlgrey/dv/tb/tb.sv
@@ -128,10 +128,10 @@
     .IOC2(tie_off[0]),     // MIO 20
     .IOC3(tie_off[1]),     // MIO 21
     .IOC4(tie_off[2]),     // MIO 22
-    .IOC5(tie_off[3]),     // MIO 23
+    .IOC5(jtag_spi_n),     // MIO 23 -- TAP_STRAP_SEL1
     .IOC6(tie_off[4]),     // MIO 24
     .IOC7(tie_off[5]),     // MIO 25
-    .IOC8(tie_off[6]),     // MIO 26
+    .IOC8(tie_off[6]),     // MIO 26 -- TAP_STRAP_SEL0
     .IOC9(tie_off[7]),     // MIO 27
     .IOC10(tie_off[8]),    // MIO 28
     .IOC11(tie_off[9]),    // MIO 29
@@ -165,7 +165,7 @@
   assign io_dps[0]  = jtag_spi_n ? jtag_tck : spi_device_sck;
   assign io_dps[1]  = jtag_spi_n ? jtag_tdi : spi_device_sdi_i;
   assign io_dps[3]  = jtag_spi_n ? jtag_tms : spi_device_csb;
-  assign io_dps[4]  = jtag_trst_n;
+  assign (weak0, weak1) io_dps[4] = 1'b0;
   assign io_dps[5]  = srst_n;
   assign io_dps[6]  = jtag_spi_n;
   assign io_dps[7]  = bootstrap;
diff --git a/hw/top_earlgrey/rtl/clkgen_xil7series.sv b/hw/top_earlgrey/rtl/clkgen_xil7series.sv
index 817e041..d931b9c 100644
--- a/hw/top_earlgrey/rtl/clkgen_xil7series.sv
+++ b/hw/top_earlgrey/rtl/clkgen_xil7series.sv
@@ -6,9 +6,9 @@
   // Add BUFG if not done by downstream logic
   parameter bit AddClkBuf = 1
 ) (
-  input IO_CLK,
-  input IO_RST_N,
-  input jtag_srst_n,
+  input  IO_CLK,
+  input  IO_RST_N,
+  input  jtag_srst_n,
   output clk_main,
   output clk_48MHz,
   output clk_aon,
diff --git a/hw/top_earlgrey/rtl/top_earlgrey_asic.sv b/hw/top_earlgrey/rtl/top_earlgrey_asic.sv
index 30da7b0..7d562cc 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey_asic.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey_asic.sv
@@ -90,12 +90,12 @@
   logic rst_n;
   logic [pinmux_reg_pkg::NMioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] mio_attr;
   logic [pinmux_reg_pkg::NDioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] dio_attr;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core, mio_out_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core, mio_oe_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core, mio_in_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_padring;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_umux;
 
   // unused pad signals. need to hook these wires up since lint does not like module ports that are
   // tied to 1'bz.
@@ -272,86 +272,48 @@
                              USB_N                        // cio_usbdev_aon_dn_p2d
                            } ),
     // Muxed IOs
-    .mio_in_o            ( mio_in_padring   ),
-    .mio_out_i           ( mio_out_padring  ),
-    .mio_oe_i            ( mio_oe_padring   ),
+    .mio_in_o            ( mio_in_core   ),
+    .mio_out_i           ( mio_out_core  ),
+    .mio_oe_i            ( mio_oe_core   ),
     // Dedicated IOs
-    .dio_in_o            ( dio_in_padring   ),
-    .dio_out_i           ( dio_out_padring  ),
-    .dio_oe_i            ( dio_oe_padring   ),
+    .dio_in_o            ( dio_in_umux   ),
+    .dio_out_i           ( dio_out_umux  ),
+    .dio_oe_i            ( dio_oe_umux   ),
     // Pad Attributes
-    .mio_attr_i          ( mio_attr         ),
-    .dio_attr_i          ( dio_attr         )
+    .mio_attr_i          ( mio_attr      ),
+    .dio_attr_i          ( dio_attr      )
   );
 
-  //////////////////////
-  // JTAG Overlay Mux //
-  //////////////////////
 
+  /////////////////////
+  // USB Overlay Mux //
+  /////////////////////
+
+  // TODO: generalize this USB mux code and align with other tops.
   logic usbdev_aon_usb_rx_enable;
   logic usb_pullup_p_en;
   logic usb_pullup_n_en;
   logic usb_diff_input;
   logic [ast_pkg::UsbCalibWidth-1:0] usb_io_pu_cal;
 
-  logic jtag_trst_n, jtag_srst_n;
-  logic jtag_tck, jtag_tms, jtag_tdi, jtag_tdo;
+  assign usb_pullup_p_en_o = dio_out_core[top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDpPullup] &
+                             dio_oe_core[top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDpPullup];
+  assign usb_pullup_n_en_o = dio_out_core[top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDnPullup] &
+                             dio_oe_core[top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDnPullup];
 
-  localparam int NumIOs = pinmux_reg_pkg::NMioPads +
-                          pinmux_reg_pkg::NDioPads;
+  // Input tie-off muxes
+  for (genvar k = 0; k < pinmux_reg_pkg::NDioPads; k++) begin : gen_input_tie_off
+    if (k == top_earlgrey_pkg::TopEarlgreyDioPinUsbdevD) begin : gen_usb_diff_in
+      logic unused_in;
+      assign unused_in = dio_in_umux[k];
+      assign dio_in_core[k] = usb_diff_input;
+    end else begin : gen_other_inputs
+      assign dio_in_core[k] = dio_in_umux[k];
+    end
+  end
 
-  // This specifies the tie-off values of the muxed MIO/DIOs
-  // when the JTAG is active. SPI CSB is active low.
-  localparam logic [NumIOs-1:0] TieOffValues =NumIOs'(1'b1 << (
-      pinmux_reg_pkg::NMioPads + top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb));
-
-  // TODO: this is a temporary solution. JTAG will eventually be selected and
-  // qualified inside the pinmux, based on strap and lifecycle state.
-  // Parameterizeable JTAG overlay mux.
-  // Unaffected indices are just passed through.
-  jtag_mux #(
-    .NumIOs         (                   NumIOs       ),
-    .TieOffValues   (                   TieOffValues ),
-    .JtagEnIdx      (                             16 ), // MIO 16
-    .JtagEnPolarity (                              1 ),
-    .TckIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSck ),
-    .TmsIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb ),
-    .TrstIdx        (                             18 ), // MIO 18
-    .SrstIdx        (                             19 ), // MIO 19
-    .TdiIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd0 ),
-    .TdoIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd1 ),
-    .UsbDpPuIdx     ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDpPullup ),
-    .UsbDnPuIdx     ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinUsbdevDnPullup ),
-    .UsbDIdx        ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinUsbdevD ),
-    .ConnectUSB     (1)
-  ) jtag_mux (
-    // To JTAG inside core
-    .jtag_tck_o   ( jtag_tck        ),
-    .jtag_tms_o   ( jtag_tms        ),
-    .jtag_trst_no ( jtag_trst_n     ),
-    .jtag_srst_no ( jtag_srst_n     ),
-    .jtag_tdi_o   ( jtag_tdi        ),
-    .jtag_tdo_i   ( jtag_tdo        ),
-    // To core side
-    .out_core_i   ( {dio_out_core, mio_out_core} ),
-    .oe_core_i    ( {dio_oe_core,  mio_oe_core}  ),
-    .in_core_o    ( {dio_in_core,  mio_in_core}  ),
-    // To padring side
-    .out_padring_o ( {dio_out_padring, mio_out_padring} ),
-    .oe_padring_o  ( {dio_oe_padring , mio_oe_padring } ),
-    .in_padring_i  ( {dio_in_padring , mio_in_padring } ),
-    // USB breakouts
-    .usb_pullup_p_en_o ( usb_pullup_p_en ),
-    .usb_pullup_n_en_o ( usb_pullup_n_en ),
-    .usb_diff_input_i  ( usb_diff_input  )
-  );
+  assign dio_out_umux = dio_out_core;
+  assign dio_oe_umux = dio_oe_core;
 
   //////////////////////
   // AST              //
@@ -616,6 +578,33 @@
   // Top-level design //
   //////////////////////
 
+  // TODO: this is temporary and will be removed in the future.
+  // This specifies the tie-off values of the muxed MIO/DIOs
+  // when the JTAG is active. SPI CSB is active low.
+  localparam logic [pinmux_pkg::NumIOs-1:0] TieOffValues = pinmux_pkg::NumIOs'(1'b1 << (
+      pinmux_reg_pkg::NMioPads + top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb));
+
+  // DFT and Debug signal positions in the pinout.
+  // TODO: generate these indices from the target-specific
+  // pinout configuration.
+  localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
+    const_sampling: 1'b1,
+    tie_offs:       TieOffValues,
+    tck_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSck,
+    tms_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb,
+    trst_idx:       18, // MIO 18
+    tdi_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd0,
+    tdo_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd1,
+    tap_strap0_idx: 26, // MIO 26
+    tap_strap1_idx: 23, // MIO 23
+    dft_strap0_idx: 21, // MIO 21
+    dft_strap1_idx: 22  // MIO 22
+  };
+
   top_earlgrey #(
     .AesMasking(1'b1),
     .AesSBoxImpl(aes_pkg::SBoxImplDom),
@@ -624,7 +613,8 @@
     .KmacEnMasking(1),  // DOM AND + Masking scheme
     .KmacReuseShare(0),
     .SramCtrlRetAonInstrExec(0),
-    .SramCtrlMainInstrExec(1)
+    .SramCtrlMainInstrExec(1),
+    .PinmuxAonTargetCfg(PinmuxTargetCfg)
   ) top_earlgrey (
     .rst_ni                       ( aon_pok                    ),
     // ast connections
@@ -658,12 +648,6 @@
     // TODO: connect these
     .flash_test_mode_a_i          ('0                          ),
     .flash_test_voltage_h_i       ('0                          ),
-    // JTAG
-    .jtag_tck_i                   ( jtag_tck                   ),
-    .jtag_tms_i                   ( jtag_tms                   ),
-    .jtag_trst_ni                 ( jtag_trst_n                ),
-    .jtag_tdi_i                   ( jtag_tdi                   ),
-    .jtag_tdo_o                   ( jtag_tdo                   ),
 
     // Multiplexed I/O
     .mio_in_i                     ( mio_in_core                ),
diff --git a/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv b/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
index 52c7dd4..0fe1b8c 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
@@ -78,12 +78,12 @@
   logic clk_main, clk_usb_48mhz, clk_aon, rst_n;
   logic [pinmux_reg_pkg::NMioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] mio_attr;
   logic [pinmux_reg_pkg::NDioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] dio_attr;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core, mio_out_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core, mio_oe_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core, mio_in_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_umux, dio_out_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_umux, dio_oe_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_umux, dio_in_padring;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_umux;
 
   padring #(
     // MIOs 43:34 and 23:20 are currently not
@@ -230,73 +230,24 @@
                              IO_USB_DP0,
                              IO_USB_DN0 } ),
     // Muxed IOs
-    .mio_in_o            ( mio_in_padring   ),
-    .mio_out_i           ( mio_out_padring  ),
-    .mio_oe_i            ( mio_oe_padring   ),
+    .mio_in_o            ( mio_in_core   ),
+    .mio_out_i           ( mio_out_core  ),
+    .mio_oe_i            ( mio_oe_core   ),
     // Dedicated IOs
-    .dio_in_o            ( dio_in_padring   ),
-    .dio_out_i           ( dio_out_padring  ),
-    .dio_oe_i            ( dio_oe_padring   ),
+    .dio_in_o            ( dio_in_umux   ),
+    .dio_out_i           ( dio_out_umux  ),
+    .dio_oe_i            ( dio_oe_umux   ),
     // Pad Attributes
-    .mio_attr_i          ( mio_attr         ),
-    .dio_attr_i          ( dio_attr         )
+    .mio_attr_i          ( mio_attr      ),
+    .dio_attr_i          ( dio_attr      )
   );
 
-  //////////////////////
-  // JTAG Overlay Mux //
-  //////////////////////
 
-  logic jtag_trst_n, jtag_srst_n;
-  logic jtag_tck, jtag_tck_buf, jtag_tms, jtag_tdi, jtag_tdo;
+  /////////////////////
+  // USB Overlay Mux //
+  /////////////////////
 
-  localparam int NumIOs = pinmux_reg_pkg::NMioPads +
-                          pinmux_reg_pkg::NDioPads;
-
-  // This specifies the tie-off values of the muxed MIO/DIOs
-  // when the JTAG is active. SPI CSB is active low.
-  localparam logic [NumIOs-1:0] TieOffValues = NumIOs'(1'b1 << (
-      pinmux_reg_pkg::NMioPads + top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb));
-
-  // TODO: this is a temporary solution. JTAG will eventually be selected and
-  // qualified inside the pinmux, based on strap and lifecycle state.
-  // Parameterizeable JTAG overlay mux.
-  // Unaffected indices are just passed through.
-  jtag_mux #(
-    .NumIOs         (                   NumIOs       ),
-    .TieOffValues   (                   TieOffValues ),
-    .JtagEnIdx      (                             16 ), // MIO 16
-    .JtagEnPolarity (                              1 ),
-    .TckIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSck ),
-    .TmsIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb ),
-    .TrstIdx        (                             18 ), // MIO 18
-    .SrstIdx        (                             19 ), // MIO 19
-    .TdiIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd0 ),
-    .TdoIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd1 )
-  ) jtag_mux (
-    // To JTAG inside core
-    .jtag_tck_o   ( jtag_tck        ),
-    .jtag_tms_o   ( jtag_tms        ),
-    .jtag_trst_no ( jtag_trst_n     ),
-    .jtag_srst_no ( jtag_srst_n     ),
-    .jtag_tdi_o   ( jtag_tdi        ),
-    .jtag_tdo_i   ( jtag_tdo        ),
-    // To core side via usbmux for DIOs
-    .out_core_i   ( {dio_out_umux, mio_out_core} ),
-    .oe_core_i    ( {dio_oe_umux,  mio_oe_core}  ),
-    .in_core_o    ( {dio_in_umux,  mio_in_core}  ),
-    // To padring side
-    .out_padring_o ( {dio_out_padring, mio_out_padring} ),
-    .oe_padring_o  ( {dio_oe_padring, mio_oe_padring } ),
-    .in_padring_i  ( {dio_in_padring, mio_in_padring } ),
-    // USB breakouts
-    .usb_pullup_p_en_o (      ),
-    .usb_pullup_n_en_o (      ),
-    .usb_diff_input_i  ( 1'b0 )
-  );
+  // TODO: generalize this USB mux code and align with other tops.
 
   // Software can enable the pinflip feature inside usbdev.
   // The example hello_usbdev does this based on GPIO0 (a switch on the board)
@@ -365,7 +316,7 @@
   // GPIO[2] = Switch 2 on board is used to select using the UPHY
   // Keep GPIO[1] for selecting differential in sw
   logic use_uphy;
-  assign use_uphy = mio_in_padring[2];
+  assign use_uphy = mio_in_core[2];
 
   for (genvar i = 0; i < pinmux_reg_pkg::NDioPads; i++) begin : gen_dio
     if (i == DioIdxUsbDn0) begin
@@ -417,19 +368,14 @@
     end
   end
 
-  ////////////////////////////////
-  // JTAG clock buffer for FPGA //
-  ////////////////////////////////
-
-  BUFG jtag_buf (
-    .I (jtag_tck),
-    .O (jtag_tck_buf)
-  );
-
   //////////////////
   // PLL for FPGA //
   //////////////////
 
+  // TODO: This needs to become a dedicated custom pin for FPGAs
+  logic jtag_srst_n;
+  assign jtag_srst_n = mio_in_core[19];
+
   clkgen_xil7series # (
     .AddClkBuf(0)
   ) clkgen (
@@ -468,6 +414,33 @@
   // for verilator purposes, make these two the same.
   lc_ctrl_pkg::lc_tx_t lc_clk_bypass;
 
+  // TODO: this is temporary and will be removed in the future.
+  // This specifies the tie-off values of the muxed MIO/DIOs
+  // when the JTAG is active. SPI CSB is active low.
+  localparam logic [pinmux_pkg::NumIOs-1:0] TieOffValues = pinmux_pkg::NumIOs'(1'b1 << (
+      pinmux_reg_pkg::NMioPads + top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb));
+
+  // DFT and Debug signal positions in the pinout.
+  // TODO: generate these indices from the target-specific
+  // pinout configuration.
+  localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
+    const_sampling: 1'b1,
+    tie_offs:       TieOffValues,
+    tck_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSck,
+    tms_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb,
+    trst_idx:       18, // MIO 18
+    tdi_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd0,
+    tdo_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd1,
+    tap_strap0_idx: 20, // MIO 20 (tied off)
+    tap_strap1_idx: 16, // MIO 16 (used as JTAG/SPI select signal)
+    dft_strap0_idx: 21, // MIO 21 (tied off)
+    dft_strap1_idx: 22  // MIO 22 (tied off)
+  };
+
   top_earlgrey #(
     .AesMasking(1'b0),
     .AesSBoxImpl(aes_pkg::SBoxImplLut),
@@ -481,7 +454,8 @@
     .BootRomInitFile(BootRomInitFile),
     .OtpCtrlMemInitFile(OtpCtrlMemInitFile),
     .SramCtrlRetAonInstrExec(0),
-    .SramCtrlMainInstrExec(1)
+    .SramCtrlMainInstrExec(1),
+    .PinmuxAonTargetCfg(PinmuxTargetCfg)
   ) top_earlgrey (
     // Clocks, resets
     .rst_ni                       ( rst_n           ),
@@ -516,13 +490,6 @@
     .flash_test_mode_a_i          ('0               ),
     .flash_test_voltage_h_i       ('0               ),
 
-    // JTAG
-    .jtag_tck_i      ( jtag_tck_buf  ),
-    .jtag_tms_i      ( jtag_tms      ),
-    .jtag_trst_ni    ( jtag_trst_n   ),
-    .jtag_tdi_i      ( jtag_tdi      ),
-    .jtag_tdo_o      ( jtag_tdo      ),
-
     // Multiplexed I/O
     .mio_in_i        ( mio_in_core   ),
     .mio_out_o       ( mio_out_core  ),
diff --git a/hw/top_earlgrey/rtl/top_earlgrey_verilator.sv b/hw/top_earlgrey/rtl/top_earlgrey_verilator.sv
index ce6b044..a88ebee 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey_verilator.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey_verilator.sv
@@ -8,9 +8,6 @@
   input rst_ni
 );
 
-  logic cio_jtag_tck, cio_jtag_tms, cio_jtag_tdi, cio_jtag_tdo;
-  logic cio_jtag_trst_n, cio_jtag_srst_n;
-
   logic [31:0]  cio_gpio_p2d, cio_gpio_d2p, cio_gpio_en_d2p;
   logic cio_uart_rx_p2d, cio_uart_tx_d2p, cio_uart_tx_en_d2p;
 
@@ -130,12 +127,33 @@
     .clk_o(clk_aon)
   );
 
+  // DFT and Debug signal positions in the pinout.
+  // TODO: generate these indices from the target-specific
+  // pinout configuration.
+  localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
+    const_sampling: 1'b1,
+    tie_offs:       '0,
+    tck_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSck,
+    tms_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceCsb,
+    trst_idx:       18, // MIO 18
+    tdi_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd0,
+    tdo_idx:        pinmux_reg_pkg::NMioPads +
+                    top_earlgrey_pkg::TopEarlgreyDioPinSpiDeviceSd1,
+    tap_strap0_idx: 26, // MIO 26
+    tap_strap1_idx: 16, // MIO 16 (this is different in the ASIC top)
+    dft_strap0_idx: 21, // MIO 21
+    dft_strap1_idx: 22  // MIO 22
+  };
 
   lc_ctrl_pkg::lc_tx_t lc_clk_bypass;
   // Top-level design
   top_earlgrey #(
     .SramCtrlRetAonInstrExec(0),
-    .SramCtrlMainInstrExec(1)
+    .SramCtrlMainInstrExec(1),
+    .PinmuxAonTargetCfg(PinmuxTargetCfg)
   ) top_earlgrey (
     .rst_ni                       (rst_ni            ),
     .clk_main_i                   (clk_i             ),
@@ -168,11 +186,6 @@
     .lc_clk_byp_ack_i             ( lc_clk_bypass    ),
     .flash_test_mode_a_i          ('0),
     .flash_test_voltage_h_i       ('0),
-    .jtag_tck_i                   (cio_jtag_tck),
-    .jtag_tms_i                   (cio_jtag_tms),
-    .jtag_trst_ni                 (cio_jtag_trst_n),
-    .jtag_tdi_i                   (cio_jtag_tdi),
-    .jtag_tdo_o                   (cio_jtag_tdo),
 
     // Multiplexed I/O
     .mio_in_i                     (mio_in),
@@ -234,18 +247,22 @@
     .dmi_rst_n      (dmi_rst_n)
   );
 `else
-  // JTAG DPI for OpenOCD
-  jtagdpi u_jtagdpi (
-    .clk_i,
-    .rst_ni,
+  // TODO: this is currently not supported.
+  // connect this to the correct pins once pinout is final and once the
+  // verilator testbench supports DFT/Debug strap sampling.
+  // See also #5221.
+  //
+  // jtagdpi u_jtagdpi (
+  //   .clk_i,
+  //   .rst_ni,
 
-    .jtag_tck    (cio_jtag_tck),
-    .jtag_tms    (cio_jtag_tms),
-    .jtag_tdi    (cio_jtag_tdi),
-    .jtag_tdo    (cio_jtag_tdo),
-    .jtag_trst_n (cio_jtag_trst_n),
-    .jtag_srst_n (cio_jtag_srst_n)
-  );
+  //   .jtag_tck    (cio_jtag_tck),
+  //   .jtag_tms    (cio_jtag_tms),
+  //   .jtag_tdi    (cio_jtag_tdi),
+  //   .jtag_tdo    (cio_jtag_tdo),
+  //   .jtag_trst_n (cio_jtag_trst_n),
+  //   .jtag_srst_n (cio_jtag_srst_n)
+  // );
 `endif
 
   // SPI DPI
diff --git a/hw/top_englishbreakfast/rtl/top_englishbreakfast_cw305.sv b/hw/top_englishbreakfast/rtl/top_englishbreakfast_cw305.sv
index aa8bb17..33a5682 100644
--- a/hw/top_englishbreakfast/rtl/top_englishbreakfast_cw305.sv
+++ b/hw/top_englishbreakfast/rtl/top_englishbreakfast_cw305.sv
@@ -60,12 +60,12 @@
   logic clk_main, clk_usb_48mhz, clk_aon, rst_n;
   logic [pinmux_reg_pkg::NMioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] mio_attr;
   logic [pinmux_reg_pkg::NDioPads-1:0][pinmux_reg_pkg::AttrDw-1:0] dio_attr;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core, mio_out_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core, mio_oe_padring;
-  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core, mio_in_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_padring;
-  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_padring;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_out_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe_core;
+  logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_core;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_out_core, dio_out_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe_core, dio_oe_umux;
+  logic [pinmux_reg_pkg::NDioPads-1:0] dio_in_core, dio_in_umux;
 
   padring #(
     // MIOs 43:34 and 31:20 are currently not
@@ -204,87 +204,26 @@
                              IO_USB_DP0,
                              IO_USB_DN0 } ),
     // Muxed IOs
-    .mio_in_o            ( mio_in_padring   ),
-    .mio_out_i           ( mio_out_padring  ),
-    .mio_oe_i            ( mio_oe_padring   ),
+    .mio_in_o            ( mio_in_core   ),
+    .mio_out_i           ( mio_out_core  ),
+    .mio_oe_i            ( mio_oe_core   ),
     // Dedicated IOs
-    .dio_in_o            ( dio_in_padring   ),
-    .dio_out_i           ( dio_out_padring  ),
-    .dio_oe_i            ( dio_oe_padring   ),
+    .dio_in_o            ( dio_in_umux   ),
+    .dio_out_i           ( dio_out_umux  ),
+    .dio_oe_i            ( dio_oe_umux   ),
     // Pad Attributes
-    .mio_attr_i          ( mio_attr         ),
-    .dio_attr_i          ( dio_attr         )
-  );
-
-  //////////////////////
-  // JTAG Overlay Mux //
-  //////////////////////
-
-  logic jtag_trst_n, jtag_srst_n;
-  logic jtag_tck, jtag_tck_buf, jtag_tms, jtag_tdi, jtag_tdo;
-
-  localparam int NumIOs = pinmux_reg_pkg::NMioPads +
-                          pinmux_reg_pkg::NDioPads;
-
-  // This specifies the tie-off values of the muxed MIO/DIOs
-  // when the JTAG is active. SPI CSB is active low.
-  localparam logic [NumIOs-1:0] TieOffValues = NumIOs'(1'b1 << (
-      pinmux_reg_pkg::NMioPads + top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceCsb));
-
-  // TODO: this is a temporary solution. JTAG will eventually be selected and
-  // qualified inside the pinmux, based on strap and lifecycle state.
-  // Parameterizeable JTAG overlay mux.
-  // Unaffected indices are just passed through.
-  jtag_mux #(
-    .NumIOs         (                   NumIOs       ),
-    .TieOffValues   (                   TieOffValues ),
-    .JtagEnIdx      (                             16 ), // MIO 16
-    .JtagEnPolarity (                              1 ),
-    .TckIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSck ),
-    .TmsIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceCsb ),
-    .TrstIdx        (                             18 ), // MIO 18
-    .SrstIdx        (                             19 ), // MIO 19
-    .TdiIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd0 ),
-    .TdoIdx         ( pinmux_reg_pkg::NMioPads +
-                      top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd1 )
-  ) jtag_mux (
-    // To JTAG inside core
-    .jtag_tck_o   ( jtag_tck        ),
-    .jtag_tms_o   ( jtag_tms        ),
-    .jtag_trst_no ( jtag_trst_n     ),
-    .jtag_srst_no ( jtag_srst_n     ),
-    .jtag_tdi_o   ( jtag_tdi        ),
-    .jtag_tdo_i   ( jtag_tdo        ),
-    // To core side
-    .out_core_i   ( {dio_out_core, mio_out}      ),
-    .oe_core_i    ( {dio_oe_core,  mio_oe_core}  ),
-    .in_core_o    ( {dio_in_core,  mio_in_core}  ),
-    // To padring side
-    .out_padring_o ( {dio_out_padring, mio_out_padring} ),
-    .oe_padring_o  ( {dio_oe_padring, mio_oe_padring } ),
-    .in_padring_i  ( {dio_in_padring, mio_in_padring } ),
-    // USB breakouts
-    .usb_pullup_p_en_o (      ),
-    .usb_pullup_n_en_o (      ),
-    .usb_diff_input_i  ( 1'b0 )
-  );
-
-  ////////////////////////////////
-  // JTAG clock buffer for FPGA //
-  ////////////////////////////////
-
-  BUFG jtag_buf (
-    .I (jtag_tck),
-    .O (jtag_tck_buf)
+    .mio_attr_i          ( mio_attr      ),
+    .dio_attr_i          ( dio_attr      )
   );
 
   //////////////////
   // PLL for FPGA //
   //////////////////
 
+  // TODO: This needs to become a dedicated custom pin for FPGAs
+  logic jtag_srst_n;
+  assign jtag_srst_n = mio_in_core[19];
+
   clkgen_xil7series # (
     .AddClkBuf(0)
   ) clkgen (
@@ -322,6 +261,33 @@
   // for verilator purposes, make these two the same.
   lc_ctrl_pkg::lc_tx_t lc_clk_bypass;
 
+  // TODO: this is temporary and will be removed in the future.
+  // This specifies the tie-off values of the muxed MIO/DIOs
+  // when the JTAG is active. SPI CSB is active low.
+  localparam logic [pinmux_pkg::NumIOs-1:0] TieOffValues = pinmux_pkg::NumIOs'(1'b1 << (
+      pinmux_reg_pkg::NMioPads + top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceCsb));
+
+  // DFT and Debug signal positions in the pinout.
+  // TODO: generate these indices from the target-specific
+  // pinout configuration.
+  localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
+    const_sampling: 1'b1,
+    tie_offs:       TieOffValues,
+    tck_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSck,
+    tms_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceCsb,
+    trst_idx:       18, // MIO 18
+    tdi_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd0,
+    tdo_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd1,
+    tap_strap0_idx: 20, // MIO 20 (tied off)
+    tap_strap1_idx: 16, // MIO 16 (used as JTAG/SPI select signal)
+    dft_strap0_idx: 21, // MIO 21 (tied off)
+    dft_strap1_idx: 22  // MIO 22 (tied off)
+  };
+
   top_englishbreakfast #(
     .AesMasking(1'b1),
     .AesSBoxImpl(aes_pkg::SBoxImplDom),
@@ -331,7 +297,8 @@
     .IbexRegFile(ibex_pkg::RegFileFPGA),
     .IbexICache(0),
     .IbexPipeLine(1),
-    .BootRomInitFile(BootRomInitFile)
+    .BootRomInitFile(BootRomInitFile),
+    .PinmuxAonTargetCfg(PinmuxTargetCfg)
   ) top_englishbreakfast (
     // Clocks, resets
     .rst_ni                       ( rst_n           ),
@@ -356,13 +323,6 @@
     .clks_ast_o                   (                 ),
     .rsts_ast_o                   (                 ),
 
-    // JTAG
-    .jtag_tck_i      ( jtag_tck_buf  ),
-    .jtag_tms_i      ( jtag_tms      ),
-    .jtag_trst_ni    ( jtag_trst_n   ),
-    .jtag_tdi_i      ( jtag_tdi      ),
-    .jtag_tdo_o      ( jtag_tdo      ),
-
     // Multiplexed I/O
     .mio_in_i        ( mio_in_core   ),
     .mio_out_o       ( mio_out_core  ),
diff --git a/hw/top_englishbreakfast/rtl/top_englishbreakfast_verilator.sv b/hw/top_englishbreakfast/rtl/top_englishbreakfast_verilator.sv
index a96ce46..796c41f 100644
--- a/hw/top_englishbreakfast/rtl/top_englishbreakfast_verilator.sv
+++ b/hw/top_englishbreakfast/rtl/top_englishbreakfast_verilator.sv
@@ -125,6 +125,27 @@
     .clk_o(clk_aon)
   );
 
+  // DFT and Debug signal positions in the pinout.
+  // TODO: generate these indices from the target-specific
+  // pinout configuration.
+  localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
+    const_sampling: 1'b1,
+    tie_offs:       '0,
+    tck_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSck,
+    tms_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceCsb,
+    trst_idx:       18, // MIO 18
+    tdi_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd0,
+    tdo_idx:        pinmux_reg_pkg::NMioPads +
+                    top_englishbreakfast_pkg::TopEnglishbreakfastDioPinSpiDeviceSd1,
+    tap_strap0_idx: 26, // MIO 26
+    tap_strap1_idx: 16, // MIO 16 (this is different in the ASIC top)
+    dft_strap0_idx: 21, // MIO 21
+    dft_strap1_idx: 22  // MIO 22
+  };
+
   // the rst_ni pin only goes to AST
   // the rest of the logic generates reset based on the 'pok' signal.
   // for verilator purposes, make these two the same.
@@ -137,7 +158,8 @@
     .SecAesSkipPRNGReseeding(1'b1),
     .IbexICache(0),
     .SramCtrlRetAonInstrExec(0),
-    .SramCtrlMainInstrExec(1)
+    .SramCtrlMainInstrExec(1),
+    .PinmuxAonTargetCfg(PinmuxTargetCfg)
   ) top_englishbreakfast (
     .rst_ni                     (rst_ni),
     .clk_main_i                 (clk_i),
@@ -154,12 +176,6 @@
     .flash_power_down_h_i         ( '0              ),
     .flash_power_ready_h_i        ( 1'b1            ),
 
-    .jtag_tck_i                 (cio_jtag_tck),
-    .jtag_tms_i                 (cio_jtag_tms),
-    .jtag_trst_ni               (cio_jtag_trst_n),
-    .jtag_tdi_i                 (cio_jtag_tdi),
-    .jtag_tdo_o                 (cio_jtag_tdo),
-
     // Multiplexed I/O
     .mio_in_i                   (mio_in),
     .mio_out_o                  (mio_out),