blob: 43ac217a60e8429afc43151f1cdb08f3ddd70489 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// This sequence sends write traffic with or without tlul memory
// bus write path error injection.
// This test will trigger fatal_std_err so clear fatal alert at the end of the test by reset.
class flash_ctrl_wr_path_intg_vseq extends flash_ctrl_rw_vseq;
`uvm_object_utils(flash_ctrl_wr_path_intg_vseq)
`uvm_object_new
task body();
string path = "tb.dut.u_prog_fifo.wdata_i[38]";
int state_timeout_ns = 100000; // 100us
// Don't select a partition defined as read-only
cfg.seq_cfg.avoid_ro_partitions = 1'b1;
repeat(5) begin
flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(scr_ecc_cfg));
`uvm_info(`gfn, "Assert write path err", UVM_LOW)
`DV_CHECK(uvm_hdl_force(path, 1'b1))
$assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A");
// disable tl_rsp error check
cfg.m_tl_agent_cfg.check_tl_errs = 0;
fork
begin
uvm_reg_data_t ldata;
repeat(cfg.otf_num_rw) begin
`DV_CHECK_RANDOMIZE_FATAL(this)
ctrl = rand_op;
bank = rand_op.addr[OTFBankId];
if (ctrl.partition == FlashPartData) begin
num = ctrl_num;
end else begin
num = ctrl_info_num;
end
// Since we force bit 38 to 1, create more than one bus words
// to make sure data integrity error is created.
if (fractions < 4) begin
fractions = 4;
end
randcase
cfg.otf_wr_pct: begin
cfg.scb_h.expected_alert["fatal_std_err"].expected = 1;
cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 2000;
cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000;
// prog_err and mp_err
set_otf_exp_alert("recov_err");
prog_flash(ctrl, bank, 1, fractions, 1);
csr_spinwait(.ptr(ral.op_status.err), .exp_data(1'b1));
end
cfg.otf_rd_pct:read_flash(ctrl, bank, num, fractions);
endcase
end // repeat (cfg.otf_num_rw)
// Check std_fault.prog_intg_err, err_code.prog_err
collect_err_cov_status(ral.std_fault_status);
csr_rd_check(.ptr(ral.std_fault_status.prog_intg_err), .compare_value(1));
csr_rd_check(.ptr(ral.err_code.prog_err), .compare_value(1));
csr_rd_check(.ptr(ral.op_status.err), .compare_value(1));
ldata = get_csr_val_with_updated_field(ral.err_code.prog_err, ldata, 1);
csr_wr(.ptr(ral.err_code), .value(ldata));
ldata = get_csr_val_with_updated_field(ral.op_status.err, ldata, 0);
csr_wr(.ptr(ral.op_status), .value(ldata));
end
begin
for (int i = 0; i < cfg.otf_num_hr; ++i) begin
fork
send_rand_host_rd();
join_none
#0;
end
csr_utils_pkg::wait_no_outstanding_access();
end
join
`uvm_info(`gfn, "Wait until all drain", UVM_LOW)
cfg.clk_rst_vif.wait_clks(100);
`DV_CHECK(uvm_hdl_release(path))
cfg.seq_cfg.disable_flash_init = 1;
cfg.seq_cfg.en_init_keys_seeds = 0;
apply_reset();
csr_wr(.ptr(ral.init), .value(1));
`uvm_info("Test","OTP",UVM_LOW)
otp_model();
`DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);,
"Timed out waiting for rd_buf_en",
state_timeout_ns)
cfg.clk_rst_vif.wait_clks(10);
end
// disable tlul_err_cnt check
cfg.tlul_core_obs_cnt = cfg.tlul_core_exp_cnt;
endtask
endclass