diff --git a/dv/uvm/riscv_dv_extension/testlist.yaml b/dv/uvm/riscv_dv_extension/testlist.yaml index d57cabdd..7f92fbc7 100644 --- a/dv/uvm/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/riscv_dv_extension/testlist.yaml @@ -9,8 +9,8 @@ +instr_cnt=10000 +num_of_sub_program=0 +no_fence=1 - +no_data_page=1'b1 - +no_branch_jump=1'b1 + +no_data_page=1 + +no_branch_jump=1 +boot_mode=m iterations: 10 gen_test: riscv_instr_base_test @@ -314,3 +314,28 @@ rtl_test: core_ibex_perf_test sim_opts: > +require_signature_addr=1 + +- test: riscv_debug_single_step_test + description: > + Randomly assert debug_req_i, and set dcsr.step to make ibex execute one isntruction and then re-enter debug mode + iterations: 5 + gen_test: riscv_instr_base_test + gen_opts: > + +require_signature_addr=1 + +gen_debug_section=1 + +no_ebreak=1 + +no_branch_jump=1 + +instr_cnt=6000 + +no_csr_instr=1 + +no_fence=1 + +num_of_sub_program=0 + +randomize_csr=1 + +enable_debug_single_step=1 + rtl_test: core_ibex_debug_single_step_test + sim_opts: > + +require_signature_addr=1 + +max_interval=1500 + +enable_debug_single_seq=1 + compare_opts: + compare_final_value_only: 1 + verbose: 1 diff --git a/dv/uvm/tests/core_ibex_seq_lib.sv b/dv/uvm/tests/core_ibex_seq_lib.sv index 60e70216..a27f1f07 100644 --- a/dv/uvm/tests/core_ibex_seq_lib.sv +++ b/dv/uvm/tests/core_ibex_seq_lib.sv @@ -119,7 +119,7 @@ class debug_seq extends core_base_seq; virtual task send_req(); `uvm_info(get_full_name(), "Sending debug request", UVM_HIGH) dut_vif.debug_req <= 1'b1; - clk_vif.wait_clks($urandom_range(10, 30)); + clk_vif.wait_clks(50); dut_vif.debug_req <= 1'b0; endtask diff --git a/dv/uvm/tests/core_ibex_test_lib.sv b/dv/uvm/tests/core_ibex_test_lib.sv index 6a33f9d8..c3c0b0de 100644 --- a/dv/uvm/tests/core_ibex_test_lib.sv +++ b/dv/uvm/tests/core_ibex_test_lib.sv @@ -296,7 +296,15 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test; wait_for_core_setup(); // Should be extended by derived classes. // DO NOT use this test class directly. - check_stimulus(); + fork + begin : stimulus + check_stimulus(); + end : stimulus + begin + wait(dut_vif.ecall === 1'b1); + disable stimulus; + end + join end end join_none @@ -459,6 +467,58 @@ class core_ibex_debug_ebreakm_test extends core_ibex_directed_test; endclass +// Debug single step test +class core_ibex_debug_single_step_test extends core_ibex_directed_test; + + `uvm_component_utils(core_ibex_debug_single_step_test) + `uvm_component_new + + virtual task check_stimulus(); + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] ret_pc; + bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] counter = 0; + bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] next_counter = 0; + forever begin + vseq.start_debug_single_seq(); + check_next_core_status(IN_DEBUG_MODE, + "Core did not enter debug mode after debug stimulus"); + wait_for_csr_write(CSR_DPC); + ret_pc = signature_data; + wait_for_csr_write(CSR_DSCRATCH0); + next_counter = signature_data; + wait_for_csr_write(CSR_DCSR); + check_dcsr_cause(DBG_CAUSE_HALTREQ); + `DV_CHECK_EQ_FATAL(signature_data[1], 1'b1, "dcsr.step is not set") + wait(dut_vif.dret === 1'b1); + // now we loop on the counter until we are done single stepping + while (counter >= 0) begin + counter = next_counter; + check_next_core_status(IN_DEBUG_MODE, + "Core did not enter debug mode after debug stimulus"); + wait_for_csr_write(CSR_DPC); + if (signature_data - ret_pc !== 'h2 && + signature_data - ret_pc !== 'h4) begin + `uvm_fatal(`gfn, $sformatf("DPC value [0x%0x] is not the next instruction after ret_pc [0x%0x]", + signature_data, ret_pc)) + end + ret_pc = signature_data; + wait_for_csr_write(CSR_DSCRATCH0); + next_counter = signature_data; + wait_for_csr_write(CSR_DCSR); + check_dcsr_cause(DBG_CAUSE_STEP); + if (counter === 0) begin + `DV_CHECK_EQ_FATAL(signature_data[2], 1'b0, "dcsr.step is set") + end else begin + `DV_CHECK_EQ_FATAL(signature_data[2], 1'b1, "dcsr.step is not set") + end + wait(dut_vif.dret === 1'b1); + if (counter === 0) break; + end + clk_vif.wait_clks(2000); + end + endtask + +endclass + // Memory interface error test class class core_ibex_mem_error_test extends core_ibex_directed_test; @@ -470,35 +530,27 @@ class core_ibex_mem_error_test extends core_ibex_directed_test; // check memory error inputs and verify that core jumps to correct exception handler // TODO(udinator) - add checks for the RVFI interface virtual task check_stimulus(); - fork - begin : drive_mem_err - forever begin - while (!vseq.data_intf_seq.get_error_synch()) begin - clk_vif.wait_clks(1); - end - vseq.data_intf_seq.inject_error(); - `uvm_info(`gfn, "Injected dmem error", UVM_LOW) - // Dmem interface error could be either a load or store operation - check_mem_fault(1'b1); - // Random delay before injecting instruction fetch fault - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [25:100] };) - clk_vif.wait_clks(err_delay); - while (!vseq.instr_intf_seq.get_error_synch()) begin - clk_vif.wait_clks(1); - end - `uvm_info(`gfn, "Injecting imem fault", UVM_LOW) - vseq.instr_intf_seq.inject_error(); - check_mem_fault(1'b0); - // Random delay before injecting this series of errors again - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [250:750] };) - clk_vif.wait_clks(err_delay); - end + forever begin + while (!vseq.data_intf_seq.get_error_synch()) begin + clk_vif.wait_clks(1); end - begin - wait(dut_vif.ecall === 1'b1); - disable drive_mem_err; + vseq.data_intf_seq.inject_error(); + `uvm_info(`gfn, "Injected dmem error", UVM_LOW) + // Dmem interface error could be either a load or store operation + check_mem_fault(1'b1); + // Random delay before injecting instruction fetch fault + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [25:100] };) + clk_vif.wait_clks(err_delay); + while (!vseq.instr_intf_seq.get_error_synch()) begin + clk_vif.wait_clks(1); end - join_any + `uvm_info(`gfn, "Injecting imem fault", UVM_LOW) + vseq.instr_intf_seq.inject_error(); + check_mem_fault(1'b0); + // Random delay before injecting this series of errors again + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [250:750] };) + clk_vif.wait_clks(err_delay); + end endtask virtual task check_mem_fault(bit imem_or_dmem);