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; +}