blob: 820f1a78889c74a863e16db17da764d4329e51bd [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_sysrst_ctrl_ulp_z3_wakeup_vseq extends chip_sw_base_vseq;
`uvm_object_utils(chip_sw_sysrst_ctrl_ulp_z3_wakeup_vseq)
`uvm_object_new
// The value of configured debounce value
localparam uint DEBOUNCE_SW_VALUE = 20;
typedef enum bit [7:0] {
PHASE_INIT = 0,
PHASE_DRIVE_ZERO = 1,
PHASE_WAIT_NO_WAKEUP = 2,
PHASE_GLITCH_LID_OPEN = 3,
PHASE_WAIT_WAKEUP = 4,
PHASE_DONE = 5
} test_phases_e;
virtual task pre_start();
super.pre_start();
// Initialize the pad input to 0 to avoid having X values in the initial test phase.
// The following correspond to IOR13, IOC7, IOC9 respectively
cfg.chip_vif.pwrb_in_if.pins_pd[0] = 1;
cfg.chip_vif.sysrst_ctrl_if.pins_pd[4] = 1;
cfg.chip_vif.sysrst_ctrl_if.pins_pd[5] = 1;
endtask
virtual task post_start();
//cfg.chip_vif.pwrb_in_if.disconnect();
//cfg.chip_vif.sysrst_ctrl_if.disconnect();
cfg.chip_vif.pwrb_in_if.pins_pd[0] = 1;
cfg.chip_vif.sysrst_ctrl_if.pins_pd[4] = 1;
cfg.chip_vif.sysrst_ctrl_if.pins_pd[5] = 1;
super.post_start();
endtask
virtual function void drive_zero_pads();
// PAD_PWRB_PATH <-> IOR13
cfg.chip_vif.pwrb_in_if.drive_pin(0, 1'b0);
// PAD_ACPRESENT_PATH <-> IOC7
cfg.chip_vif.sysrst_ctrl_if.drive_pin(4, 1'b0);
// PAD_LIDOPEN_PATH <-> IOC9
cfg.chip_vif.sysrst_ctrl_if.drive_pin(5, 1'b0);
endfunction
virtual task glitch_lid_open();
uint glitch_loop_cnt = $urandom_range(1, DEBOUNCE_SW_VALUE - 1);
bit glitchy_bit = 1'b1;
// The following loop ends before the second sampling of debounce happens
for (int i = 0; i < glitch_loop_cnt ; i++) begin
// PAD_LIDOPEN_PATH <- glitchy_bit;
cfg.chip_vif.sysrst_ctrl_if.drive_pin(5, glitchy_bit);
cfg.chip_vif.aon_clk_por_rst_if.wait_clks(1);
glitchy_bit = ~glitchy_bit;
end
cfg.chip_vif.sysrst_ctrl_if.drive_pin(5, 1'b1);
endtask
virtual function void write_test_phase(test_phases_e phase);
bit [7:0] test_phase[1];
test_phase[0] = phase;
sw_symbol_backdoor_overwrite("kTestPhase", test_phase);
endfunction
virtual function void check_wakeup_pin();
logic wakeup_result;
// Read PAD_Z3WAKEUP_PATH <-> IOB7
wakeup_result = cfg.chip_vif.pinmux_wkup_if.sample_pin(0);
`DV_CHECK_EQ_FATAL(wakeup_result, 1'b1);
endfunction
virtual task wait_wakeup_time();
// Wait until we are sure that we passed the second sampling of debounce logic
cfg.chip_vif.aon_clk_por_rst_if.wait_clks(DEBOUNCE_SW_VALUE);
endtask
virtual task sync_with_sw();
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi)
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
endtask
virtual task body();
super.body();
// TODO(lowRISC/opentitan:#13373): Revisit pad assignments.
// pinmux_wkup_vif (at Iob7) is re-used for PinZ3WakeupOut
// due to lack of unused pins. Disable the default drive
// to this pin.
cfg.chip_vif.pinmux_wkup_if.drive_en_pin(0, 0);
write_test_phase(PHASE_INIT);
sync_with_sw();
drive_zero_pads();
write_test_phase(PHASE_DRIVE_ZERO);
sync_with_sw();
wait_wakeup_time();
write_test_phase(PHASE_WAIT_NO_WAKEUP);
// Skip sync_with_sw, because SW starts sleeping after Wfi
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi)
glitch_lid_open();
write_test_phase(PHASE_GLITCH_LID_OPEN);
sync_with_sw();
wait_wakeup_time();
write_test_phase(PHASE_WAIT_WAKEUP);
check_wakeup_pin();
sync_with_sw();
write_test_phase(PHASE_DONE);
endtask
endclass : chip_sw_sysrst_ctrl_ulp_z3_wakeup_vseq