Skip to content

[dv] V2S Coverage Implementation #1895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions doc/03_reference/coverage_plan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,36 @@ Basic read/write functionality must be tested on all implemented CSRs.
CSRs addresses do not need to be crossed with the variety of CSR instructions as these all use the same basic read & write interface into ``ibex_cs_registers``.
Coverage of the above points will be sampled at the ``ibex_cs_registers`` interface (as opposed to sampling CSR instructions).

Security Countermeasures
^^^^^^^^^^^^^^^^^^^^^^^^
For more detail about each security countermeasure in Ibex see :ref:`security`

* ``cp_data_ind_timing`` - Enabling/Disabling "Data Independent Timing" feature.

* ``cp_data_ind_timing_instr`` - Executing each instruction category while data independent timing feature is enabled.

* ``cp_dummy_instr_en`` - Enabling/Disabling "Dummy Instruction Insertion" feature.

* ``cp_dummy_instr_mask`` - Frequency of injection for the dummy instructions.

* ``cp_dummy_instr_type`` - Type of the injected dummy instruction.

* ``cp_dummy_instr`` - Executing each instruction category while dummy instruction insertion feature is enabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add coverage for interrupt and debug requests whilst a dummy instruction is being executed (different points for IF, ID/EX and WB stages).

Copy link
Contributor

@andreaskurth andreaskurth Nov 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just added two commits that should add this coverage


* ``cp_dummy_instr_if_stage`` - The IF stage handles a dummy instruction.

* ``cp_dummy_instr_id_stage`` - The ID/EX stage handles a dummy instruction.

* ``cp_dummy_instr_wb_stage`` - The WB stage handles a dummy instruction.

* ``cp_rf_a_ecc_err``, ``cp_rf_b_ecc_err`` - Register file integrity (ECC) fault is seen for port A/B.

* ``cp_icache_ecc_err`` - ICache has seen an integrity (ECC) fault.

* ``cp_lockstep_err`` - Lockstep glitch fault seen.

* ``cp_rf_we_glitch_err`` - Register file write enable glitch fault seen.

Miscellaneous
^^^^^^^^^^^^^
Various points of interest do not fit into the categories above.
Expand Down Expand Up @@ -348,3 +378,11 @@ There must be a documented reason a particular bin is added to the illegal or ig
* ``pmp_iside_priv_bits_cross``, ``pmp_iside2_priv_bits_cross``, ``pmp_dside_priv_bits_cross``, PMP regions x permissions x access fail/pass x privilege level

* Three crosses, one for each PMP channel (instruction, instruction 2 and data).

* ``dummy_instr_config_cross`` - Dummy Instruction Type x Dummy Instruction Insertion Frequency to explore all possible configurations.

* ``rf_ecc_err_cross`` - ECC Error on Port A x ECC Error on Port B to explore all possible combinations of reported ECC errors.

* ``debug_req_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while a debug request arrives.

* ``irq_pending_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while an IRQ is pending.
58 changes: 57 additions & 1 deletion dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ interface core_ibex_fcov_if import ibex_pkg::*; (
input debug_mode,

input fcov_csr_read_only,
input fcov_csr_write
input fcov_csr_write,

input fcov_rf_ecc_err_a_id,
input fcov_rf_ecc_err_b_id
);
`include "dv_fcov_macros.svh"
import uvm_pkg::*;
Expand Down Expand Up @@ -381,6 +384,10 @@ interface core_ibex_fcov_if import ibex_pkg::*; (
(id_stall_type == IdStallTypeNone) && (id_stall_type_last != IdStallTypeNone) &&
id_stall_type_last_valid;

// V2S Related Probes for Top-Level
logic rf_we_glitch_err;
logic lockstep_glitch_err;

covergroup uarch_cg @(posedge clk_i);
option.per_instance = 1;
option.name = "uarch_cg";
Expand Down Expand Up @@ -423,6 +430,36 @@ interface core_ibex_fcov_if import ibex_pkg::*; (
cp_id_stage_state : coverpoint id_stage_state;
cp_wb_stage_state : coverpoint wb_stage_state;

// V2S Coverpoints
cp_data_ind_timing: coverpoint cs_registers_i.data_ind_timing_o;
cp_data_ind_timing_instr: coverpoint id_instr_category iff (cs_registers_i.data_ind_timing_o) {
// Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
// revisit if any issues are seen
illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
}

cp_dummy_instr_en: coverpoint cs_registers_i.dummy_instr_en_o;
cp_dummy_instr_mask: coverpoint cs_registers_i.dummy_instr_mask_o;
cp_dummy_instr_type: coverpoint if_stage_i.fcov_dummy_instr_type;
cp_dummy_instr: coverpoint id_instr_category iff (cs_registers_i.dummy_instr_en_o) {
// Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
// revisit if any issues are seen
illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
}

// Each stage sees a dummy instruction.
cp_dummy_instr_if_stage: coverpoint if_stage_i.fcov_insert_dummy_instr;
cp_dummy_instr_id_stage: coverpoint if_stage_i.dummy_instr_id_o;
cp_dummy_instr_wb_stage: coverpoint wb_stage_i.dummy_instr_wb_o;

cp_rf_a_ecc_err: coverpoint fcov_rf_ecc_err_a_id;
cp_rf_b_ecc_err: coverpoint fcov_rf_ecc_err_b_id;

cp_icache_ecc_err : coverpoint if_stage_i.icache_ecc_error_o;

cp_lockstep_err : coverpoint lockstep_glitch_err;
cp_rf_we_glitch_err : coverpoint rf_we_glitch_err;

// TODO: MRET/WFI in debug mode?
// Specific cover points for these as `id_instr_category` will be InstrCategoryPrivIllegal when
// executing these instructions in U-mode.
Expand Down Expand Up @@ -673,6 +710,25 @@ interface core_ibex_fcov_if import ibex_pkg::*; (
// Only care about specific debug CSRs
ignore_bins ignore = !binsof(cp_csr_write) intersect {`DEBUG_CSRS};
}

