[rv_timer/dv] add sticky interrupt coverage
1. rv_timer_env_cov,rv_timer_scoreboard: sticky interrupt coverage and
updated step bins.
2. rv_timer_sanity_vseq: removed wait for outstanding access
3. rv_timer_cfg_update_on_fly_vseq: Check for sticky interrupt
diff --git a/hw/ip/rv_timer/dv/env/rv_timer_env_cov.sv b/hw/ip/rv_timer/dv/env/rv_timer_env_cov.sv
index bc03a8c..c502cd8 100644
--- a/hw/ip/rv_timer/dv/env/rv_timer_env_cov.sv
+++ b/hw/ip/rv_timer/dv/env/rv_timer_env_cov.sv
@@ -16,7 +16,7 @@
uint64 mtime,
uint64 mtime_cmp);
cp_step: coverpoint step {
- bins step_all_val[] = {[0:$]};
+ bins step_all_val[] = {[1:$]};
}
cp_prescale: coverpoint prescale {
option.auto_bin_max = 256;
@@ -65,10 +65,13 @@
//Create cfg coverage for each timer
foreach (cfg_values_cov_obj[timer]) begin
cfg_values_cov_obj[timer] = new($sformatf("rv_timer-%0d", timer));
+ sticky_intr_cov[{"rv_timer_sticky_intr_pin", $sformatf("%0d", timer)}] =
+ new(.name({"rv_timer_sticky_intr_pin", $sformatf("%0d", timer)}), .toggle_cov_en(0));
end
//Create toggle coverage for each prescale bit
foreach (rv_timer_prescale_values_cov_obj[timer, bit_num]) begin
- rv_timer_prescale_values_cov_obj[timer][bit_num] = new($sformatf("rv_timer-%0d-prescale-%0d", timer, bit_num));
+ rv_timer_prescale_values_cov_obj[timer][bit_num] = new($sformatf("rv_timer-%0d-prescale-%0d",
+ timer, bit_num));
end
//Create all timers active coverage for each hart
foreach (ctrl_reg_cov_obj[hart]) begin
diff --git a/hw/ip/rv_timer/dv/env/rv_timer_scoreboard.sv b/hw/ip/rv_timer/dv/env/rv_timer_scoreboard.sv
index 3415b05..2a277df 100644
--- a/hw/ip/rv_timer/dv/env/rv_timer_scoreboard.sv
+++ b/hw/ip/rv_timer/dv/env/rv_timer_scoreboard.sv
@@ -132,7 +132,22 @@
string intr_state_str = $sformatf("intr_state%0d", i);
if (csr_name == intr_state_str) begin
// Intr_state reg is W1C, update expected status with RAL mirrored val
- intr_status_exp[i] = get_reg_fld_mirror_value(ral, intr_state_str);
+ for (int j = 0; j < NUM_TIMERS; j++) begin
+ int timer_idx = i * NUM_TIMERS + j;
+ if (item.a_data[j] == 1) begin
+ if (en_timers[i][j] == 0) begin
+ intr_status_exp[i][j] = 0;
+ if (cfg.en_cov) begin
+ cov.sticky_intr_cov[{"rv_timer_sticky_intr_pin",
+ $sformatf("%0d", timer_idx)}].sample(1'b0);
+ end
+ end
+ else if (cfg.en_cov) begin // sticky interrupt
+ cov.sticky_intr_cov[{"rv_timer_sticky_intr_pin",
+ $sformatf("%0d", timer_idx)}].sample(1'b1);
+ end
+ end
+ end
break;
end
end
diff --git a/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_cfg_update_on_fly_vseq.sv b/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_cfg_update_on_fly_vseq.sv
index c7e8717..c3cae09 100644
--- a/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_cfg_update_on_fly_vseq.sv
+++ b/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_cfg_update_on_fly_vseq.sv
@@ -139,6 +139,9 @@
read_intr_status_reg(.hart(hart), .status_val(read_data));
`DV_CHECK_EQ_FATAL(read_data, (1 << timer))
+ // clear intr status randomly while timer is still enable and check for sticky interrupt
+ if ($urandom_range(0, 1)) clear_intr_state(.hart(hart), .timer(timer));
+
// disable timers and clear interrupt
cfg_timer(.hart(hart), .timer(timer), .enable(1'b0));
clear_intr_state(.hart(hart), .timer(timer));
diff --git a/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_sanity_vseq.sv b/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_sanity_vseq.sv
index 6c2b8d7..f54ba1f 100644
--- a/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_sanity_vseq.sv
+++ b/hw/ip/rv_timer/dv/env/seq_lib/rv_timer_sanity_vseq.sv
@@ -114,7 +114,6 @@
if (assert_reset) begin
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
cfg.clk_rst_vif.wait_clks(delay);
- csr_utils_pkg::wait_no_outstanding_access();
apply_reset("HARD");
end
join_none