Add tap straps tests to edacloud

Change-Id: I6b749cb5a0a3dfe33f8125dfdda7732a1f575d68
diff --git a/hw/dv/tools/dvsim/sim.mk b/hw/dv/tools/dvsim/sim.mk
index cbac3af..d803100 100644
--- a/hw/dv/tools/dvsim/sim.mk
+++ b/hw/dv/tools/dvsim/sim.mk
@@ -91,7 +91,7 @@
 		else \
 			bazel_cquery="$${bazel_label}"; \
 		fi; \
-		if [[ $$sw_image =~ "test_rom" || $${flags[@]} =~ "matcha" ]]; then \
+		if [[ $$sw_image =~ "test_rom" || $${flags[@]} =~ "matcha" || $${flags[@]} =~ "test_in_rom" ]]; then \
 		  build_repo="matcha"; \
 	          cd ${proj_root}; \
 		else \
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index 4eaebca..31a5426 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -2113,6 +2113,9 @@
         "chip_sw_sram_ctrl_smoketest",
         "chip_sw_uart_smoketest",
         "chip_sw_uart_tx_rx",
+        "chip_tap_straps_dev",
+        "chip_tap_straps_prod",
+        "chip_tap_straps_rma",
       ]
     }
     {
@@ -2180,6 +2183,9 @@
         "chip_sw_sram_ctrl_smoketest",
         "chip_sw_uart_smoketest",
         "chip_sw_uart_tx_rx",
+        "chip_tap_straps_dev",
+        "chip_tap_straps_prod",
+        "chip_tap_straps_rma",
       ]
     }
     {
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_tap_straps_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_tap_straps_vseq.sv
index 6994085..ffab4b7 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_tap_straps_vseq.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_tap_straps_vseq.sv
@@ -1,3 +1,4 @@
+// Copyright 2023 Google LLC.
 // Copyright lowRISC contributors.
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
@@ -12,8 +13,6 @@
 // Verify pimux.dft_strap_test_o is always 0 in the states other than TEST_UNLOCKED* and
 // RMA, regardless of the value on DFT SW straps.
 
-// TODO: This test is broken. Drive functional JTAG traffic as opposed to pin connectivity.
-
 class chip_tap_straps_vseq extends chip_sw_base_vseq;
   string path_dft_strap_test_o = "tb.dut.top_matcha.dft_strap_test_o";
   string path_dft_tap_req = "tb.dut.top_matcha.u_dft_tap_breakout.req_i";
@@ -51,7 +50,17 @@
   virtual task dut_init(string reset_kind = "HARD");
     bit lc_at_prod;
 
-    randomize_dft_straps();
+    // Release DFT straps after they are sampled
+    fork
+        begin randomize_dft_straps(); end
+        begin
+
+           wait (cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
+           cfg.chip_vif.dft_straps_if.disconnect();
+           `uvm_info(`gfn, "DICONNECTED DFT STRAPS", UVM_NONE)
+        end
+    join_none
+
     `DV_CHECK_STD_RANDOMIZE_FATAL(select_jtag)
     cfg.chip_vif.tap_straps_if.drive(select_jtag);
     cfg.chip_vif.set_tdo_pull(0);
@@ -208,8 +217,8 @@
       `DV_CHECK_FATAL(uvm_hdl_force(path_tb_jtag_tdi,    exp_jtag_req.tdi))
       `DV_CHECK_FATAL(uvm_hdl_force(path_dft_tap_rsp,    exp_jtag_rsp))
 
-      // avoid race condition
-      #1ps;
+      // Wait for jtag signals to be driven
+      cfg.clk_rst_vif.wait_clks(10);
 
       // check jtag
       `DV_CHECK_FATAL(uvm_hdl_read(path_dft_tap_req, act_jtag_req))
@@ -262,24 +271,30 @@
     end
   endtask
 
+  // Randomize DFT straps for rma and unlock between (0,2,3) for dev and prod (0,1,2,3).
+  // It is problematic to run the test with some DFT values, for some vendors.
+  bit [1:0] dft_straps_val;
+  bit partner;
   virtual function void randomize_dft_straps();
-    bit [1:0] val = $urandom;
-
-    `uvm_info(`gfn, $sformatf("Drive dft straps to %0d", val), UVM_LOW)
-    cfg.chip_vif.dft_straps_if.drive(val);
+    if ($value$plusargs("PARTNER_N=%b",partner))
+    begin
+        randomize(dft_straps_val) with {dft_straps_val inside {0,2,3};};
+    end else begin
+        randomize(dft_straps_val) with {dft_straps_val inside {0,1,2,3};};
+    end
+    `uvm_info(`gfn, $sformatf("LC state is = %0s, DFT straps = %2b\n",
+              cur_lc_state.name(),dft_straps_val), UVM_LOW)
+    cfg.chip_vif.dft_straps_if.drive(dft_straps_val);
   endfunction
 