// V2S Crosses

dummy_instr_config_cross: cross cp_dummy_instr_type, cp_dummy_instr_mask
iff (cs_registers_i.dummy_instr_en_o);

rf_ecc_err_cross: cross cp_rf_a_ecc_err, cp_rf_b_ecc_err
iff (id_stage_i.instr_valid_i);

// Each stage sees a debug request while executing a dummy instruction.
debug_req_dummy_instr_if_stage_cross: cross cp_debug_req, cp_dummy_instr_if_stage;
debug_req_dummy_instr_id_stage_cross: cross cp_debug_req, cp_dummy_instr_id_stage;
debug_req_dummy_instr_wb_stage_cross: cross cp_debug_req, cp_dummy_instr_wb_stage;

// Each stage sees an interrupt request while executing a dummy instruction.
irq_pending_dummy_instr_if_stage_cross: cross cp_irq_pending, cp_dummy_instr_if_stage;
irq_pending_dummy_instr_id_stage_cross: cross cp_irq_pending, cp_dummy_instr_id_stage;
irq_pending_dummy_instr_wb_stage_cross: cross cp_irq_pending, cp_dummy_instr_wb_stage;

endgroup

bit en_uarch_cov;
Expand Down
6 changes: 4 additions & 2 deletions dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@
+require_signature_addr=1
+instr_cnt=10000
+randomize_csr=1
+gen_all_csrs_by_default=1
+add_csr_write=MSTATUS,MEPC,MCAUSE,MTVAL,0x7c0,0x7c1
+enable_unaligned_load_store=1
+suppress_pmp_setup=1
+disable_pmp_exception_handler=1
Expand Down Expand Up @@ -633,8 +635,8 @@
+instr_cnt=10000
+no_csr_instr=0
+randomize_csr=1
+enable_illegal_csr_instruction=1
+enable_access_invalid_csr_level=1
+gen_all_csrs_by_default=1
+add_csr_write=MSTATUS,MEPC,MCAUSE,MTVAL,0x7c0,0x7c1
+no_fence=0
+no_wfi=0
+num_of_sub_program=1
Expand Down
6 changes: 6 additions & 0 deletions dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ module core_ibex_tb_top;
!dut_if.alert_minor && !dut_if.alert_major_internal && !dut_if.alert_major_bus, clk, !rst_n)
`DV_ASSERT_CTRL("tb_no_alerts_triggered", core_ibex_tb_top.NoAlertsTriggered)

assign dut.u_ibex_top.u_ibex_core.u_fcov_bind.rf_we_glitch_err =
dut.u_ibex_top.rf_alert_major_internal;

assign dut.u_ibex_top.u_ibex_core.u_fcov_bind.lockstep_glitch_err =
dut.u_ibex_top.lockstep_alert_major_internal;

// Data load/store vif connection
assign data_mem_vif.reset = ~rst_n;
// Instruction fetch vif connnection
Expand Down
4 changes: 4 additions & 0 deletions rtl/ibex_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@ module ibex_core import ibex_pkg::*; #(
//////////

`ifndef SYNTHESIS
// fcov signals for V2S
`DV_FCOV_SIGNAL_GEN_IF(logic, rf_ecc_err_a_id, gen_regfile_ecc.rf_ecc_err_a_id, RegFileECC)
`DV_FCOV_SIGNAL_GEN_IF(logic, rf_ecc_err_b_id, gen_regfile_ecc.rf_ecc_err_b_id, RegFileECC)

// fcov signals for CSR access. These are complicated by illegal accesses. Where an access is
// legal `csr_op_en` signals the operation occurring, but this is deasserted where an access is
// illegal. Instead `illegal_insn_id` confirms the instruction is taking an illegal instruction
Expand Down
12 changes: 12 additions & 0 deletions rtl/ibex_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,18 @@ module ibex_if_stage import ibex_pkg::*; #(
assign fetch_ready = id_in_ready_i & ~stall_dummy_instr;
end

//////////
// FCOV //
//////////

`ifndef SYNTHESIS
// fcov signals for V2S
`DV_FCOV_SIGNAL_GEN_IF(logic [1:0], dummy_instr_type,
gen_dummy_instr.dummy_instr_i.lfsr_data.instr_type, DummyInstructions)
`DV_FCOV_SIGNAL_GEN_IF(logic, insert_dummy_instr,
gen_dummy_instr.insert_dummy_instr, DummyInstructions)
`endif

////////////////
// Assertions //
////////////////
Expand Down