[flash_ctrl]: ADD FUNCTIONAL COVERAGE
Add covergroups for functional coverage defined in Testplan.
Signed-off-by: Nikola Miladinovic <nikola.miladinovic@ensilica.com>
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson b/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
index 9783eab..b293fad 100644
--- a/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
+++ b/hw/ip/flash_ctrl/data/flash_ctrl_testplan.hjson
@@ -292,30 +292,14 @@
desc: '''
Covers that all operations READ/PROGRAM/ERASE/UNKNOWN have been tested.
Covers that ERASE operation is performed on a page and on entire bank.
- Covers data and info partition selection.
- Covers types of informational partitions.
- Covers if request of erase suspension occured.
- Covers High Endurance feature.
- Covers scramble feature.
- Covers ECC feature.
+ Covers data and info partitions selection.
All valid combinations of the above will also be crossed.
'''
}
{
- name: flash_words_len_cg
+ name: erase_susp_cg
desc: '''
- Covers number of flash words for operations READ/PROGRAM.
- The minimum tested number of words is 0 and the maximum length is 2^12-1.
- Cover an acceptable distribution of lengths has been seen including corner cases
- (length 0 and length 2^12-1).
- '''
- }
- {
- name: region_range_cg
- desc: '''
- Covers all possible numbers of region base pages abd region size pages which are given
- in pages. Cover an acceptable distribution of lengths has been seen including corner
- cases (value 0 and maximum value for which it makes sense to test it).
+ Covers if request of erase suspension occured.
'''
}
{
diff --git a/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov.core b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov.core
new file mode 100644
index 0000000..d04d5e1
--- /dev/null
+++ b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov.core
@@ -0,0 +1,21 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:dv:flash_ctrl_cov"
+description: "FLASH_CTRL functional coverage interface & bind."
+
+filesets:
+ files_dv:
+ depend:
+ - lowrisc:dv:dv_utils
+ - lowrisc:ip:flash_ctrl
+ files:
+ - flash_ctrl_cov_if.sv
+ - flash_ctrl_cov_bind.sv
+ file_type: systemVerilogSource
+
+targets:
+ default:
+ filesets:
+ - files_dv
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
new file mode 100644
index 0000000..21b8f34
--- /dev/null
+++ b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv
@@ -0,0 +1,8 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Binds FLASH_CTRL functional coverage interface to the top level FLASH_CTRL module.
+module flash_ctrl_cov_bind;
+ bind flash_ctrl flash_ctrl_cov_if u_flash_ctrl_cov_if (.*);
+endmodule
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
new file mode 100644
index 0000000..33da7ee
--- /dev/null
+++ b/hw/ip/flash_ctrl/dv/cov/flash_ctrl_cov_if.sv
@@ -0,0 +1,23 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Implements functional coverage for FLASH_CTRL
+
+interface flash_ctrl_cov_if (
+ input logic clk_i,
+ input logic rst_ni
+);
+
+ import uvm_pkg::*;
+ import flash_ctrl_pkg::*;
+ import dv_utils_pkg::*;
+ `include "dv_fcov_macros.svh"
+
+ ///////////////////////////////////
+ // Control register cover points //
+ ///////////////////////////////////
+
+ // TODO add covergroups and coverpoints
+
+endinterface
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 c9505ef..eee66ae 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
@@ -15,18 +15,28 @@
// flash_ctrl_env_cfg: cfg
// covergroups
- // [add covergroups here]
+
+ covergroup control_cg with function sample (flash_op_t flash_cfg_opts);
+ part_cp : coverpoint flash_cfg_opts.partition;
+ erase_cp : coverpoint flash_cfg_opts.erase_type;
+ op_cp : coverpoint flash_cfg_opts.op;
+ op_part_cross : cross part_cp, op_cp;
+ endgroup // control_cg
+
+ covergroup erase_susp_cg with function sample (bit erase_req = 0);
+ erase_susp_cp : coverpoint erase_req {
+ bins erase_susp_true = {1};
+ }
+ endgroup // erase_susp_cg
function new(string name, uvm_component parent);
super.new(name, parent);
- // [instantiate covergroups here]
+ control_cg = new();
+ erase_susp_cg = new();
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
- // [or instantiate covergroups here]
- // Please instantiate sticky_intr_cov array of objects for all interrupts that are sticky
- // See cip_base_env_cov for details
endfunction
endclass
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
index 7dd99fc..4dec2bc 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
@@ -75,12 +75,12 @@
parameter uint FlashFullDataWidth = flash_ctrl_pkg::DataWidth + 4;
// params for words
- parameter uint NUM_PAGE_WORDS = FlashNumBusWordsPerPage;
+ parameter uint NUM_PAGE_WORDS = FlashNumBusWordsPerPage;
parameter uint NUM_BK_DATA_WORDS = FlashNumBusWordsPerBank; // 256 pages
- parameter uint NUM_BK_INFO_WORDS = InfoTypeBusWords[0]; // 10 pages
+ parameter uint NUM_BK_INFO_WORDS = InfoTypeBusWords[0]; // 10 pages
// params for num of pages
- parameter uint NUM_PAGE_PART_DATA = flash_ctrl_pkg::PagesPerBank;
+ parameter uint NUM_PAGE_PART_DATA = flash_ctrl_pkg::PagesPerBank;
parameter uint NUM_PAGE_PART_INFO0 = flash_ctrl_pkg::InfoTypeSize[0];
parameter uint NUM_PAGE_PART_INFO1 = flash_ctrl_pkg::InfoTypeSize[1];
parameter uint NUM_PAGE_PART_INFO2 = flash_ctrl_pkg::InfoTypeSize[2];
@@ -155,21 +155,21 @@
} flash_sec_part_e;
typedef enum {
- AllOnes, // All 1s
- AllZeros, // All 0s
- CustomVal // Custom Value
+ AllOnes, // All 1s
+ AllZeros, // All 0s
+ CustomVal // Custom Value
} flash_scb_wr_e;
typedef struct packed {
- mubi4_t en; // enable this region
- mubi4_t read_en; // enable reads
- mubi4_t program_en; // enable write
- mubi4_t erase_en; // enable erase
- mubi4_t scramble_en; // enable scramble
- mubi4_t ecc_en; // enable ecc
- mubi4_t he_en; // enable high endurance
- uint num_pages; // 0:NumPages % start_page
- uint start_page; // 0:NumPages-1
+ mubi4_t en; // enable this region
+ mubi4_t read_en; // enable reads
+ mubi4_t program_en; // enable write
+ mubi4_t erase_en; // enable erase
+ mubi4_t scramble_en; // enable scramble
+ mubi4_t ecc_en; // enable ecc
+ mubi4_t he_en; // enable high endurance
+ uint num_pages; // 0:NumPages % start_page
+ uint start_page; // 0:NumPages-1
} flash_mp_region_cfg_t;
typedef struct packed {
@@ -197,7 +197,7 @@
typedef bit [TL_AW-1:0] addr_t;
parameter uint ALL_ZEROS = 32'h0000_0000;
- parameter uint ALL_ONES = 32'hffff_ffff;
+ parameter uint ALL_ONES = 32'hffff_ffff;
// Parameter for Probing into the DUT RMA FSM
parameter string PRB_RMA_FSM = "tb.dut.u_flash_hw_if.state_q";
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 127615c..b87ca21 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv
@@ -133,6 +133,7 @@
virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name);
uvm_reg csr;
+ string csr_wr_name = "";
bit do_read_check = 1'b1;
bit write = item.is_write();
uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr);
@@ -141,6 +142,8 @@
bit addr_phase_write = (write && channel == AddrChannel);
bit data_phase_read = (!write && channel == DataChannel);
bit data_phase_write = (write && channel == DataChannel);
+ flash_op_t flash_op_cov;
+ bit erase_req;
// if access was to a valid csr, get the csr handle
if ((is_mem_addr(
@@ -179,9 +182,10 @@
end else if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin
csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr);
`DV_CHECK_NE_FATAL(csr, null)
+ csr_wr_name = csr.get_name();
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
`uvm_info(`gfn, $sformatf("SCB EXP FLASH REG: 0x%0h", csr_addr), UVM_HIGH)
- if ((csr.get_name() == "control") && cfg.scb_check) begin
+ if ((csr_wr_name == "control") && cfg.scb_check) begin
csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1));
curr_op = get_field_val(ral.control.op, data);
if (curr_op == 2) begin //erase op
@@ -214,6 +218,34 @@
end
end
end
+ // coverage collection
+ case (csr_wr_name)
+ "control": begin
+ csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1));
+ curr_op = get_field_val(ral.control.op, data);
+ erase_sel = get_field_val(ral.control.erase_sel, data);
+ part_sel = get_field_val(ral.control.partition_sel, data);
+ info_sel = get_field_val(ral.control.info_sel, data);
+ part = calc_part(part_sel, info_sel);
+ flash_op_cov.partition = part;
+ flash_op_cov.erase_type = erase_sel;
+ flash_op_cov.op = curr_op;
+ if (cfg.en_cov) begin
+ cov.control_cg.sample(flash_op_cov);
+ end
+ end
+ "erase_suspend": begin
+ csr_rd(.ptr(ral.erase_suspend), .value(data), .backdoor(1'b1));
+ erase_req = get_field_val(ral.erase_suspend.req, data);
+ if (cfg.en_cov) begin
+ cov.erase_susp_cg.sample(erase_req);
+ end
+ end
+ default: begin
+ // TODO: Uncomment once func cover is implemented
+ // `uvm_info(`gfn, $sformatf("Not for func coverage: %0s", csr.get_full_name()))
+ end
+ endcase
end
end
diff --git a/hw/ip/flash_ctrl/dv/flash_ctrl_sim.core b/hw/ip/flash_ctrl/dv/flash_ctrl_sim.core
index 6ad0b24..b76c17f 100644
--- a/hw/ip/flash_ctrl/dv/flash_ctrl_sim.core
+++ b/hw/ip/flash_ctrl/dv/flash_ctrl_sim.core
@@ -18,6 +18,7 @@
- lowrisc:dv:mem_bkdr_util
- lowrisc:dv:flash_ctrl_test
- lowrisc:dv:flash_ctrl_sva
+ - lowrisc:dv:flash_ctrl_cov
files:
- tb/tb.sv
file_type: systemVerilogSource
diff --git a/hw/ip/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson b/hw/ip/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson
index 4ad3b5b..a5ad86e 100644
--- a/hw/ip/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson
+++ b/hw/ip/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson
@@ -57,7 +57,7 @@
]
// Add additional tops for simulation.
- sim_tops: ["flash_ctrl_bind"]
+ sim_tops: ["flash_ctrl_bind","flash_ctrl_cov_bind"]
// Default iterations for all tests - each test entry can override this.
reseed: 50