[flash_ctrl,dv]Add covergroups for newly added features
This PR added covergroups for follwoing features as part of
addression issue #14527
- Flash instruction execution enable
- RMA entry without flash initialization
- Adjust rd_err sampling point
Other features can be checked by code coverage.
Also moved flash_ctrl_dv_if to flash_ctrl_cov_if
as part of covarege code clean up.
Signed-off-by: Jaedon Kim <jdonjdon@google.com>
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson b/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
index 7021cc1..25a9405 100644
--- a/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
+++ b/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
@@ -419,5 +419,36 @@
- update_err: A shadow register encountered an update error.
'''
}
+ {
+ name: eviction_cg
+ desc: '''
+ Covers eviction with mp_region_cfgs for data and info regions.
+ Sample all 4 rd_buf status.
+ When each buffer hazard is set, capture the address stored in the buffer.
+ Then search from tb data base to see which region the address belong to.
+ After that record the config value (scrambe_en and ecc_en) of the region.
+ Use cross over buffer index, the operation to cause the eviction and
+ the region config values.
+ '''
+ }
+ {
+ name: fetch_code_cg
+ desc: '''
+ Covers whether dut received valid or invalid key value from ral.exec register.
+ Cross with tlul.instr_types.
+ '''
+ }
+ {
+ name: rma_init_cg
+ desc: '''
+ Cover rma operation is executed regardless of when flash_init started.
+ flash_ctrl_hw_rma runs rma operation and flash init in parallel thread.
+ In this test, sample rma state when flash init starts.
+ If rma state is StRmaIdle, which means rma is not started. So it confirms
+ rma start after flash init start.
+ If rma state is [StRmaPageSel:StRmaInvalid], which mean rma is on going.
+ So it confirms rma start before flash init start.
+ '''
+ }
]
}
diff --git a/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_if.sv b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_if.sv
index 33da7ee..c9eb5bc 100644
--- a/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_if.sv
+++ b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_if.sv
@@ -11,13 +11,15 @@
import uvm_pkg::*;
import flash_ctrl_pkg::*;
+ import lc_ctrl_pkg::*;
import dv_utils_pkg::*;
`include "dv_fcov_macros.svh"
- ///////////////////////////////////
- // Control register cover points //
- ///////////////////////////////////
-
- // TODO add covergroups and coverpoints
-
+ logic rd_buf_en;
+ lc_tx_t rma_req;
+ rma_state_e rma_state;
+ logic [10:0] prog_state0;
+ logic [10:0] prog_state1;
+ logic [10:0] lcmgr_state;
+ logic init;
endinterface
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 1ebc9ec..0d46919 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.core
@@ -19,7 +19,6 @@
- flash_ctrl_eflash_ral_pkg.sv
- flash_ctrl_env_pkg.sv
- flash_ctrl_if.sv
- - flash_ctrl_dv_if.sv
- flash_ctrl_mem_if.sv
- flash_mem_bkdr_util.sv: {is_include_file: true}
- flash_mem_addr_attrs.sv: {is_include_file: true}
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
index 6b2843d..a729498 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
@@ -30,9 +30,9 @@
)) begin
`uvm_fatal(`gfn, "failed to get flash_ctrl_vif from uvm_config_db")
end
- if (!uvm_config_db#(virtual flash_ctrl_dv_if)::get(
- this, "", "flash_ctrl_dv_vif", cfg.flash_ctrl_dv_vif)) begin
- `uvm_fatal(`gfn, "failed to get flash_ctrl_dv_vif from uvm_config_db")
+ if (!uvm_config_db#(virtual flash_ctrl_cov_if)::get(
+ this, "", "flash_ctrl_cov_vif", cfg.flash_ctrl_cov_vif)) begin
+ `uvm_fatal(`gfn, "failed to get flash_ctrl_cov_vif from uvm_config_db")
end
for (int i = 0; i < NumBanks; i++) begin
if (!uvm_config_db#(virtual flash_ctrl_mem_if)::get(
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 d0f951b..9b300a5 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
@@ -22,7 +22,7 @@
flash_phy_prim_agent_cfg m_fpp_agent_cfg;
// interface
virtual flash_ctrl_if flash_ctrl_vif;
- virtual flash_ctrl_dv_if flash_ctrl_dv_vif;
+ virtual flash_ctrl_cov_if flash_ctrl_cov_vif;
virtual clk_rst_if clk_rst_vif_flash_ctrl_eflash_reg_block;
virtual clk_rst_if clk_rst_vif_flash_ctrl_prim_reg_block;
virtual flash_ctrl_mem_if flash_ctrl_mem_vif[NumBanks];
@@ -871,141 +871,150 @@
// Use per bank address.
aligned_addr[31:OTFBankId] = 'h0;
for (int i = 0; i < size; i++) begin
- rd_entry.addr = addr_cp;
- if (ecc_mode == FlashSerrTestMode) begin
- err_idx = get_serr_idx();
- if (err_idx >= 0) begin
- // Make sure only assert error only once per address
- if (!serr_addr_tbl[addr_cp].exists(partition)) begin
- serr_addr_tbl[addr_cp][partition] = 1;
- `uvm_info(name,
- $sformatf({"single bit error is inserted at line:%0d(0x%x) %sz",
- " the databit[%0d]"},
- i, addr_cp, partition.name, err_idx), UVM_MEDIUM)
- flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr, err_idx);
- end
- end
- end else if (ecc_mode == FlashIerrTestMode) begin
- randcase
- ierr_pct: begin
- if (derr_otd.exists(rd_entry)) continue;
- if (ierr_addr_tbl[addr_cp].exists(partition)) begin
- ierr_created[caller] = 1;
- end else if (!otf_read_entry.hash.exists(rd_entry)) begin
- ierr_addr_tbl[addr_cp][partition] = 1;
- ierr_created[caller] = 1;
+ // For controller initiated read, in the worst case, each word (8byte) can belong to
+ // different memory protection region.
+ // So before inject bit error, we have to check per word ecc_en
+ // to make sure bit error injection become valid.
+ // If ecc is not enabled, bit error cannot be detected.
+ if (caller == ReadTaskHost || (item.ctrl_rd_region_q[i].ecc_en == MuBi4True)) begin
+ rd_entry.addr = addr_cp;
+ if (ecc_mode == FlashSerrTestMode) begin
+ err_idx = get_serr_idx();
+ if (err_idx >= 0) begin
+ // Make sure only assert error only once per address
+ if (!serr_addr_tbl[addr_cp].exists(partition)) begin
+ serr_addr_tbl[addr_cp][partition] = 1;
`uvm_info(name,
- $sformatf("icv error [%s][%0d] is inserted at line:%0d rd_entry:%p",
- partition.name, bank, i, rd_entry), UVM_MEDIUM)
- flash_icv_flip(mem_bkdr_util_h[partition][bank], aligned_addr, item);
+ $sformatf({"single bit error is inserted at line:%0d(0x%x) %sz",
+ " the databit[%0d]"},
+ i, addr_cp, partition.name, err_idx), UVM_MEDIUM)
+ flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr, err_idx);
end
end
- 10-ierr_pct: begin
- end
- endcase // randcase
- end else begin // if (ecc_mode == FlashIerrTestMode)
- derr_idx.shuffle();
- err_idx = 0;
- if (derr_otd.exists(rd_entry)) continue;
- if (derr_once == 0 || (derr_created[0] | derr_created[1]) == 0 ) begin
- repeat (2) begin
- randcase
- derr_pct: begin
+ end else if (ecc_mode == FlashIerrTestMode) begin
+ randcase
+ ierr_pct: begin
+ if (derr_otd.exists(rd_entry)) continue;
+ if (ierr_addr_tbl[addr_cp].exists(partition)) begin
+ ierr_created[caller] = 1;
+ end else if (!otf_read_entry.hash.exists(rd_entry)) begin
+ ierr_addr_tbl[addr_cp][partition] = 1;
+ ierr_created[caller] = 1;
`uvm_info(name,
- $sformatf({"addr:0x%x %x bit error is inserted at line:%0d",
- " the databit[%0d] err_idx:%0d"},
- aligned_addr, addr_cp, i, derr_idx[err_idx], err_idx),
- UVM_MEDIUM)
+ $sformatf("icv error [%s][%0d] is inserted at line:%0d rd_entry:%p",
+ partition.name, bank, i, rd_entry), UVM_MEDIUM)
+ flash_icv_flip(mem_bkdr_util_h[partition][bank], aligned_addr, item);
+ end
+ end
+ 10-ierr_pct: begin
+ end
+ endcase // randcase
+ end else begin // if (ecc_mode == FlashIerrTestMode)
+ derr_idx.shuffle();
+ err_idx = 0;
+ if (derr_otd.exists(rd_entry)) continue;
+ if (derr_once == 0 || (derr_created[0] | derr_created[1]) == 0 ) begin
+ repeat (2) begin
+ randcase
+ derr_pct: begin
+ `uvm_info(name,
+ $sformatf({"addr:0x%x %x bit error is inserted at line:%0d",
+ " the databit[%0d] err_idx:%0d"},
+ aligned_addr, addr_cp, i, derr_idx[err_idx], err_idx),
+ UVM_MEDIUM)
- // If address already had a single bit error, just skip this line.
- // We could add another bit error instead of modeling read cache behavior.
- if (err_idx != 0 || serr_addr_tbl[addr_cp].exists(partition) == 0) begin
- if (!otf_read_entry.hash.exists(rd_entry)) begin
- flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr,
- derr_idx[err_idx++]);
- serr_addr_tbl[addr_cp][partition] = 1;
+ // If address already had a single bit error, just skip this line.
+ // We could add another bit error instead of modeling read cache behavior.
+ if (err_idx != 0 || serr_addr_tbl[addr_cp].exists(partition) == 0) begin
+ if (!otf_read_entry.hash.exists(rd_entry)) begin
+ flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr,
+ derr_idx[err_idx++]);
+ serr_addr_tbl[addr_cp][partition] = 1;
+ end
+ end
+ if (err_idx == 2) begin
+ `uvm_info(name, $sformatf(" addr:0x%x is added to derr_addr_tbl", addr_cp),
+ UVM_MEDIUM)
+ derr_addr_tbl[addr_cp][partition] = 1;
+ derr_created[caller] = 1;
end
end
- if (err_idx == 2) begin
- `uvm_info(name, $sformatf(" addr:0x%x is added to derr_addr_tbl", addr_cp),
- UVM_MEDIUM)
- derr_addr_tbl[addr_cp][partition] = 1;
- derr_created[caller] = 1;
+ 10-derr_pct: begin
end
- end
- 10-derr_pct: begin
- end
- endcase // randcase
- end // repeat (2)
- end // if (derr_once == 0 || (|derr_created) == 0)
- end // else: !if(ecc_mode == FlashIerrTestMode)
- aligned_addr += 8;
- addr_cp[OTFBankId-1:0] = aligned_addr[OTFBankId-1:0];
+ endcase // randcase
+ end // repeat (2)
+ end // if (derr_once == 0 || (|derr_created) == 0)
+ end // else: !if(ecc_mode == FlashIerrTestMode)
+ aligned_addr += 8;
+ addr_cp[OTFBankId-1:0] = aligned_addr[OTFBankId-1:0];
+ end
end // for (int i = 0; i < size; i++)
if (tail) begin
- rd_entry.addr = addr_cp;
- if (ecc_mode == FlashSerrTestMode) begin
- err_idx = get_serr_idx();
- if (err_idx >= 0) begin
- if (!serr_addr_tbl[addr_cp].exists(partition)) begin
- serr_addr_tbl[addr_cp][partition] = 1;
- `uvm_info(name,
- $sformatf({"last:single bit error is inserted at line:%0d(0x%x) %s",
- " the databit[%0d]"},
- size, addr_cp, partition.name, err_idx), UVM_MEDIUM)
- flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr, err_idx);
- end
- end
- end else if (ecc_mode == FlashIerrTestMode) begin
- randcase
- ierr_pct: begin
- if (derr_otd.exists(rd_entry)) return;
- if (ierr_addr_tbl[addr_cp].exists(partition)) begin
- ierr_created[caller] = 1;
- end else if (!otf_read_entry.hash.exists(rd_entry)) begin
- ierr_addr_tbl[addr_cp][partition] = 1;
- ierr_created[caller] = 1;
+ if (caller == ReadTaskHost || (item.ctrl_rd_region_q[size].ecc_en == MuBi4True)) begin
+ rd_entry.addr = addr_cp;
+ if (ecc_mode == FlashSerrTestMode) begin
+ err_idx = get_serr_idx();
+ if (err_idx >= 0) begin
+ if (!serr_addr_tbl[addr_cp].exists(partition)) begin
+ serr_addr_tbl[addr_cp][partition] = 1;
`uvm_info(name,
- $sformatf("last:icv error[%s][%0d] is inserted at line:%0d rd_entry:%p",
- partition.name, bank, size, rd_entry), UVM_MEDIUM)
- flash_icv_flip(mem_bkdr_util_h[partition][bank], aligned_addr, item);
+ $sformatf({"last:single bit error is inserted at line:%0d(0x%x) %s",
+ " the databit[%0d]"},
+ size, addr_cp, partition.name, err_idx), UVM_MEDIUM)
+ flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr, err_idx);
end
end
- 10-ierr_pct: begin
- end
- endcase // randcase
- end else begin // if (ecc_mode == FlashIerrTestMode)
- derr_idx.shuffle();
- err_idx = 0;
- if (derr_otd.exists(rd_entry)) return;
- if (derr_once == 0 || (derr_created[0] | derr_created[1]) == 0) begin
- repeat (2) begin
- randcase
- derr_pct: begin
+ end else if (ecc_mode == FlashIerrTestMode) begin
+ randcase
+ ierr_pct: begin
+ if (derr_otd.exists(rd_entry)) return;
+ if (ierr_addr_tbl[addr_cp].exists(partition)) begin
+ ierr_created[caller] = 1;
+ end else if (!otf_read_entry.hash.exists(rd_entry)) begin
+ ierr_addr_tbl[addr_cp][partition] = 1;
+ ierr_created[caller] = 1;
`uvm_info(name,
- $sformatf({"last:addr:0x%x %x bit error is inserted at line:%0d",
- " the databit[%0d] err_idx:%0d"},
- aligned_addr, addr_cp, size, derr_idx[err_idx], err_idx),
- UVM_MEDIUM)
- if (err_idx != 0 || serr_addr_tbl[addr_cp].exists(partition) == 0) begin
- if (!otf_read_entry.hash.exists(rd_entry)) begin
- flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr,
- derr_idx[err_idx++]);
- serr_addr_tbl[addr_cp][partition] = 1;
+ $sformatf("last:icv error[%s][%0d] is inserted at line:%0d rd_entry:%p",
+ partition.name, bank, size, rd_entry), UVM_MEDIUM)
+ flash_icv_flip(mem_bkdr_util_h[partition][bank], aligned_addr, item);
+ end
+ end
+ 10-ierr_pct: begin
+ end
+ endcase // randcase
+ end else begin // if (ecc_mode == FlashIerrTestMode)
+ derr_idx.shuffle();
+ err_idx = 0;
+ if (derr_otd.exists(rd_entry)) return;
+ if (derr_once == 0 || (derr_created[0] | derr_created[1]) == 0) begin
+ repeat (2) begin
+ randcase
+ derr_pct: begin
+ `uvm_info(name,
+ $sformatf({"last:addr:0x%x %x bit error is inserted at line:%0d",
+ " the databit[%0d] err_idx:%0d"},
+ aligned_addr, addr_cp, size, derr_idx[err_idx], err_idx),
+ UVM_MEDIUM)
+ if (err_idx != 0 || serr_addr_tbl[addr_cp].exists(partition) == 0) begin
+ if (!otf_read_entry.hash.exists(rd_entry)) begin
+ flash_bit_flip(mem_bkdr_util_h[partition][bank], aligned_addr,
+ derr_idx[err_idx++]);
+ serr_addr_tbl[addr_cp][partition] = 1;
+ end
+ end
+ if (err_idx == 2) begin
+ derr_addr_tbl[addr_cp][partition] = 1;
+ derr_created[caller] = 1;
end
end
- if (err_idx == 2) begin
- derr_addr_tbl[addr_cp][partition] = 1;
- derr_created[caller] = 1;
+ 10-derr_pct: begin
end
- end
- 10-derr_pct: begin
- end
- endcase // randcase
- end
- end // if (derr_once == 0 || (|derr_created) == 0)
- end // else: !if(ecc_mode == FlashIerrTestMode)
+ endcase // randcase
+ end
+ end // if (derr_once == 0 || (|derr_created) == 0)
+ end // else: !if(ecc_mode == FlashIerrTestMode)
+ end
end // if (tail)
endfunction // add_bit_err
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cov.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cov.sv
index 78f8d2d..28bacb6 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cov.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cov.sv
@@ -73,6 +73,21 @@
evic_all_cross : cross evic_idx_cp, evic_op_cp, evic_cfg_cp;
endgroup // eviction_cg
+ covergroup fetch_code_cg with function sample(bit is_exec_key, logic [MuBi4Width-1:0] instr);
+ key_cp: coverpoint is_exec_key;
+ instr_type_cp: coverpoint instr {
+ bins instr_types[2] = {MuBi4True, MuBi4False};
+ bins others = {[0:15]} with (!(item inside {MuBi4True, MuBi4False}));
+ }
+ key_instr_cross : cross key_cp, instr_type_cp;
+ endgroup // fetch_code_cg
+
+ covergroup rma_init_cg with function sample(flash_ctrl_pkg::rma_state_e st);
+ rma_start_cp: coverpoint st {
+ bins rma_st[2] = {StRmaIdle, [StRmaPageSel:StRmaInvalid]};
+ }
+ endgroup // rma_init_cg
+
function new(string name, uvm_component parent);
super.new(name, parent);
control_cg = new();
@@ -80,6 +95,8 @@
error_cg = new();
fifo_lvl_cg = new();
eviction_cg = new();
+ fetch_code_cg = new();
+ rma_init_cg = new();
endfunction : new
virtual function void build_phase(uvm_phase phase);
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 4944a74..4c77195 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
@@ -74,9 +74,21 @@
process_eflash_tl_a_chan_fifo();
process_eflash_tl_d_chan_fifo();
mon_eviction();
+ mon_rma();
join_none
endtask
+ task mon_rma;
+ bit init_set = 0;
+ forever begin
+ @(negedge cfg.clk_rst_vif.clk);
+ if (init_set == 0 && cfg.flash_ctrl_cov_vif.init == 1) begin
+ init_set = 1;
+ if (cfg.en_cov) cov.rma_init_cg.sample(cfg.flash_ctrl_cov_vif.rma_state);
+ end
+ end
+ endtask // mon_rma
+
task mon_eviction;
flash_mp_region_cfg_t my_region;
bit ecc_en, scr_en;
@@ -299,6 +311,13 @@
end
end
end
+ "exec": begin
+ bit is_exec_key = `gmv(ral.exec) == CODE_EXEC_KEY;
+ tlul_pkg::tl_a_user_t a_user = item.a_user;
+ if (cfg.en_cov) begin
+ cov.fetch_code_cg.sample(is_exec_key, a_user.instr_type);
+ end
+ end
default: begin
// TODO: Uncomment once func cover is implemented
// `uvm_info(`gfn, $sformatf("Not for func coverage: %0s", csr.get_full_name()))
@@ -314,6 +333,11 @@
// process the csr req
// for write, update local variable and fifo at address phase
// for read, update predication at address phase and compare at data phase
+ if(!uvm_re_match("err_code*",csr.get_name())) begin
+ if (cfg.en_cov) begin
+ cov.error_cg.sample(item.d_data);
+ end
+ end
case (csr.get_name())
// add individual case item for each csr
"intr_state": begin
@@ -337,9 +361,6 @@
do_read_check = 1'b0;
end
"err_code": begin
- if (cfg.en_cov) begin
- cov.error_cg.sample(item.d_data);
- end
do_read_check = 1'b0;
end
default: begin
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv
index cf977e7..177bfb3 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv
@@ -258,7 +258,6 @@
end
end
-
endtask : body
// Task to initialize the Flash Access (Enable All Regions)
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv
index c0145cd..d2b3ff8 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv
@@ -56,7 +56,7 @@
reset_state_index_e reset_state_index = $urandom_range(DVStRmaPageSel, DVStRmaRdVerify);
// Assert reset during RMA state transition
`uvm_info("Test", $sformatf("Reset index: %s", reset_state_index.name), UVM_LOW)
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.rma_state == dv2rma_st(reset_state_index));,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.rma_state == dv2rma_st(reset_state_index));,
$sformatf("Timed out waiting for rma_state: %s", reset_state_index.name),
state_wait_timeout_ns)
// Give more cycles for long stages
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 a6f1ab5..ca65863 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
@@ -540,9 +540,8 @@
// Address has to be 8byte aligned
rd_entry.addr[2:0] = 'h0;
rd_entry.part = flash_op.partition;
-
if (cfg.ecc_mode > FlashEccEnabled) begin
- if (exp_item.region.ecc_en == MuBi4True && drop == 0) begin
+ if (drop == 0) begin
if (cfg.ecc_mode == FlashSerrTestMode || flash_op.addr[2] == 0) begin
cfg.add_bit_err(flash_op, ReadTaskCtrl, exp_item);
end
@@ -580,8 +579,6 @@
wait_flash_op_done();
end
if (derr_is_set | cfg.ierr_created[0]) begin
- uvm_reg_data_t ldata;
- csr_rd(.ptr(ral.err_code), .value(ldata), .backdoor(1));
`uvm_info("read_flash", $sformatf({"bank:%0d addr: %x(otf:%x) derr_is_set:%0d",
" ierr_created[0]:%0d"}, bank, flash_op.addr,
flash_op.otf_addr, derr_is_set, cfg.ierr_created[0])
@@ -737,6 +734,12 @@
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));
+
+ // issue csr rd to capture coverpoint at sb.
+ if (derr) begin
+ uvm_reg_data_t ldata;
+ csr_rd(.ptr(ral.err_code), .value(ldata));
+ end
if (completed) begin
exp_item.dq.push_back(rdata);
p_sequencer.eg_exp_host_port[bank].write(exp_item);
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv
index b5931f3..d0f8f9a 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv
@@ -46,7 +46,7 @@
csr_wr(.ptr(ral.init), .value(1));
`uvm_info("Test","OTP",UVM_LOW)
otp_model();
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.rd_buf_en == 1);,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.rd_buf_en == 1);,
"Timed out waiting for rd_buf_en",
state_wait_timeout_ns)
`uvm_info("Test", "RMA REQUEST START", UVM_LOW)
@@ -70,7 +70,7 @@
if (reset_index == DVWaitRmaRsp) wait_time = long_wait_timeout_ns;
else wait_time = state_wait_timeout_ns;
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.lcmgr_state == dv2rtl_st(reset_index));,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.lcmgr_state == dv2rtl_st(reset_index));,
$sformatf("Timed out waiting for %s", reset_index.name),
wait_time)
// Since these are single cycle state,
@@ -138,7 +138,7 @@
cfg.clk_rst_vif.wait_clks(2);
`uvm_info("Test","OTP after loop",UVM_LOW)
otp_model();
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.rd_buf_en == 1);,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.rd_buf_en == 1);,
"Timed out waiting for rd_buf_en",
state_wait_timeout_ns)
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
index a4ce41c..9787cdb 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
@@ -69,8 +69,8 @@
string path1, path2;
reset_index_e reset_index = $urandom_range(DVStPrePack, DVStCalcEcc);
`uvm_info("Test", $sformatf("reset_idx: %s", reset_index.name), UVM_MEDIUM)
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.prog_state0 == dv2rtl_st(reset_index) ||
- cfg.flash_ctrl_dv_vif.prog_state1 == dv2rtl_st(reset_index));,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.prog_state0 == dv2rtl_st(reset_index) ||
+ cfg.flash_ctrl_cov_vif.prog_state1 == dv2rtl_st(reset_index));,
$sformatf("Timed out waiting for %s", reset_index.name),
// Use long time out.
// Some unique state does not always guarantee to reach.
@@ -87,7 +87,7 @@
csr_wr(.ptr(ral.init), .value(1));
`uvm_info("Test","OTP",UVM_LOW)
otp_model();
- `DV_SPINWAIT(wait(cfg.flash_ctrl_dv_vif.rd_buf_en == 1);,
+ `DV_SPINWAIT(wait(cfg.flash_ctrl_cov_vif.rd_buf_en == 1);,
"Timed out waiting for rd_buf_en",
state_timeout_ns)
diff --git a/hw/ip/flash_ctrl/dv/tb/tb.sv b/hw/ip/flash_ctrl/dv/tb/tb.sv
index ac89784..ee0224d 100644
--- a/hw/ip/flash_ctrl/dv/tb/tb.sv
+++ b/hw/ip/flash_ctrl/dv/tb/tb.sv
@@ -65,10 +65,6 @@
.rst_n(rst_n)
);
flash_ctrl_if flash_ctrl_if ();
- flash_ctrl_dv_if flash_ctrl_dv_if (
- .clk_i (clk),
- .rst_ni (rst_n)
- );
flash_phy_prim_if fpp_if (
.clk (clk),
.rst_n(rst_n)
@@ -111,14 +107,15 @@
assign otp_rsp.rand_key = flash_ctrl_if.otp_rsp.rand_key;
assign otp_rsp.seed_valid = flash_ctrl_if.otp_rsp.seed_valid;
- assign flash_ctrl_dv_if.rd_buf_en = tb.dut.u_flash_hw_if.rd_buf_en_o;
- assign flash_ctrl_dv_if.rma_req = tb.dut.u_flash_hw_if.rma_req_i;
- assign flash_ctrl_dv_if.rma_state = tb.dut.u_flash_hw_if.rma_state_q;
- assign flash_ctrl_dv_if.prog_state0 =
+ assign dut.u_flash_ctrl_cov_if.rd_buf_en = tb.dut.u_flash_hw_if.rd_buf_en_o;
+ assign dut.u_flash_ctrl_cov_if.rma_req = tb.dut.u_flash_hw_if.rma_req_i;
+ assign dut.u_flash_ctrl_cov_if.rma_state = tb.dut.u_flash_hw_if.rma_state_q;
+ assign dut.u_flash_ctrl_cov_if.prog_state0 =
tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data.u_prog.state_q;
- assign flash_ctrl_dv_if.prog_state1 =
+ assign dut.u_flash_ctrl_cov_if.prog_state1 =
tb.dut.u_eflash.gen_flash_cores[1].u_core.gen_prog_data.u_prog.state_q;
- assign flash_ctrl_dv_if.lcmgr_state = tb.dut.u_flash_hw_if.state_q;
+ assign dut.u_flash_ctrl_cov_if.lcmgr_state = tb.dut.u_flash_hw_if.state_q;
+ assign dut.u_flash_ctrl_cov_if.init = tb.dut.u_flash_hw_if.init_i;
wire flash_test_v;
assign (pull1, pull0) flash_test_v = 1'b1;
@@ -339,8 +336,15 @@
prim_tl_if);
uvm_config_db#(virtual flash_ctrl_if)::set(null, "*.env", "flash_ctrl_vif", flash_ctrl_if);
uvm_config_db#(virtual flash_phy_prim_if)::set(null, "*.env.m_fpp_agent*", "vif", fpp_if);
- uvm_config_db#(virtual flash_ctrl_dv_if)::set(null, "*.env", "flash_ctrl_dv_vif",
- flash_ctrl_dv_if);
+ uvm_config_db#(virtual flash_ctrl_cov_if)::set(null, "*.env", "flash_ctrl_cov_vif",
+ dut.u_flash_ctrl_cov_if);
+ uvm_config_db#(virtual flash_ctrl_mem_if)::set(null, "*.env", "flash_ctrl_mem_vif[0]",
+ dut.u_eflash.u_flash.gen_generic.u_impl_generic.gen_prim_flash_banks[0].
+ u_prim_flash_bank.flash_ctrl_mem_if);
+ uvm_config_db#(virtual flash_ctrl_mem_if)::set(null, "*.env", "flash_ctrl_mem_vif[1]",
+ dut.u_eflash.u_flash.gen_generic.u_impl_generic.gen_prim_flash_banks[1].
+ u_prim_flash_bank.flash_ctrl_mem_if);
+
$timeformat(-9, 1, " ns", 9);
run_test();
end