blob: 3c7e06d8334cb79207980f6cda5306a5e95318fc [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_in_irq_vseq extends chip_sw_base_vseq;
`uvm_object_utils(chip_sw_sysrst_ctrl_in_irq_vseq)
`uvm_object_new
localparam string PAD_KEY0_PATH = "tb.dut.IOB3";
localparam string PAD_KEY1_PATH = "tb.dut.IOB6";
localparam string PAD_KEY2_PATH = "tb.dut.IOB8";
localparam string PAD_PWRB_PATH = "tb.dut.IOR13";
localparam string PAD_ACPRES_PATH = "tb.dut.IOC7";
localparam string PAD_LIDOPEN_PATH = "tb.dut.IOC9";
localparam string PAD_ECRST_PATH = "tb.dut.IOR8";
localparam string PAD_FLASHWP_PATH = "tb.dut.IOR9";
int test_phase = 0;
virtual function void set_pads(input bit [7:0] pad_values);
`DV_CHECK(uvm_hdl_force(PAD_PWRB_PATH, pad_values[0]));
`DV_CHECK(uvm_hdl_force(PAD_KEY0_PATH, pad_values[1]));
`DV_CHECK(uvm_hdl_force(PAD_KEY1_PATH, pad_values[2]));
`DV_CHECK(uvm_hdl_force(PAD_KEY2_PATH, pad_values[3]));
`DV_CHECK(uvm_hdl_force(PAD_ACPRES_PATH, pad_values[4]));
`DV_CHECK(uvm_hdl_force(PAD_ECRST_PATH, pad_values[5]));
`DV_CHECK(uvm_hdl_force(PAD_FLASHWP_PATH, pad_values[6]));
`DV_CHECK(uvm_hdl_force(PAD_LIDOPEN_PATH, pad_values[7]));
endfunction
virtual function void write_test_phase(input int phase);
bit [7:0] test_phase[1];
test_phase[0] = phase;
sw_symbol_backdoor_overwrite("kCurrentTestPhase", test_phase);
endfunction
virtual task create_glitch_on_pads(int glitch_duration_ns, bit [7:0] pad_values_prev,
bit [7:0] pad_values_next);
int glitch_pulse_duration_ns;
while (glitch_duration_ns > 0) begin
glitch_pulse_duration_ns = $urandom_range(0, glitch_duration_ns);
glitch_duration_ns -= glitch_pulse_duration_ns;
set_pads(pad_values_prev);
#(glitch_pulse_duration_ns * 1ns);
glitch_pulse_duration_ns = $urandom_range(0, glitch_duration_ns);
glitch_duration_ns -= glitch_pulse_duration_ns;
set_pads(pad_values_next);
#(glitch_pulse_duration_ns * 1ns);
end
endtask
virtual task sync_with_sw();
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInWfi)
endtask
virtual task set_pads_and_synch(int glitch_duration_ns, bit [7:0] pad_values_prev,
bit [7:0] pad_values_next);
sync_with_sw();
// Apply glitch with a total length less than the detection timer and check
// that the interrupt is not triggered in sw side.
set_pads(pad_values_prev);
create_glitch_on_pads(glitch_duration_ns, pad_values_prev, pad_values_next);
set_pads(pad_values_prev);
#10us;
write_test_phase(++test_phase);
sync_with_sw();
// Apply an input pulse with a glitch and check that there is only one
// interrupt is triggered in sw side, not multiple.
set_pads(pad_values_prev);
#10us;
create_glitch_on_pads(glitch_duration_ns, pad_values_prev, pad_values_next);
set_pads(pad_values_next);
write_test_phase(++test_phase);
endtask
virtual task body();
super.body();
// Set initial value.
set_pads(8'b00000000);
// Test 7 H2L input transition.
for (int i = 0; i < 7; i++) begin
set_pads_and_synch(500, (8'b00000001 << i), 8'b00000000);
end
// Test 7 L2H input transition.
for (int i = 0; i < 7; i++) begin
set_pads_and_synch(500, 8'b00000000, (8'b00000001 << i));
end
// Test 4 different combo key intr sources with 2, 3, 4 and 5 combo key
// transition H2L.
set_pads_and_synch(500, 8'b00000011, 8'b00000000);
set_pads_and_synch(500, 8'b00011100, 8'b00000000);
set_pads_and_synch(500, 8'b00011011, 8'b00000000);
set_pads_and_synch(500, 8'b00011111, 8'b00000000);
// Last sync with sw.
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
endtask
endclass