diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index 379e254e6a68ea..c59592377ac821 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -925,7 +925,11 @@ uvm_test_seq: chip_sw_lc_volatile_raw_unlock_vseq sw_images: ["//sw/device/tests/sim_dv:lc_ctrl_volatile_raw_unlock_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] - run_opts: ["+use_otp_image=OtpTypeLcStRaw"] + run_opts: [ + "+use_otp_image=OtpTypeLcStRaw", + # We set this to zero if the volatile RAW unlock mechanism is expected + # to be disabled (this should be the case in production silicon). + "+exp_volatile_raw_unlock_en=0"] run_timeout_mins: 120 } { @@ -935,7 +939,10 @@ en_run_modes: ["sw_test_mode_test_rom"] run_opts: [ "+use_otp_image=OtpTypeLcStRaw", - "+chip_clock_source=ChipClockSourceExternal48Mhz"] + "+chip_clock_source=ChipClockSourceExternal48Mhz", + # We set this to zero if the volatile RAW unlock mechanism is expected + # to be disabled (this should be the case in production silicon). + "+exp_volatile_raw_unlock_en=0"] run_timeout_mins: 120 } { 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 e73670285f2253..d31648fb141bee 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 @@ -801,9 +801,18 @@ class chip_sw_base_vseq extends chip_base_vseq; cfg.m_jtag_riscv_agent_cfg.allow_errors = 0; endtask + virtual task wait_lc_token_error(bit allow_err = 1, int max_attempt = 5000); + cfg.m_jtag_riscv_agent_cfg.allow_errors = allow_err; + wait_lc_status(LcTokenError, max_attempt); + cfg.m_jtag_riscv_agent_cfg.allow_errors = 0; + endtask + // Use JTAG interface to transit LC_CTRL from RAW to TEST_UNLOCKED* states // using the VOLATILE_RAW_UNLOCK mode of operation. - virtual task jtag_lc_state_volatile_raw_unlock(chip_jtag_tap_e target_strap); + // If this operation is expected to fail due to the absence of the mechanism in HW, set the + // expect_success argument to 0. + virtual task jtag_lc_state_volatile_raw_unlock(chip_jtag_tap_e target_strap, + bit expect_success = 0); bit [TL_DW-1:0] current_lc_state; bit [TL_DW-1:0] transition_ctrl; bit use_ext_clk = 1'b0; @@ -840,8 +849,15 @@ class chip_sw_base_vseq extends chip_base_vseq; ral.lc_ctrl.transition_ctrl.get_offset(), p_sequencer.jtag_sequencer_h, transition_ctrl); - `DV_CHECK_FATAL(transition_ctrl & (1 << 1), {"VOLATILE_RAW_UNLOCK is not supported by this ", - "top level. Check the SecVolatileRawUnlockEn parameter configuration."}) + // In this case we expect the transition_ctrl bit to stay 0. + if (expect_success) begin + `DV_CHECK_FATAL(transition_ctrl & (1 << 1), {"VOLATILE_RAW_UNLOCK is not supported by this ", + "top level. Check the SecVolatileRawUnlockEn parameter configuration."}) + end else begin + `DV_CHECK_FATAL(!(transition_ctrl & (1 << 1)), {"VOLATILE_RAW_UNLOCK is not expected to be ", + "supported by this top-level. Check the SecVolatileRawUnlockEn parameter " + "configuration"}) + end if (use_ext_clk) begin wait_lc_ext_clk_switched(); @@ -869,10 +885,15 @@ class chip_sw_base_vseq extends chip_base_vseq; 1); if (target_strap == JtagTapLc) begin - wait_lc_transition_successful(.max_attempt(max_attempt)); - jtag_riscv_agent_pkg::jtag_write_csr(ral.lc_ctrl.claim_transition_if.get_offset(), - p_sequencer.jtag_sequencer_h, - prim_mubi_pkg::MuBi8False); + // The token should be invalid for this transition. + if (expect_success) begin + wait_lc_transition_successful(.max_attempt(max_attempt)); + jtag_riscv_agent_pkg::jtag_write_csr(ral.lc_ctrl.claim_transition_if.get_offset(), + p_sequencer.jtag_sequencer_h, + prim_mubi_pkg::MuBi8False); + end else begin + wait_lc_token_error(.max_attempt(max_attempt)); + end end else begin cfg.clk_rst_vif.wait_clks($urandom_range(10000, 20000)); end diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv index dec13dd8f1cad8..c671e8de4ac986 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_volatile_raw_unlock_vseq.sv @@ -11,8 +11,12 @@ class chip_sw_lc_volatile_raw_unlock_vseq extends chip_sw_base_vseq; // image. bit rom_prod_mode = 1'b0; + // Indicates whether we expect the volatile RAW unlock feature to be enabled in HW or not. + bit exp_volatile_raw_unlock_en = 1'b0; + virtual task pre_start(); void'($value$plusargs("rom_prod_mode=%0d", rom_prod_mode)); + void'($value$plusargs("exp_volatile_raw_unlock_en=%0d", exp_volatile_raw_unlock_en)); cfg.chip_vif.tap_straps_if.drive(JtagTapLc); super.pre_start(); endtask @@ -40,42 +44,45 @@ class chip_sw_lc_volatile_raw_unlock_vseq extends chip_sw_base_vseq; // VOLATILE_RAW_UNLOCK does not require a reset after completion. // Applying a reset will move the device back to RAW state in this case. - jtag_lc_state_volatile_raw_unlock(JtagTapRvDm); + jtag_lc_state_volatile_raw_unlock(.target_strap(JtagTapRvDm), + .expect_success(exp_volatile_raw_unlock_en)); reset_jtag_tap(); - if (rom_prod_mode) begin - // The production ROM is not instrumented to report `sw_test_status`, so - // we wait for the PC to advance before continuing with the test. The - // PC was taken from the ROM disassembly. - `DV_WAIT(cfg.chip_vif.probed_cpu_pc.pc_wb >= 8194) - end else begin - // In RAW state the ROM should halt as RomExecEn is not set yet. - `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInBootRomHalt) + // If we're expecting the feature to be enabled, the device should boot. + if (exp_volatile_raw_unlock_en) begin + if (rom_prod_mode) begin + // The production ROM is not instrumented to report `sw_test_status`, so + // we wait for the PC to advance before continuing with the test. The + // PC was taken from the ROM disassembly. + `DV_WAIT(cfg.chip_vif.probed_cpu_pc.pc_wb >= 8194) + end else begin + // In RAW state the ROM should halt as RomExecEn is not set yet. + `DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInBootRomHalt) + end + + // Use the frontend interface to configure the RomExecEn OTP value. A + // reset is required to have otp_ctrl sample the new OTP value. + `uvm_info(`gfn, "Configuring RomExecEng", UVM_LOW) + jtag_dm_activation_seq.start(p_sequencer.jtag_sequencer_h); + `uvm_info(`gfn, $sformatf("rv_dm_activated: %0d", cfg.m_jtag_riscv_agent_cfg.rv_dm_activated), + UVM_LOW) + cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 1; + jtag_otp_program32(otp_ctrl_reg_pkg::CreatorSwCfgRomExecEnOffset, 1); + + cfg.chip_vif.tap_straps_if.drive(JtagTapLc); + cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 0; + apply_reset(); + reset_jtag_tap(); + + // Wait for `rom_ctrl` to complete the ROM check. This will give the dut + // enough time to configure the TAP interface before any JTAG agents send + // any commands. + wait_rom_check_done(); + + // Second VOLATILE_RAW_UNLOCK does not change the TAP interface to rv_dm + // so that we can check the completion status through that interface. + // After this, the rest of the test should proceed. + jtag_lc_state_volatile_raw_unlock(JtagTapLc); end - - // Use the frontend interface to configure the RomExecEn OTP value. A - // reset is required to have otp_ctrl sample the new OTP value. - `uvm_info(`gfn, "Configuring RomExecEng", UVM_LOW) - jtag_dm_activation_seq.start(p_sequencer.jtag_sequencer_h); - `uvm_info(`gfn, $sformatf("rv_dm_activated: %0d", cfg.m_jtag_riscv_agent_cfg.rv_dm_activated), - UVM_LOW) - cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 1; - jtag_otp_program32(otp_ctrl_reg_pkg::CreatorSwCfgRomExecEnOffset, 1); - - cfg.chip_vif.tap_straps_if.drive(JtagTapLc); - cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 0; - apply_reset(); - reset_jtag_tap(); - - // Wait for `rom_ctrl` to complete the ROM check. This will give the dut - // enough time to configure the TAP interface before any JTAG agents send - // any commands. - wait_rom_check_done(); - - // Second VOLATILE_RAW_UNLOCK does not change the TAP interface to rv_dm - // so that we can check the completion status through that interface. - // After this, the rest of the test should proceed. - jtag_lc_state_volatile_raw_unlock(JtagTapLc); - endtask endclass