[top, pinmux] Add ability to halt tap strap sampling during dft state

- This allows dft to perform different kinds of tests without
  disturbing the tap selection

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/pinmux/data/pinmux.hjson.tpl b/hw/ip/pinmux/data/pinmux.hjson.tpl
index 02117a4..62ce49d 100644
--- a/hw/ip/pinmux/data/pinmux.hjson.tpl
+++ b/hw/ip/pinmux/data/pinmux.hjson.tpl
@@ -83,6 +83,14 @@
       package: "pinmux_pkg",
       default: "'0"
     }
+    // DFT indication to stop tap strap sampling
+    { struct:  "logic",
+      type:    "uni",
+      name:    "dft_hold_tap_sel",
+      act:     "rcv",
+      package: "",
+      default: "'0"
+    }
     // Define pwr mgr <-> pinmux signals
     { struct:  "logic",
       type:    "uni",
diff --git a/hw/ip/pinmux/rtl/pinmux.sv b/hw/ip/pinmux/rtl/pinmux.sv
index c35bba6..77ae62e 100644
--- a/hw/ip/pinmux/rtl/pinmux.sv
+++ b/hw/ip/pinmux/rtl/pinmux.sv
@@ -35,6 +35,8 @@
   input  lc_ctrl_pkg::lc_tx_t      lc_hw_debug_en_i,
   // Sampled values for DFT straps
   output dft_strap_test_req_t      dft_strap_test_o,
+  // DFT indication to stop tap strap sampling
+  input                            dft_hold_tap_sel_i,
   // Qualified JTAG signals for TAPs
   output jtag_pkg::jtag_req_t      lc_jtag_o,
   input  jtag_pkg::jtag_rsp_t      lc_jtag_i,
@@ -179,6 +181,7 @@
     .lc_dft_en_i,
     .lc_hw_debug_en_i,
     .dft_strap_test_o,
+    .dft_hold_tap_sel_i,
     .lc_jtag_o,
     .lc_jtag_i,
     .rv_jtag_o,
diff --git a/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
index 34499c0..f6754f2 100644
--- a/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
+++ b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
@@ -27,6 +27,8 @@
   input  lc_ctrl_pkg::lc_tx_t      lc_hw_debug_en_i,
   // Sampled values for DFT straps
   output dft_strap_test_req_t      dft_strap_test_o,
+  // Hold tap strap select
+  input                            dft_hold_tap_sel_i,
   // Qualified JTAG signals for TAPs
   output jtag_pkg::jtag_req_t      lc_jtag_o,
   input  jtag_pkg::jtag_rsp_t      lc_jtag_i,
@@ -98,6 +100,19 @@
   assign dft_strap_test_o.straps = dft_strap_q;
 
 
+  // During dft enabled states, we continously sample all straps unless
+  // told not to do so by external dft logic
+  logic dft_sampling_en;
+  logic dft_hold_tap_sel;
+
+  prim_buf #(
+    .Width(1)
+  ) u_buf_hold_tap (
+    .in_i(dft_hold_tap_sel_i),
+    .out_o(dft_hold_tap_sel)
+  );
+  assign dft_sampling_en = lc_dft_en[0] == lc_ctrl_pkg::On & ~dft_hold_tap_sel;
+
   always_comb begin : p_strap_sampling
     lc_strap_sample_en = 1'b0;
     rv_strap_sample_en = 1'b0;
@@ -107,7 +122,7 @@
     // qualified by life cycle signals.
     // In DFT-enabled life cycle states we continously
     // sample all straps.
-    if (strap_en_i || lc_dft_en[0] == lc_ctrl_pkg::On) begin
+    if (strap_en_i || dft_sampling_en) begin
       lc_strap_sample_en = 1'b1;
       if (lc_hw_debug_en[0] == lc_ctrl_pkg::On) begin
         rv_strap_sample_en = 1'b1;
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 8be4673..431d31f 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -2943,6 +2943,19 @@
           index: -1
         }
         {
+          name: dft_hold_tap_sel
+          struct: logic
+          type: uni
+          act: rcv
+          width: 1
+          default: "'0"
+          inst_name: pinmux_aon
+          package: ""
+          external: true
+          top_signame: dft_hold_tap_sel
+          index: -1
+        }
+        {
           name: sleep_en
           struct: logic
           type: uni
@@ -6234,6 +6247,7 @@
       entropy_src.rng_fips: es_rng_fips
       peri.tl_ast: ast_tl
       pinmux_aon.dft_strap_test: dft_strap_test
+      pinmux_aon.dft_hold_tap_sel: dft_hold_tap_sel
       pwrmgr_aon.pwr_ast: pwrmgr_ast
       otp_ctrl.otp_ast_pwr_seq: ""
       otp_ctrl.otp_ast_pwr_seq_h: ""
@@ -13201,6 +13215,19 @@
         index: -1
       }
       {
+        name: dft_hold_tap_sel
+        struct: logic
+        type: uni
+        act: rcv
+        width: 1
+        default: "'0"
+        inst_name: pinmux_aon
+        package: ""
+        external: true
+        top_signame: dft_hold_tap_sel
+        index: -1
+      }
+      {
         name: sleep_en
         struct: logic
         type: uni
@@ -15846,6 +15873,18 @@
         netname: dft_strap_test
       }
       {
+        package: ""
+        struct: logic
+        signame: dft_hold_tap_sel_i
+        width: 1
+        type: uni
+        default: "'0"
+        direction: in
+        conn_type: false
+        index: -1
+        netname: dft_hold_tap_sel
+      }
+      {
         package: pwrmgr_pkg
         struct: pwr_ast_req
         signame: pwrmgr_ast_req_o
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index e827180..b4c4d02 100644
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -987,6 +987,7 @@
         'entropy_src.rng_fips'         : 'es_rng_fips',
         'peri.tl_ast'                  : 'ast_tl',
         'pinmux_aon.dft_strap_test'    : 'dft_strap_test'
+        'pinmux_aon.dft_hold_tap_sel'  : 'dft_hold_tap_sel',
         'pwrmgr_aon.pwr_ast'           : 'pwrmgr_ast',
         'otp_ctrl.otp_ast_pwr_seq'     : '',
         'otp_ctrl.otp_ast_pwr_seq_h'   : '',
diff --git a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
index 173c6a7..cf72271 100644
--- a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
+++ b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
@@ -79,6 +79,14 @@
       package: "pinmux_pkg",
       default: "'0"
     }
