blob: bb7a89d59381a37ac4798ebd93b8a83a5efc2f60 [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_lc_ctrl_scrap_vseq extends chip_sw_base_vseq;
`uvm_object_utils(chip_sw_lc_ctrl_scrap_vseq)
`uvm_object_new
rand lc_ctrl_state_pkg::dec_lc_state_e src_state;
rand bit perform_transition_via_sw;
constraint valid_src_state_c {
!(src_state inside {DecLcStScrap, DecLcStInvalid, DecLcStPostTrans, DecLcStEscalate});
solve src_state before perform_transition_via_sw;
}
// don't try to perform transition via SW for the following states
constraint transition_via_sw_c {
src_state inside {DecLcStRaw,
DecLcStTestLocked0,
DecLcStTestLocked1,
DecLcStTestLocked2,
DecLcStTestLocked3,
DecLcStTestLocked4,
DecLcStTestLocked5,
DecLcStTestLocked6} ->
perform_transition_via_sw == 0;
}
function void pre_randomize();
super.pre_randomize();
// disable source state randomization if it's set by the command line
// and set the source state value
if ($test$plusargs("src_dec_state")) begin
this.valid_src_state_c.constraint_mode(0);
this.src_state.rand_mode(0);
// source state is randomized by default,
// but if a plusarg is supplied, assign the given value
`DV_GET_ENUM_PLUSARG(lc_ctrl_state_pkg::dec_lc_state_e, src_state, src_dec_state)
`uvm_info(`gfn, $sformatf("Source state is %0s", src_state.name), UVM_MEDIUM)
end
endfunction : pre_randomize
function void post_randomize();
super.post_randomize();
// a guard to check we didn't screw up
`DV_CHECK_FATAL(src_state != DecLcStScrap)
endfunction : post_randomize
virtual task pre_start();
cfg.chip_vif.tap_straps_if.drive(JtagTapLc);
super.pre_start();
endtask : pre_start
virtual function void backdoor_override_otp();
// Override the LC partition to TestLocked1 state.
cfg.mem_bkdr_util_h[Otp].otp_write_lc_partition_state(
lc_ctrl_dv_utils_pkg::encode_lc_state(src_state));
endfunction : backdoor_override_otp
virtual task dut_init(string reset_kind = "HARD");
super.dut_init(reset_kind);
backdoor_override_otp();
endtask : dut_init
protected task sync_with_sw();
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusBooted)
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest)
endtask : sync_with_sw
protected task perform_transition_to_scrap();
// perform transition through JTAG if we're not using SW transition
// or if SW transition isn't allowed (RAW/TEST_LOCKED*)
if (!perform_transition_via_sw) begin : jtag_transition
// acquire the LC controller access to registers
wait_lc_ready(.allow_err(1));
// perform a LC state transition
jtag_lc_state_transition(src_state, DecLcStScrap);
end : jtag_transition
// else, we're performing the transition though SW
else begin : sw_transition
// sync with SW, and let perform the transition
sync_with_sw();
end : sw_transition
// wait for transition to end
wait_lc_transition_successful();
// LC state transition requires a chip reset.
`uvm_info(`gfn, $sformatf("Applying reset after lc transition from %s state", src_state.name),
UVM_MEDIUM)
apply_reset();
endtask : perform_transition_to_scrap
task cpu_init();
super.cpu_init();
// tell SW whether the transition is done by JTAG or SW
sw_symbol_backdoor_overwrite("kPerformTransitionBySW", {perform_transition_via_sw});
endtask : cpu_init
virtual task body();
bit [BUS_DW-1:0] state;
super.body();
// perform the transition to SCRAP state
perform_transition_to_scrap();
// acquire again access to LC controller
// this now can only be done by JTAG, as we're in SCRAP state
wait_lc_initialized(.allow_err(1));
// read the LC state from the LC controller and
// check LC state is indeed in SCRAP
jtag_riscv_agent_pkg::jtag_read_csr(ral.lc_ctrl.lc_state.get_offset(),
p_sequencer.jtag_sequencer_h, state);
`DV_CHECK_EQ(state, {DecLcStateNumRep{DecLcStScrap}})
endtask : body
task post_start();
// post-transition reset is performed via SV
// however, as it's the last step of the test
// and SW can't execute (SCRAP state),
// we'll need to override the SW test status
// from there
override_test_status_and_finish(.passed(1));
super.post_start();
endtask : post_start
endclass : chip_sw_lc_ctrl_scrap_vseq