Skip to content

Commit

Permalink
[dv] Add riscv_rf_ctrl_intg_test
Browse files Browse the repository at this point in the history
This tests new hardening added to the register file around read and
write control signals.
  • Loading branch information
GregAC committed Jul 3, 2024
1 parent e2b721d commit 2c13211
Show file tree
Hide file tree
Showing 3 changed files with 93 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_rf_ctrl_intg_test
description: >
Randomly corrupt one of the register file write and read enables signals 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_rf_ctrl_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
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 @@ -157,10 +157,16 @@ module core_ibex_tb_top;
.core_sleep_o (dut_if.core_sleep )
);

`define IBEX_RF_PATH core_ibex_tb_top.dut.u_ibex_top.gen_regfile_ff.register_file_i

// We should never see any alerts triggered in normal testing
`ASSERT(NoAlertsTriggered,
!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)
`DV_ASSERT_CTRL("tb_rf_rd_mux_a_onehot",
`IBEX_RF_PATH.gen_rdata_mux_check.u_rdata_a_mux.SelIsOnehot_A)
`DV_ASSERT_CTRL("tb_rf_rd_mux_b_onehot",
`IBEX_RF_PATH.gen_rdata_mux_check.u_rdata_b_mux.SelIsOnehot_A)

assign dut.u_ibex_top.u_ibex_core.u_fcov_bind.rf_we_glitch_err =
dut.u_ibex_top.rf_alert_major_internal;
Expand Down
72 changes: 72 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,78 @@ class core_ibex_rf_intg_test extends core_ibex_base_test;

endclass

class core_ibex_rf_ctrl_intg_test extends core_ibex_base_test;
`uvm_component_utils(core_ibex_rf_ctrl_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 ctrl_signals[];
int unsigned ctrl_signal_idx;
string top_path = "core_ibex_tb_top.dut.u_ibex_top";
string ibex_rf_path = {top_path, ".gen_regfile_ff.register_file_i"};

ctrl_signals = {
"we_a_dec",
"gen_rdata_mux_check.raddr_onehot_a",
"gen_rdata_mux_check.raddr_onehot_b"
};

`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(ctrl_signal_idx, ctrl_signal_idx < ctrl_signals.size();)
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(rnd_delay, rnd_delay > 1000; rnd_delay < 10_000;)

glitch_path = $sformatf("%s.%s", ibex_rf_path, ctrl_signals[ctrl_signal_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 < 32;)

glitch_val = orig_val;
glitch_val[bit_idx] = ~glitch_val[bit_idx];

// Disable TB assertion for alerts.
`DV_ASSERT_CTRL_REQ("tb_no_alerts_triggered", 1'b0)
// Disable one-hot check assertions for RF muxes
`DV_ASSERT_CTRL_REQ("tb_rf_rd_mux_a_onehot", 1'b0)
`DV_ASSERT_CTRL_REQ("tb_rf_rd_mux_b_onehot", 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 2c13211

Please sign in to comment.