diff --git a/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv b/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv index 380d1f3b5..b63065f58 100644 --- a/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv +++ b/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv @@ -34,6 +34,7 @@ interface core_ibex_dut_probe_if(input logic clk); logic rf_ren_b; logic rf_rd_a_wb_match; logic rf_rd_b_wb_match; + logic rf_write_wb; logic sync_exc_seen; logic irq_exc_seen; logic csr_save_cause; @@ -80,6 +81,7 @@ interface core_ibex_dut_probe_if(input logic clk); input rf_ren_b; input rf_rd_a_wb_match; input rf_rd_b_wb_match; + input rf_write_wb; input sync_exc_seen; input irq_exc_seen; input wb_exception; @@ -93,6 +95,7 @@ interface core_ibex_dut_probe_if(input logic clk); `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_ren_b, rf_ren_b) `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_rd_a_wb_match, rf_rd_a_wb_match) `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_rd_b_wb_match, rf_rd_b_wb_match) + `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_write_wb, rf_write_wb) `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_alert_minor, alert_minor) `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_tag_req, ic_tag_req) `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_tag_write, ic_tag_write) diff --git a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml index 1869a6f7f..5f8b3a33c 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml @@ -683,8 +683,14 @@ - test: riscv_rf_intg_test description: > Randomly corrupt the register file read port once in the middle of program execution - iterations: 15 + iterations: 100 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_intg_test rtl_params: SecureIbex: 1 diff --git a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index dbebbe1ac..601509975 100644 --- a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -250,6 +250,7 @@ module core_ibex_tb_top; assign dut_if.rf_ren_b = dut.u_ibex_top.u_ibex_core.rf_ren_b; assign dut_if.rf_rd_a_wb_match = dut.u_ibex_top.u_ibex_core.rf_rd_a_wb_match; assign dut_if.rf_rd_b_wb_match = dut.u_ibex_top.u_ibex_core.rf_rd_b_wb_match; + assign dut_if.rf_write_wb = dut.u_ibex_top.u_ibex_core.rf_write_wb; assign dut_if.sync_exc_seen = dut.u_ibex_top.u_ibex_core.cs_registers_i.cpuctrlsts_part_q.sync_exc_seen; assign dut_if.csr_save_cause = dut.u_ibex_top.u_ibex_core.csr_save_cause; assign dut_if.exc_cause = dut.u_ibex_top.u_ibex_core.exc_cause; diff --git a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv index 5d1e30673..bf4181af6 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv @@ -129,7 +129,8 @@ class core_ibex_rf_intg_test extends core_ibex_base_test; endfunction virtual task send_stimulus(); - bit port_idx; + int rnd_delay; + bit port_idx; string port_name; vseq.start(env.vseqr); @@ -138,14 +139,19 @@ class core_ibex_rf_intg_test extends core_ibex_base_test; port_idx = $urandom_range(1); port_name = port_idx ? "rf_rdata_b_ecc" : "rf_rdata_a_ecc"; + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(rnd_delay, rnd_delay > 1000; rnd_delay < 10_000;) + clk_vif.wait_n_clks(rnd_delay); + forever begin - logic rf_ren, rf_rd_wb_match; + logic rf_ren, rf_rd_wb_match, rf_write_wb; int unsigned bit_idx; uvm_hdl_data_t data, mask; logic exp_alert, alert_major_internal; clk_vif.wait_n_clks(1); + rf_write_wb = dut_vif.signal_probe_rf_write_wb(dv_utils_pkg::SignalProbeSample); + // Check if port is being read. if (port_idx) begin rf_ren = dut_vif.signal_probe_rf_ren_b(dv_utils_pkg::SignalProbeSample); @@ -156,7 +162,7 @@ class core_ibex_rf_intg_test extends core_ibex_base_test; end // Only corrupt port if it is read. - if (!(rf_ren == 1'b1 && rf_rd_wb_match == 1'b0)) continue; + if (!(rf_ren == 1'b1 && (rf_rd_wb_match == 1'b0 || rf_write_wb == 1'b0))) continue; data = read_data(port_name); `uvm_info(`gfn, $sformatf("Corrupting %s; original value: 'h%0x", port_name, data), UVM_LOW) diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index fa5c51e3f..5df9ae1b7 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -916,8 +916,8 @@ module ibex_core import ibex_pkg::*; #( assign rf_rdata_b = rf_rdata_b_ecc_i[31:0]; // Calculate errors - qualify with WB forwarding to avoid xprop into the alert signal - assign rf_ecc_err_a_id = |rf_ecc_err_a & rf_ren_a & ~rf_rd_a_wb_match; - assign rf_ecc_err_b_id = |rf_ecc_err_b & rf_ren_b & ~rf_rd_b_wb_match; + assign rf_ecc_err_a_id = |rf_ecc_err_a & rf_ren_a & ~(rf_rd_a_wb_match & rf_write_wb); + assign rf_ecc_err_b_id = |rf_ecc_err_b & rf_ren_b & ~(rf_rd_b_wb_match & rf_write_wb); // Combined error assign rf_ecc_err_comb = instr_valid_id & (rf_ecc_err_a_id | rf_ecc_err_b_id);