blob: e94fd8f2d455daa464a8d66ab2319c35ab300a7d [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// The test to create transition to invalid state from any reset transitions.
class pwrmgr_reset_invalid_vseq extends pwrmgr_base_vseq;
`uvm_object_utils(pwrmgr_reset_invalid_vseq)
`uvm_object_new
// Create enum to map rtl local sparse state
// to continuous dv state.
typedef enum bit [3:0] {
DVWaitDisClks = 0,
DVWaitNvmShutDown = 1,
DVWaitResetPrep = 2,
DVWaitLowPower = 3,
DVWaitEnableClocks = 4,
DVWaitReleaseLcRst = 5,
DVWaitOtpInit = 6,
DVWaitLcInit = 7,
DVWaitAckPwrUp = 8,
DVWaitRomCheck = 9,
DVWaitStrap = 10,
DVWaitActive = 11,
DVWaitInvalid = 12
} reset_index_e;
constraint wakeups_c {wakeups == 0;}
constraint wakeups_en_c {wakeups_en == 0;}
function void post_randomize();
sw_rst_from_rstmgr = get_rand_mubi4_val(.t_weight(8), .f_weight(4), .other_weight(4));
super.post_randomize();
endfunction
task body();
reset_index_e reset_index;
resets_t enabled_resets;
string path = "tb.dut.u_fsm.fsm_invalid_i";
int num_of_target_states = 11;
wait_for_fast_fsm_active();
check_reset_status('0);
$assertoff(0, "tb.dut.u_cdc.u_clr_reqack.SyncReqAckHoldReq");
for (int i = 0; i < num_of_target_states; ++i) begin
`uvm_info(`gfn, $sformatf("Starting new round %0d", i), UVM_MEDIUM)
`DV_CHECK_RANDOMIZE_FATAL(this)
setup_interrupt(.enable(en_intr));
fork
create_any_reset_event();
begin
int wait_time_ns = 10000;
`DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == dv2rtl_st(reset_index));, $sformatf(
"Timed out waiting for state %s", reset_index.name), wait_time_ns)
@cfg.clk_rst_vif.cbn;
`uvm_info(`gfn, $sformatf("Will cause invalid state forcing %s = 1", path), UVM_MEDIUM)
`DV_CHECK(uvm_hdl_force(path, 1))
@cfg.clk_rst_vif.cb;
end
join
@cfg.clk_rst_vif.cb;
`DV_CHECK(uvm_hdl_release(path))
`DV_CHECK(cfg.pwrmgr_vif.fast_state, pwrmgr_pkg::FastPwrStateInvalid)
`uvm_info(`gfn, "All good, resetting for next round", UVM_MEDIUM)
repeat (10) @cfg.clk_rst_vif.cb;
apply_reset();
reset_index++;
wait_for_fast_fsm_active();
end
endtask
task create_any_reset_event();
resets_t enabled_resets = resets_en & resets;
`uvm_info(`gfn, $sformatf(
"Enabled resets=0x%x, power_reset=%b, escalation=%b, sw_reset=%b, ndm_reset=%b",
enabled_resets,
power_glitch_reset,
escalation_reset,
sw_rst_from_rstmgr == prim_mubi_pkg::MuBi4True,
ndm_reset
), UVM_MEDIUM)
`uvm_info(`gfn, "Trying to write to reset_en CSR", UVM_MEDIUM)
csr_wr(.ptr(ral.reset_en[0]), .value(resets_en));
// This is necessary to propagate reset_en.
wait_for_csr_to_propagate_to_slow_domain();
// Trigger resets. The glitch is sent prior to the externals since if it is delayed
// it will cause a separate reset after the externals, which complicates the checks.
if (power_glitch_reset) send_power_glitch();
cfg.clk_rst_vif.wait_clks(cycles_before_reset);
if (cycles_before_reset == 0) enabled_resets = 0;
`uvm_info(`gfn, $sformatf("Sending resets=0x%x", resets), UVM_MEDIUM)
cfg.pwrmgr_vif.update_resets(resets);
`uvm_info(`gfn, $sformatf("Sending sw reset from rstmgr=%b", sw_rst_from_rstmgr), UVM_MEDIUM)
if (escalation_reset) send_escalation_reset();
if (ndm_reset) send_ndm_reset();
cfg.pwrmgr_vif.update_sw_rst_req(sw_rst_from_rstmgr);
endtask : create_any_reset_event
function pwrmgr_pkg::fast_pwr_state_e dv2rtl_st(reset_index_e idx);
case (idx)
DVWaitDisClks: return pwrmgr_pkg::FastPwrStateDisClks;
DVWaitNvmShutDown: return pwrmgr_pkg::FastPwrStateNvmShutDown;
DVWaitResetPrep: return pwrmgr_pkg::FastPwrStateResetPrep;
DVWaitLowPower: return pwrmgr_pkg::FastPwrStateLowPower;
DVWaitEnableClocks: return pwrmgr_pkg::FastPwrStateEnableClocks;
DVWaitReleaseLcRst: return pwrmgr_pkg::FastPwrStateReleaseLcRst;
DVWaitOtpInit: return pwrmgr_pkg::FastPwrStateOtpInit;
DVWaitLcInit: return pwrmgr_pkg::FastPwrStateLcInit;
DVWaitAckPwrUp: return pwrmgr_pkg::FastPwrStateAckPwrUp;
DVWaitRomCheck: return pwrmgr_pkg::FastPwrStateRomCheckDone;
DVWaitStrap: return pwrmgr_pkg::FastPwrStateStrap;
DVWaitActive: return pwrmgr_pkg::FastPwrStateActive;
DVWaitInvalid: return pwrmgr_pkg::FastPwrStateInvalid;
default: begin
`uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx))
end
endcase
endfunction : dv2rtl_st
endclass : pwrmgr_reset_invalid_vseq