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_ram_intg_test #2184

Merged
merged 1 commit into from
Jul 4, 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 @@ -704,6 +704,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 @@ -271,6 +271,123 @@ class core_ibex_rf_ctrl_intg_test extends core_ibex_base_test;
endtask
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
Loading