diff --git a/hw/dv/sv/sw_test_status/sw_test_status_if.sv b/hw/dv/sv/sw_test_status/sw_test_status_if.sv index abd271a8c50c7..8b2ba2ce0fc2c 100644 --- a/hw/dv/sv/sw_test_status/sw_test_status_if.sv +++ b/hw/dv/sv/sw_test_status/sw_test_status_if.sv @@ -29,15 +29,16 @@ interface sw_test_status_if #( sw_test_status_e sw_test_status_prev; // If the sw_test_status reaches the terminal states, assert that we are done. + bit in_terminal_state; bit sw_test_done; bit sw_test_passed; - // SystemVerilog sequence can iterate over SW test multiple times with external reset. - // Only allow SW to exit if it is the last SV iteration. - bit sw_test_last_iteration = 1'b1; + // The test seq may reboot the CPU multiple times, so it may cycle through the SW test states + // multiple times. + int num_iterations = 1; - function automatic void set_sw_test_last_iteration(bit value); - sw_test_last_iteration = value; + function automatic void set_num_iterations(int value); + num_iterations = value; endfunction always @(posedge clk_i) begin @@ -54,22 +55,25 @@ interface sw_test_status_if #( `dv_error("SW test status must not change after reaching the pass or fail state.") `dv_error("==== SW TEST FAILED ====") end - sw_test_done |= sw_test_status inside {SwTestStatusPassed, SwTestStatusFailed}; - sw_test_done &= sw_test_last_iteration; + + in_terminal_state = sw_test_status inside {SwTestStatusPassed, SwTestStatusFailed}; + if (in_terminal_state) num_iterations--; + sw_test_done |= in_terminal_state && (num_iterations == 0); // Exit only when all iterations of the SW test are finished. - if ((sw_test_status == SwTestStatusPassed) && sw_test_done) begin - if (can_pass_only_in_test && sw_test_status_prev != SwTestStatusInTest) begin - `dv_error($sformatf("SW test transitioned to %s from an illegal state: %s.", - sw_test_status.name(), sw_test_status_prev.name())) - `dv_error("==== SW TEST FAILED ====") + if (sw_test_done) begin + if (sw_test_status == SwTestStatusPassed) begin + if (can_pass_only_in_test && sw_test_status_prev != SwTestStatusInTest) begin + `dv_error($sformatf("SW test transitioned to %s from an illegal state: %s.", + sw_test_status.name(), sw_test_status_prev.name())) + `dv_error("==== SW TEST FAILED ====") + end else begin + sw_test_passed = 1'b1; + `dv_info("==== SW TEST PASSED ====") + end end else begin - sw_test_passed = 1'b1; - `dv_info("==== SW TEST PASSED ====") + `dv_error("==== SW TEST FAILED ====") end - // Any SW test failure will result in a DV error. - end else if (sw_test_status == SwTestStatusFailed) begin - `dv_error("==== SW TEST FAILED ====") end end end diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv index d0b1877145d59..3b71b67e7346e 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_base_vseq.sv @@ -20,11 +20,6 @@ class chip_base_vseq extends cip_base_vseq #( // Local queue for holding received UART TX data. byte uart_tx_data_q[$]; - // Default only iterate through SW code once. - constraint num_trans_c { - num_trans == 1; - } - `uvm_object_new task post_start(); @@ -70,7 +65,6 @@ class chip_base_vseq extends cip_base_vseq #( // Do DUT init after some additional settings. bit do_dut_init_save = do_dut_init; do_dut_init = 1'b0; - cfg.sw_test_status_vif.set_sw_test_last_iteration(num_trans == 1); super.pre_start(); do_dut_init = do_dut_init_save; diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv index cadab64b94908..507e06277bc5b 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_base_vseq.sv @@ -5,6 +5,11 @@ class chip_sw_base_vseq extends chip_base_vseq; `uvm_object_utils(chip_sw_base_vseq) + // Default only iterate through SW code once. + constraint num_trans_c { + num_trans == 1; + } + `uvm_object_new virtual task dut_init(string reset_kind = "HARD"); @@ -57,6 +62,7 @@ class chip_sw_base_vseq extends chip_base_vseq; endtask virtual task body(); + cfg.sw_test_status_vif.set_num_iterations(num_trans); // Initialize the CPU to kick off the sw test. cpu_init(); endtask diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_gpio_smoke_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_gpio_smoke_vseq.sv index 566b0572dd523..1be015138ebb1 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_gpio_smoke_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_gpio_smoke_vseq.sv @@ -32,7 +32,7 @@ class chip_sw_gpio_smoke_vseq extends chip_sw_base_vseq; super.cpu_init(); // Need to convert integer array to byte array. byte_gpio_vals = new[4 * num_gpio_vals]; - {< 0) begin apply_reset(); backdoor_override_otp(); - cfg.sw_test_status_vif.set_sw_test_last_iteration(trans_i == num_trans); end // Override the C test kLcExitToken with random data.