+    // DFT indication to stop tap strap sampling
+    { struct:  "logic",
+      type:    "uni",
+      name:    "dft_hold_tap_sel",
+      act:     "rcv",
+      package: "",
+      default: "'0"
+    }
     // Define pwr mgr <-> pinmux signals
     { struct:  "logic",
       type:    "uni",
diff --git a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
index 2496d43..8425a3f 100644
--- a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
+++ b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
@@ -1161,6 +1161,7 @@
     // DFT signals
     .ast_lc_dft_en_o              ( dft_en                     ),
     .dft_strap_test_o             ( dft_strap_test             ),
+    .dft_hold_tap_sel_i           ( '0                         ),
     .scan_rst_ni                  ( scan_rst_n                 ),
     .scan_en_i                    ( scan_en                    ),
     .scanmode_i                   ( scanmode                   )
diff --git a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_nexysvideo.sv b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_nexysvideo.sv
index 6142c6a..96bf208 100644
--- a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_nexysvideo.sv
+++ b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_nexysvideo.sv
@@ -780,9 +780,10 @@
     .rom_cfg_i       ( '0 ),
 
     // DFT signals
-    .scan_rst_ni     ( 1'b1          ),
-    .scan_en_i       ( 1'b0          ),
-    .scanmode_i      ( lc_ctrl_pkg::Off )
+    .dft_hold_tap_sel_i ( '0               ),
+    .scan_rst_ni        ( 1'b1             ),
+    .scan_en_i          ( 1'b0             ),
+    .scanmode_i         ( lc_ctrl_pkg::Off )
   );
 
 
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index 7d64c51..a530f3d 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -77,6 +77,7 @@
   output tlul_pkg::tl_h2d_t       ast_tl_req_o,
   input  tlul_pkg::tl_d2h_t       ast_tl_rsp_i,
   output pinmux_pkg::dft_strap_test_req_t       dft_strap_test_o,
+  input  logic       dft_hold_tap_sel_i,
   output pwrmgr_pkg::pwr_ast_req_t       pwrmgr_ast_req_o,
   input  pwrmgr_pkg::pwr_ast_rsp_t       pwrmgr_ast_rsp_i,
   output otp_ctrl_pkg::otp_ast_req_t       otp_ctrl_otp_ast_pwr_seq_o,
@@ -1794,6 +1795,7 @@
       .dft_jtag_o(),
       .dft_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT),
       .dft_strap_test_o(dft_strap_test_o),
+      .dft_hold_tap_sel_i(dft_hold_tap_sel_i),
       .sleep_en_i(pwrmgr_aon_low_power),
       .strap_en_i(pwrmgr_aon_strap),
       .aon_wkup_req_o(pwrmgr_aon_wakeups[2]),
diff --git a/hw/top_englishbreakfast/data/top_englishbreakfast.hjson b/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
index f96a752..789a354 100644
--- a/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
+++ b/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
@@ -745,6 +745,7 @@
         # 'entropy_src.rng_fips'         : '',
         # 'peri.tl_ast'                  : '',
         'pinmux_aon.dft_strap_test'    : 'dft_strap_test'
+        'pinmux_aon.dft_hold_tap_sel'  : 'dft_hold_tap_sel',
         'pwrmgr_aon.pwr_ast'           : 'pwrmgr_ast',
         # 'otp_ctrl.otp_ast_pwr_seq'     : '',
         # 'otp_ctrl.otp_ast_pwr_seq_h'   : '',
diff --git a/util/topgen/templates/chiplevel.sv.tpl b/util/topgen/templates/chiplevel.sv.tpl
index caee806..d0e02c3 100644
--- a/util/topgen/templates/chiplevel.sv.tpl
+++ b/util/topgen/templates/chiplevel.sv.tpl
@@ -1017,6 +1017,7 @@
     // DFT signals
     .ast_lc_dft_en_o              ( dft_en                     ),
     .dft_strap_test_o             ( dft_strap_test             ),
+    .dft_hold_tap_sel_i           ( '0                         ),
     .scan_rst_ni                  ( scan_rst_n                 ),
     .scan_en_i                    ( scan_en                    ),
     .scanmode_i                   ( scanmode                   )
@@ -1172,9 +1173,10 @@
     .rom_cfg_i       ( '0 ),
 
     // DFT signals
-    .scan_rst_ni     ( 1'b1          ),
-    .scan_en_i       ( 1'b0          ),
-    .scanmode_i      ( lc_ctrl_pkg::Off )
+    .dft_hold_tap_sel_i ( '0               ),
+    .scan_rst_ni        ( 1'b1             ),
+    .scan_en_i          ( 1'b0             ),
+    .scanmode_i         ( lc_ctrl_pkg::Off )
   );
 % endif