blob: 679aba94dab8ccafc50118b8499dbd5c6afc89b6 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class chip_sw_random_power_glitch_vseq extends chip_sw_base_vseq;
`uvm_object_utils(chip_sw_random_power_glitch_vseq)
`uvm_object_new
// NumRound = 12 is the number of resets in this test. It consists of one PoR
// reset (1st one) + 11 random reset. 11 random resets are 10 sleep mode
// (light sleep and deep sleep) and one normal mode. The reset array rst_idx has
// 12 (NumRound) reset elements where 11 (NumRound-1) random reset sequence is
// ordered using a random variable assa. The last reset does not have to set the next reset type.
parameter int NumSleepType = 2;
// (key rst + pad rst) x 2 (normal sleep/deep sleep)
parameter int NumPadRstEvent = 2 * NumSleepType;
// (sw_req + escalation rst + normal watchdog) x 2
parameter int NumWdogRstEvent = 3 * NumSleepType;
parameter int NumNormalMode = 1;
parameter int NumRound = NumPadRstEvent + NumWdogRstEvent + NumNormalMode + 1;
rand int cycles_after_trigger;
rand int cycles_till_reset;
rand int reset_delay;
constraint cycles_after_trigger_c {cycles_after_trigger inside {[300 : 320]};}
constraint cycles_tll_reset_c {cycles_till_reset inside {[0 : 200]};}
constraint reset_delay_c {reset_delay inside {[0 : 4]};}
rand bit[7:0] assa[NumRound-1];
constraint assa_c {
foreach (assa[i]) assa[i] inside {[0:NumRound-2]};
}
virtual task cpu_init();
bit[7:0] rst_idx[NumRound];
for (int i=0; i< NumRound; i = i+1) begin
if (i == (NumRound-1)) begin
rst_idx[i] = i;
end
else begin
rst_idx[i] = assa[i];
end
end
super.cpu_init();
sw_symbol_backdoor_overwrite("RST_IDX", rst_idx);
endtask
virtual task body();
super.body();
// Wait until we reach the SW test state.
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
`uvm_info(`gfn, "SW test ready", UVM_MEDIUM)
repeat (NumRound) begin
// The timeout for this test needs to be larger than 30_000_000, otherwise certain seeds
// like:
// ./util/dvsim/dvsim.py hw/top_earlgrey/dv/chip_sim_cfg.hjson -i \
// chip_sw_pwrmgr_random_sleep_power_glitch_reset --build-seed 4232114340 \
// --fixed-seed 2369106033 --verbosity m
// will fail.
`DV_WAIT(
cfg.sw_logger_vif.printed_log ==
"Booting and setting deep sleep followed by hw por" ||
cfg.sw_logger_vif.printed_log ==
"Booting and setting normal sleep followed by hw por" ||
cfg.sw_logger_vif.printed_log ==
"Booting and setting deep sleep followed by glitch reset" ||
cfg.sw_logger_vif.printed_log ==
"Booting and setting normal sleep followed by glitch reset" ||
cfg.sw_logger_vif.printed_log == "Last Booting" ||
cfg.sw_logger_vif.printed_log == "Test finish", , 40_000_000
)
`uvm_info(`gfn, "HW Booting is called", UVM_MEDIUM)
if (cfg.sw_logger_vif.printed_log ==
"Booting and setting deep sleep followed by glitch reset" ||
cfg.sw_logger_vif.printed_log ==
"Booting and setting normal sleep followed by glitch reset")
begin
`uvm_info(`gfn, "SW message delivered to TB", UVM_MEDIUM)
if (cfg.sw_logger_vif.printed_log ==
"Booting and setting deep sleep followed by glitch reset") begin
`uvm_info(`gfn, "glitch for deep sleep", UVM_MEDIUM)
cfg.ast_supply_vif.glitch_vcmain_pok_on_next_low_power_trigger();
end
else begin
`uvm_info(`gfn, "glitch for normal sleep", UVM_MEDIUM)
cfg.ast_supply_vif.glitch_vcmain_pok_on_next_core_sleeping_trigger(cycles_after_trigger);
end
end
else if (cfg.sw_logger_vif.printed_log ==
"Booting and setting deep sleep followed by hw por" |
cfg.sw_logger_vif.printed_log ==
"Booting and setting normal sleep followed by hw por") begin
`uvm_info(`gfn, "SW message delivered to TB", UVM_MEDIUM)
repeat (10 + cycles_till_reset) @cfg.chip_vif.pwrmgr_low_power_if.cb;
`uvm_info(`gfn, $sformatf("POR reset req set after fixed delay : %d + variable delay : %d",
10, cycles_till_reset), UVM_MEDIUM)
execute_reset();
end
end
endtask
virtual task pre_start();
super.pre_start();
endtask
task execute_reset();
`uvm_info(`gfn, "wait for low power entry", UVM_MEDIUM)
`DV_WAIT(cfg.chip_vif.pwrmgr_low_power_if.low_power == 1)
`uvm_info(`gfn, "reset after low power entry", UVM_MEDIUM)
assert_por_reset_deep_sleep (reset_delay);
endtask // execute_reset
endclass