Skip to content
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

[dv] Add riscv_rf_ctrl_intg_test #2182

Merged
merged 1 commit into from
Jul 3, 2024
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
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
Loading