Skip to content

Commit

Permalink
[dv] Add riscv_ram_intg_test
Browse files Browse the repository at this point in the history
This test injects a fault into different MuBi encoded signals within
the prim_ram_1p_scr and prim_ram_1p_adv and checks whether a fatal
alert is triggered.

I have excluded the addr_match signal from FI as its encoding
is not directly checked. If the signal was a MuBi True, a
fault into it is treated by the mubi4_and_hi as a False.
If the signal was a MuBi False, a fault into it is treated
by the mubi4_and_hi also as a False. Hence, no address
collision occurs and the holding register is not returned.

This PR is based on #2182 and closes #2173.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa committed Jul 2, 2024
1 parent e2b721d commit 29c0fae
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
15 changes: 15 additions & 0 deletions dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,21 @@
rtl_params:
SecureIbex: 1

- test: riscv_ram_intg_test
description: >
Randomly corrupt one of the RAM MUBI values in the middle of program execution
iterations: 15
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+gen_all_csrs_by_default=1
+add_csr_write=MSTATUS,MEPC,MCAUSE,MTVAL,0x7c0,0x7c1
+no_csr_instr=0
rtl_test: core_ibex_ram_intg_test
rtl_params:
SecureIbex: 1

- test: riscv_icache_intg_test
description: >
Randomly corrupt the instruction cache once in the middle of program execution
Expand Down
117 changes: 117 additions & 0 deletions dv/uvm/core_ibex/tests/core_ibex_test_lib.sv
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,123 @@ class core_ibex_rf_intg_test extends core_ibex_base_test;

endclass

class core_ibex_ram_intg_test extends core_ibex_base_test;
`uvm_component_utils(core_ibex_ram_intg_test)
`uvm_component_new

uvm_report_server rs;

virtual task send_stimulus();
int rnd_delay;
int unsigned bit_idx;
logic [31:0] orig_val, glitch_val;
logic alert_major_internal;
string glitch_path, alert_major_internal_path;
string glitch_paths[];
string signals[];
string scr_signals[];
int unsigned scr_signals_idx;
string adv_signals[];
int unsigned adv_signals_idx;
string ram_path;
int unsigned bank_idx, ram_idx, glitch_idx;
string top_path = "core_ibex_tb_top.dut.u_ibex_top";
string bank_paths[];

// Hard coded paths for the data and tag bank.
bank_paths = {
"gen_rams.gen_rams_inner[0].gen_scramble_rams.tag_bank",
"gen_rams.gen_rams_inner[1].gen_scramble_rams.tag_bank",
"gen_rams.gen_rams_inner[0].gen_scramble_rams.data_bank",
"gen_rams.gen_rams_inner[1].gen_scramble_rams.data_bank"
};

// All banks contain a single prim_ram_1p_adv instance.
ram_path = "u_prim_ram_1p_adv";

scr_signals = {
"write_en_d",
"write_en_q",
"addr_collision_d",
"addr_collision_q",
"write_scr_pending_d",
"write_pending_q",
"rvalid_q",
"read_en_buf"
};

adv_signals = {
"req_q",
"req_d",
"write_q",
"write_d",
"rvalid_q",
"rvalid_d",
"rvalid_sram_q",
"rvalid_sram_d"
};

`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(scr_signals_idx, scr_signals_idx < scr_signals.size();)
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(adv_signals_idx, adv_signals_idx < adv_signals.size();)
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(bank_idx, bank_idx < bank_paths.size();)
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(rnd_delay, rnd_delay > 1000; rnd_delay < 10_000;)

signals = {
scr_signals[scr_signals_idx],
adv_signals[adv_signals_idx]
};

// Assemble paths and do the final muxing of the target glitch path below.
glitch_paths = {
$sformatf("%s.%s.%s", top_path, bank_paths[bank_idx], signals[0]),
$sformatf("%s.%s.%s.%s", top_path, bank_paths[bank_idx], ram_path, signals[1])
};

`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(glitch_idx, glitch_idx < glitch_paths.size();)

glitch_path = glitch_paths[glitch_idx];

vseq.start(env.vseqr);
clk_vif.wait_n_clks(rnd_delay);

`uvm_info(`gfn, $sformatf("Reading value of %s", glitch_path), UVM_LOW)
`DV_CHECK_FATAL(uvm_hdl_read(glitch_path, orig_val));
`uvm_info(`gfn, $sformatf("Read %x", orig_val), UVM_LOW)

`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(bit_idx, bit_idx < 4;)

glitch_val = orig_val;
glitch_val ^= 1 << bit_idx;

// Disable TB assertion for alerts.
`DV_ASSERT_CTRL_REQ("tb_no_alerts_triggered", 1'b0)

`uvm_info(`gfn, $sformatf("Forcing %s to value 'h%0x", glitch_path, glitch_val), UVM_LOW)
`DV_CHECK_FATAL(uvm_hdl_force(glitch_path, glitch_val));

// Leave glitch applied for one clock cycle.
clk_vif.wait_n_clks(1);

// Check that the alert matches our expectation.
alert_major_internal_path = $sformatf("%s.alert_major_internal_o", top_path);
`DV_CHECK_FATAL(uvm_hdl_read(alert_major_internal_path, alert_major_internal))
`DV_CHECK_FATAL(alert_major_internal, "Major alert did not fire!")

// Release glitch.
`DV_CHECK_FATAL(uvm_hdl_release(glitch_path))
`uvm_info(`gfn, $sformatf("Releasing force of %s", glitch_path), UVM_LOW)

// Re-enable TB assertion for alerts.
`DV_ASSERT_CTRL_REQ("tb_no_alerts_triggered", 1'b1)

// Complete the test at this point because cosimulation does not model faults so will cause
// a mis-match and a test failure.
rs = uvm_report_server::get_server();
rs.report_summarize();
$finish();
endtask
endclass

// Test that corrupts the instruction cache and checks that an appropriate alert occurs.
class core_ibex_icache_intg_test extends core_ibex_base_test;

Expand Down

0 comments on commit 29c0fae

Please sign in to comment.