+  // Compare DFT strap to driven values, interface is disconnected and loses actual value.
   virtual function void check_dft_straps();
-    bit [1:0] exp_val, act_val;
-
-    if (is_lc_in_unlocked_or_rma()) begin
-      exp_val = cfg.chip_vif.dft_straps_if.sample();
-    end else begin
-      exp_val = 0;
+    bit [1:0] act_val;
+    if (!is_lc_in_unlocked_or_rma()) begin
+      dft_straps_val = 0;
     end
     `DV_CHECK_FATAL(uvm_hdl_read(path_dft_strap_test_o, act_val))
-
-    `DV_CHECK_EQ(act_val, exp_val)
+    `DV_CHECK_EQ(act_val, dft_straps_val)
   endfunction
 
   virtual function bit is_lc_in_unlocked_or_rma();
@@ -287,4 +302,5 @@
         LcStTestUnlocked0, LcStTestUnlocked1, LcStTestUnlocked2, LcStTestUnlocked3,
         LcStTestUnlocked4, LcStTestUnlocked5, LcStTestUnlocked6, LcStTestUnlocked7};
   endfunction
+
 endclass
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 800e410..e7f62af 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2022 Google LLC.
+# Copyright 2023 Google LLC.
 # Copyright lowRISC contributors.
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
@@ -660,6 +660,22 @@
 )
 
 matcha_dv_test(
+    name = "example_test_from_rom",
+    srcs = ["example_test_from_rom.c"],
+    # This test is designed to run and complete entirely in the ROM boot stage.
+    # Setting the `test_in_rom` flag makes the `matcha_dv_test` rule aware
+    # of this, and instructs it to load the test image into ROM (rather than
+    # loading the default test ROM, or any other ROM that may be specified via
+    # DV params).
+    test_in_rom = True,
+    deps = [
+        ":test_lib_base",
+        "//sw/device/lib/testing/test_rom:linker_script",
+        "//sw/device/lib/testing/test_rom:test_rom_lib",
+    ],
+)
+
+matcha_dv_test(
     name = "hmac_enc_test",
     srcs = ["@lowrisc_opentitan//sw/device/tests:hmac_enc_test.c"],
     deps = [
diff --git a/sw/device/tests/example_test_from_rom.c b/sw/device/tests/example_test_from_rom.c
new file mode 100644
index 0000000..eddb47d
--- /dev/null
+++ b/sw/device/tests/example_test_from_rom.c
@@ -0,0 +1,54 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"  // Generated.
+#include "sw/device/lib/arch/device.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_uart.h"
+#include "sw/device/lib/runtime/hart.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/runtime/print.h"
+#include "sw/device/lib/testing/pinmux_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/status.h"
+
+static dif_pinmux_t pinmux;
+static dif_uart_t uart0;
+
+bool rom_test_main(void) {
+  // We need to set the test status as "in test" to indicate to the test code
+  // has been reached, even though this test is also in the "boot ROM".
+  test_status_set(kTestStatusInTest);
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+  pinmux_testutils_init(&pinmux);
+
+  // We need to initialize the UART regardless if we LOG any messages, since
+  // Verilator and FPGA platforms use the UART to communicate the test results.
+  if (kDeviceType != kDeviceSimDV) {
+    CHECK_DIF_OK(dif_uart_init(
+        mmio_region_from_addr(TOP_MATCHA_UART0_BASE_ADDR), &uart0));
+    CHECK_DIF_OK(
+        dif_uart_configure(&uart0, (dif_uart_config_t){
+                                       .baudrate = kUartBaudrate,
+                                       .clk_freq_hz = kClockFreqPeripheralHz,
+                                       .parity_enable = kDifToggleDisabled,
+                                       .parity = kDifUartParityEven,
+                                       .tx_enable = kDifToggleEnabled,
+                                       .rx_enable = kDifToggleEnabled,
+                                   }));
+    base_uart_stdout(&uart0);
+  }
+
+  /**
+   * Place test code here.
+   */
+
+  /**
+   * Return true if the test succeeds. Return false if it should fail.
+   */
+  return true;
+}