[flash_ctrl,dv] flash disable test
Signed-off-by: Jaedon Kim <jdonjdon@google.com>
[flash_ctrl,dv] flash disable test
Signed-off-by: Jaedon Kim <jdonjdon@google.com>
diff --git a/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv
index 21b8f34..ee2e927 100644
--- a/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv
+++ b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv
@@ -3,6 +3,21 @@
// SPDX-License-Identifier: Apache-2.0
//
// Binds FLASH_CTRL functional coverage interface to the top level FLASH_CTRL module.
+`define FLASH_COV_LC_TX_BIND(__name) \
+ bind flash_ctrl cip_lc_tx_cov_if u_``__name``_cov_if( \
+ .rst_ni (rst_ni), \
+ .val (``__name``_i) \
+ );
+
module flash_ctrl_cov_bind;
bind flash_ctrl flash_ctrl_cov_if u_flash_ctrl_cov_if (.*);
+
+ `FLASH_COV_LC_TX_BIND(lc_creator_seed_sw_rw_en)
+ `FLASH_COV_LC_TX_BIND(lc_owner_seed_sw_rw_en)
+ `FLASH_COV_LC_TX_BIND(lc_iso_part_sw_rd_en)
+ `FLASH_COV_LC_TX_BIND(lc_iso_part_sw_wr_en)
+ `FLASH_COV_LC_TX_BIND(lc_seed_hw_rd_en)
+ `FLASH_COV_LC_TX_BIND(lc_escalate_en)
+ `FLASH_COV_LC_TX_BIND(lc_nvm_debug_en)
+
endmodule
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core
index 0d46919..94f1628 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core
@@ -79,6 +79,7 @@
- seq_lib/flash_ctrl_re_evict_vseq.sv: {is_include_file: true}
- seq_lib/flash_ctrl_oversize_error_vseq.sv: {is_include_file: true}
- seq_lib/flash_ctrl_connect_vseq.sv: {is_include_file: true}
+ - seq_lib/flash_ctrl_disable_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
generate:
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
index 9b300a5..2e3e33a 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
@@ -173,8 +173,24 @@
int rd_lvl = 0;
int wr_lvl = 0;
- // force all region read enable
+ // force all region enable to '1'
+ // '0' doesn't affect randomization
bit en_always_read = 0;
+ bit en_always_erase = 0;
+ bit en_always_prog = 0;
+ bit en_always_all = 0;
+
+ // This is not tied to plusarg.
+ // Internal use only.
+ bit en_always_any = 0;
+
+ // tlul error transaction counter
+ // compare at the end of sim
+ int tlul_core_exp_cnt = 0;
+ int tlul_core_obs_cnt = 0;
+
+
+
`uvm_object_utils(flash_ctrl_env_cfg)
`uvm_object_new
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv
index 55041ef..b27f61e 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv
@@ -154,7 +154,12 @@
$sformatf("unexpected double bit error 0x%x", err_addr))
end
end else begin
- if (exp.derr & obs.derr) begin
+ if (exp.exp_err) begin
+ `uvm_info("process_eg_host",
+ $sformatf("expected other tlul error start:%x",
+ exp.start_addr),
+ UVM_MEDIUM)
+ end else if (exp.derr & obs.derr) begin
`uvm_info("process_eg_host",
$sformatf("expected double bit error by redundant write start:%x",
exp.start_addr),
@@ -272,7 +277,12 @@
send.raw_fq[i] = exp.fq[i];
end
end
- if (exp.derr & send.derr) begin
+ if (exp.exp_err) begin
+ `uvm_info("process_read",
+ $sformatf("expected other tlul error start:%x",
+ exp.start_addr),
+ UVM_MEDIUM)
+ end else if (exp.derr & send.derr) begin
`uvm_info("process_read",
$sformatf("expected double bit error by redundant write start:%x",
exp.start_addr),
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
index 4c77195..529e618 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
@@ -43,6 +43,9 @@
bit ecc_error_addr[bit [AddrWidth - 1 : 0]];
int over_rd_err[addr_t];
+ //host error injection
+ bit in_error_addr[bit [AddrWidth - 1 : 0]];
+
// TLM agent fifos
uvm_tlm_analysis_fifo #(tl_seq_item) eflash_tl_a_chan_fifo;
uvm_tlm_analysis_fifo #(tl_seq_item) eflash_tl_d_chan_fifo;
@@ -426,6 +429,9 @@
if (cfg.scb_check && cfg.check_full_scb_mem_model) begin
cfg.check_mem_model();
end
+
+ `DV_CHECK_EQ(cfg.tlul_core_obs_cnt, cfg.tlul_core_exp_cnt,
+ "core_tlul_error_cnt mismatch")
endfunction
virtual function flash_dv_part_e calc_part(bit part_sel, bit [1:0] info_sel);
@@ -772,16 +778,16 @@
// Overriden function from cip_base_scoreboard, to handle TL/UL Error seen on Hardware Interface
// when using Code Access Restrictions (EXEC)
virtual function bit predict_tl_err(tl_seq_item item, tl_channels_e channel, string ral_name);
- bit ecc_err;
+ bit ecc_err, in_err;
// For flash, address has to be 8byte aligned.
ecc_err = ecc_error_addr.exists({item.a_addr[AddrWidth-1:3],3'b0});
-
+ in_err = in_error_addr.exists({item.a_addr[AddrWidth-1:3],3'b0});
`uvm_info("predic_tl_err_dbg",
- $sformatf("addr:0x%x(%x) ecc_err:%0d channel:%s ral_name:%s",
+ $sformatf("addr:0x%x(%x) ecc_err:%0d in_err:%0d channel:%s ral_name:%s",
{item.a_addr[AddrWidth-1:3],3'b0},
- item.a_addr, ecc_err,
+ item.a_addr, ecc_err, in_err,
channel.name, ral_name
- ), UVM_HIGH)
+ ), UVM_MEDIUM)
if (over_rd_err.exists(item.a_addr)) begin
if (channel == DataChannel) begin
@@ -792,14 +798,22 @@
return 1;
end
- if ((ral_name == cfg.flash_ral_name) && (get_flash_instr_type_err(item, channel))) return (1);
- else if (ecc_err) begin
- if (channel == DataChannel) begin
- `DV_CHECK_EQ(item.d_error, 1, $sformatf("On interface %s, TL item: %s, ecc_err:%0d",
- ral_name, item.sprint(uvm_default_line_printer),
- ecc_err))
- return 1;
- end
+ if (ral_name == cfg.flash_ral_name) begin
+ if (get_flash_instr_type_err(item, channel)) return (1);
+ end else begin
+ if (cfg.tlul_core_exp_cnt > 0 && item.d_error == 1) begin
+ cfg.tlul_core_obs_cnt++;
+ return 1;
+ end
+ if (ecc_err | in_err) begin
+ if (channel == DataChannel) begin
+ `DV_CHECK_EQ(item.d_error, 1,
+ $sformatf("On interface %s, TL item: %s, ecc_err:%0d in_err:%0d",
+ ral_name, item.sprint(uvm_default_line_printer),
+ ecc_err, in_err))
+ return 1;
+ end
+ end
end
return (super.predict_tl_err(item, channel, ral_name));
endfunction : predict_tl_err
diff --git a/hw/ip/flash_ctrl/dv/env/flash_otf_item.sv b/hw/ip/flash_ctrl/dv/env/flash_otf_item.sv
index 98f20e9..ece14c9 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_otf_item.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_otf_item.sv
@@ -17,6 +17,9 @@
flash_mp_region_cfg_t ctrl_rd_region_q[$];
bit derr;
+ // other expected error than double bit ecc
+ bit exp_err;
+
bit skip_err_chk;
addr_t err_addr, eaddr_q[$];
function new(string name = "flash_otf_item");
@@ -24,6 +27,7 @@
head_pad = 0;
tail_pad = 0;
derr = 0;
+ exp_err = 0;
skip_err_chk = 0;
endfunction // new
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv
new file mode 100644
index 0000000..7d89729
--- /dev/null
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv
@@ -0,0 +1,40 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Test flash access disable feature by
+// Global escalation : Set lc_escalate_en to On
+// sw command (flash_ctrl.DIS)
+class flash_ctrl_disable_vseq extends flash_ctrl_otf_base_vseq;
+ `uvm_object_utils(flash_ctrl_disable_vseq)
+ `uvm_object_new
+
+
+ virtual task body();
+ bit exp_err;
+
+ send_rand_ops();
+ exp_err = set_flash_disable();
+
+ if (exp_err) begin
+ `uvm_info("SEQ", $sformatf("assa disable is set"), UVM_MEDIUM)
+ csr_utils_pkg::wait_no_outstanding_access();
+ cfg.m_tl_agent_cfg.check_tl_errs = 0;
+
+ end
+ `uvm_info("SEQ", $sformatf("assa disable txn start"), UVM_MEDIUM)
+ // mp error or tlul error expected
+
+ send_rand_ops(1, exp_err);
+
+ `DV_CHECK_EQ(cfg.tlul_core_obs_cnt, cfg.tlul_core_exp_cnt)
+ endtask // body
+
+ // Assign static value for now.
+ // Will be randomzie for V2S.
+ function bit set_flash_disable();
+ cfg.flash_ctrl_vif.lc_escalate_en = lc_ctrl_pkg::On;
+
+ return (cfg.flash_ctrl_vif.lc_escalate_en == lc_ctrl_pkg::On);
+ endfunction
+endclass
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
index 94c5f18..08b35e1 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
@@ -38,7 +38,7 @@
constraint all_ent_c {
solve all_entry_en before rand_regions, rand_info;
- if (cfg.en_always_read) all_entry_en == 1;
+ if (cfg.en_always_any) all_entry_en == 1;
else all_entry_en dist { 1 := 1, 0 := 4};
}
constraint scr_ecc_c {
@@ -54,7 +54,6 @@
};
rand_regions[i].num_pages inside {[1 : FlashNumPages - rand_regions[i].start_page]};
rand_regions[i].num_pages <= 32;
- if (cfg.en_always_read) rand_regions[i].read_en == MuBi4True;
rand_regions[i].scramble_en dist { MuBi4True := 4, MuBi4False := 1};
rand_regions[i].ecc_en dist { MuBi4True := 4, MuBi4False := 1};
}
@@ -107,6 +106,20 @@
allow_spec_info_acc dist { 3'h7 := 1, 3'h0 := 1, [1:6] :/ 2};
}
+ function void post_randomize();
+ super.post_randomize();
+ foreach (rand_regions[i]) begin
+ if (cfg.en_always_read) rand_regions[i].read_en = MuBi4True;
+ if (cfg.en_always_prog) rand_regions[i].program_en = MuBi4True;
+ if (cfg.en_always_erase) rand_regions[i].erase_en = MuBi4True;
+ end
+ foreach (rand_info[i, j, k]) begin
+ if (cfg.en_always_read) rand_info[i][j][k].read_en = MuBi4True;
+ if (cfg.en_always_prog) rand_info[i][j][k].program_en = MuBi4True;
+ if (cfg.en_always_erase) rand_info[i][j][k].erase_en = MuBi4True;
+ end
+ endfunction // post_randomize
+
virtual task pre_start();
// Erased page doesn't go through descramble.
// To maintain high stress rate,
@@ -217,10 +230,11 @@
// @arg: bank: bank index to access flash
// @arg: num : number of 8 words range: [1 : 32]
// @arg: wd : number of 4byte (TL bus unit) : default : 16
- task prog_flash(ref flash_op_t flash_op, input int bank, int num, int wd = 16);
+ task prog_flash(ref flash_op_t flash_op, input int bank, int num, int wd = 16,
+ bit in_err = 0);
data_q_t flash_data_chunk;
flash_otf_item exp_item;
- bit poll_fifo_status = 1;
+ bit poll_fifo_status = in_err;
bit [15:0] lcnt = 0;
bit [flash_ctrl_pkg::BusAddrByteW-1:0] start_addr, end_addr;
data_4s_t tmp_data;
@@ -347,8 +361,11 @@
flash_ctrl_intr_write(flash_op, flash_program_data);
end else begin
flash_ctrl_start_op(flash_op);
+ if (in_err) begin
+ cfg.tlul_core_exp_cnt += flash_op.num_words;
+ end
flash_ctrl_write(flash_program_data, poll_fifo_status);
- wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns));
+ if (!in_err) wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns));
end
if (is_odd == 1) begin
tmp_data = {32{1'b1}};
@@ -405,10 +422,10 @@
// @arg: num : number of 8 words range: [1 : 32]
// @arg: wd : number of 4byte (TL bus unit) : default : 16
task read_flash(ref flash_op_t flash_op, input int bank, int num, int wd = 16,
- int overrd = 0);
+ int overrd = 0, bit in_err = 0);
data_q_t flash_read_data;
flash_otf_item exp_item;
- bit poll_fifo_status = 1;
+ bit poll_fifo_status = ~in_err;
bit [flash_ctrl_pkg::BusAddrByteW-1:0] start_addr, end_addr;
int page;
bit overflow = 0;
@@ -572,11 +589,17 @@
flash_ctrl_intr_read(flash_op, flash_read_data);
end else begin
flash_ctrl_start_op(flash_op);
+ if (in_err) begin
+ cfg.tlul_core_exp_cnt += flash_op.num_words;
+ end
flash_ctrl_read(flash_op.num_words, flash_read_data, poll_fifo_status);
if (overrd > 0) begin
overread(flash_op, bank, num, overrd);
end
wait_flash_op_done();
+
+ if (!in_err) wait_flash_op_done();
+
end
if (derr_is_set | cfg.ierr_created[0]) begin
`uvm_info("read_flash", $sformatf({"bank:%0d addr: %x(otf:%x) derr_is_set:%0d",
@@ -593,6 +616,7 @@
cfg.ierr_created[0] = 0;
end
+ exp_item.exp_err |= in_err;
exp_item.dq = flash_read_data;
exp_item.fq = exp_item.dq2fq(flash_read_data);
if (drop) begin
@@ -632,7 +656,7 @@
// @arg : bank : bank index to access flash.
// @arg : num : number of 4byte data to read countinuously
// by 4 byte apart.
- task otf_direct_read(bit [OTFHostId-2:0] addr, int bank, int num, int dbg = -1);
+ task otf_direct_read(bit [OTFHostId-2:0] addr, int bank, int num, int dbg = -1, bit in_err);
bit[TL_AW-1:0] tl_addr, st_addr, end_addr;
data_4s_t rdata;
flash_otf_item exp_item;
@@ -722,8 +746,12 @@
if (cfg.scb_h.ecc_error_addr.exists({tl_addr[31:3],3'h0}) | derr_is_set) derr = 1;
end
cfg.otf_read_entry.insert(rd_entry, flash_op);
- `uvm_info("direct_read", $sformatf("%0d:%0d bank:%0d exec: 0x%x derr:%0d",
- dbg, i, bank, tl_addr, derr), UVM_MEDIUM)
+ `uvm_info("direct_read", $sformatf("%0d:%0d bank:%0d exec: 0x%x derr:%0d in_err:%0d",
+ dbg, i, bank, tl_addr, derr, in_err), UVM_MEDIUM)
+ if (in_err) cfg.scb_h.in_error_addr[{tl_addr[31:3],3'h0}] = 1;
+
+ derr |= in_err;
+
if (cfg.ecc_mode > FlashSerrTestMode) begin
if (derr & cfg.scb_h.do_alert_check) begin
cfg.scb_h.exp_alert["fatal_err"] = 1;
@@ -731,6 +759,12 @@
cfg.scb_h.exp_alert_contd["fatal_err"] = 10000;
end
end
+
+ // in_err is currently used to address error caused by disable flash.
+ if (in_err) begin
+ set_otf_exp_alert("fatal_err");
+ end
+
cfg.inc_otd_tbl(bank, tl_addr, FlashPartData);
do_direct_read(.addr(tl_addr), .mask('1), .blocking(1), .rdata(rdata),
.completed(completed), .exp_err_rsp(derr));
@@ -742,6 +776,8 @@
end
if (completed) begin
exp_item.dq.push_back(rdata);
+ exp_item.exp_err |= in_err;
+
p_sequencer.eg_exp_host_port[bank].write(exp_item);
`uvm_info("direct_read",
$sformatf("SEQ:st_addr:%x addr:%x rcvd:%0d rdata:%x derr:%0d",
@@ -1038,8 +1074,6 @@
`uvm_info("direct_readback", $sformatf("idx:%0d: bank:%0d exec: 0x%x page:%0d derr:%0d",
i, bank, tl_addr, page, derr), UVM_MEDIUM)
-
-
cfg.inc_otd_tbl(bank, tl_addr, FlashPartData);
do_direct_read(.addr(tl_addr), .mask('1), .blocking(1), .rdata(rdata),
.completed(completed), .exp_err_rsp(derr));
@@ -1065,7 +1099,7 @@
endtask
- task erase_flash(flash_op_t flash_op, int bank);
+ task erase_flash(flash_op_t flash_op, int bank, bit in_err = 0);
bit drop = 0;
int page;
flash_mp_region_cfg_t my_region;
@@ -1082,9 +1116,10 @@
flash_op.otf_addr[10:9] = cfg.tgt_pre[flash_op.partition][TgtEr];
end
end
- `uvm_info("erase_flash", $sformatf("{bank:%0d otf_addr:0x%0h, page:%0d part:%s",
+ `uvm_info("erase_flash", $sformatf("{bank:%0d otf_addr:0x%0h, page:%0d part:%s erase_type:%s",
bank, flash_op.otf_addr, cfg.addr2page(flash_op.addr),
- flash_op.partition.name), UVM_MEDIUM)
+ flash_op.partition.name, flash_op.erase_type.name),
+ UVM_MEDIUM)
if (flash_op.partition == FlashPartData) begin
page = cfg.addr2page(flash_op.addr);
my_region = cfg.get_region(page);
@@ -1099,10 +1134,8 @@
flash_op.op.name, my_region), UVM_MEDIUM)
set_otf_exp_alert("recov_err");
end
-
flash_ctrl_start_op(flash_op);
- wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns));
-
+ if (!in_err) wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns));
endtask
function void update_otf_mem_read_zone(flash_dv_part_e part, int bank, addr_t addr);
@@ -1196,7 +1229,7 @@
endfunction // flash_otf_init
// Send direct host read to both bankds 'host_num' times.
- virtual task send_rand_host_rd(int num = -1, int dbg = -1);
+ virtual task send_rand_host_rd(int num = -1, int dbg = -1, bit in_err = 0);
flash_op_t host;
int host_num, host_bank;
@@ -1206,7 +1239,7 @@
else host_num = $urandom_range(1,128);
host_bank = $urandom_range(0,1);
- otf_direct_read(host.otf_addr, host_bank, host_num, dbg);
+ otf_direct_read(host.otf_addr, host_bank, host_num, dbg, in_err);
endtask // send_rand_host_rd
// Clean up tb vars. Used for multiple sequence run.
@@ -1224,6 +1257,7 @@
cfg.serr_addr_tbl.delete();
cfg.scb_h.ecc_error_addr.delete();
+ cfg.scb_h.in_error_addr.delete();
global_derr_is_set = 0;
cfg.otf_read_entry.hash.delete();
@@ -1281,6 +1315,30 @@
update_p2r_map(cfg.mp_regions);
endtask
+ task send_rand_ops(int iter = 1, bit exp_err = 0);
+ flash_op_t ctrl;
+ int num, bank;
+
+ repeat (iter) 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
+ randcase
+ 1:prog_flash(ctrl, bank, 1, fractions, exp_err);
+ 1:read_flash(ctrl, bank, 1, fractions, 0, exp_err);
+ 1: begin
+ send_rand_host_rd(.in_err(exp_err));
+ end
+ 1:erase_flash(ctrl, bank, exp_err);
+ endcase // randcase
+ end
+ endtask
+
function void update_partition_access(bit[2:0] acc);
cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off;
cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off;
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv
index be8d2c4..eed6b65 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv
@@ -47,4 +47,5 @@
`include "flash_ctrl_re_evict_vseq.sv"
`include "flash_ctrl_oversize_error_vseq.sv"
`include "flash_ctrl_connect_vseq.sv"
+`include "flash_ctrl_disable_vseq.sv"
`include "flash_ctrl_stress_all_vseq.sv"
diff --git a/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson b/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
index ba0eb8e..672a352 100644
--- a/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
+++ b/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
@@ -313,19 +313,26 @@
uvm_test_seq: flash_ctrl_prog_reset_vseq
run_opts: ["+scb_otf_en=1", "+ecc_mode=1"]
reseed: 30
- }
+ }
{
name: flash_ctrl_rw_evict
uvm_test_seq: flash_ctrl_rw_evict_vseq
run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"]
reseed: 40
- }
+ }
{
name: flash_ctrl_re_evict
uvm_test_seq: flash_ctrl_re_evict_vseq
run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"]
reseed: 20
- }
+ }
+ {
+ name: flash_ctrl_disable
+ uvm_test_seq: flash_ctrl_disable_vseq
+ run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+en_always_all=1",
+ "+bypass_alert_ready_to_end_check=1"]
+ reseed: 1
+ }
{
name: flash_ctrl_sec_cm
run_timeout_mins: 120
diff --git a/hw/ip/flash_ctrl/dv/tests/flash_ctrl_base_test.sv b/hw/ip/flash_ctrl/dv/tests/flash_ctrl_base_test.sv
index b1a557f..3c7bd76 100644
--- a/hw/ip/flash_ctrl/dv/tests/flash_ctrl_base_test.sv
+++ b/hw/ip/flash_ctrl/dv/tests/flash_ctrl_base_test.sv
@@ -62,7 +62,17 @@
void'($value$plusargs("otf_num_hr=%0d", cfg.otf_num_hr));
void'($value$plusargs("otf_wr_pct=%0d", cfg.otf_wr_pct));
void'($value$plusargs("otf_rd_pct=%0d", cfg.otf_rd_pct));
+ void'($value$plusargs("en_always_all=%0d", cfg.en_always_all));
void'($value$plusargs("en_always_read=%0d", cfg.en_always_read));
+ void'($value$plusargs("en_always_erase=%0d", cfg.en_always_erase));
+ void'($value$plusargs("en_always_prog=%0d", cfg.en_always_prog));
+ if (cfg.en_always_all) begin
+ cfg.en_always_read = 1;
+ cfg.en_always_prog = 1;
+ cfg.en_always_erase = 1;
+ end
+ cfg.en_always_any = (cfg.en_always_read | cfg.en_always_erase |
+ cfg.en_always_prog);
endfunction
task run_phase(uvm_phase phase);