diff --git a/dv/uvm/Makefile b/dv/uvm/Makefile index d827ad3b..30c46b44 100644 --- a/dv/uvm/Makefile +++ b/dv/uvm/Makefile @@ -85,7 +85,7 @@ RISCV_DV_OPTS=--custom_target=${DV_DIR}/riscv_dv_extension \ ${COMMON_OPTS} \ ${CSR_OPTS} \ --sim_opts="+uvm_set_type_override=riscv_asm_program_gen,ibex_asm_program_gen \ - +signature_addr=${SIGNATURE_ADDR}"; + +signature_addr=0x${SIGNATURE_ADDR}"; # Compile the generated assmebly programs to ELF/BIN gcc_compile: diff --git a/dv/uvm/env/core_ibex_env_cfg.sv b/dv/uvm/env/core_ibex_env_cfg.sv index dd0e4e96..8e0f2c75 100644 --- a/dv/uvm/env/core_ibex_env_cfg.sv +++ b/dv/uvm/env/core_ibex_env_cfg.sv @@ -5,8 +5,7 @@ class core_ibex_env_cfg extends uvm_object; bit enable_irq_seq; - bit enable_debug_stress_seq; - bit enable_debug_single_seq; + bit enable_debug_seq; bit[31:0] max_interval; bit require_signature_addr; string signature_addr_str; @@ -14,8 +13,7 @@ class core_ibex_env_cfg extends uvm_object; `uvm_object_utils_begin(core_ibex_env_cfg) `uvm_field_int(enable_irq_seq, UVM_DEFAULT) - `uvm_field_int(enable_debug_single_seq, UVM_DEFAULT) - `uvm_field_int(enable_debug_stress_seq, UVM_DEFAULT) + `uvm_field_int(enable_debug_seq, UVM_DEFAULT) `uvm_field_int(max_interval, UVM_DEFAULT) `uvm_field_int(require_signature_addr, UVM_DEFAULT) `uvm_field_int(signature_addr, UVM_DEFAULT) @@ -24,8 +22,7 @@ class core_ibex_env_cfg extends uvm_object; function new(string name = ""); super.new(name); void'($value$plusargs("enable_irq_seq=%0d", enable_irq_seq)); - void'($value$plusargs("enable_debug_stress_seq=%0d", enable_debug_stress_seq)); - void'($value$plusargs("enable_debug_single_seq=%0d", enable_debug_single_seq)); + void'($value$plusargs("enable_debug_seq=%0d", enable_debug_seq)); void'($value$plusargs("max_interval=%0d", max_interval)); void'($value$plusargs("require_signature_addr=%0d", require_signature_addr)); void'($value$plusargs("signature_addr=%s", signature_addr_str)); diff --git a/dv/uvm/riscv_dv_extension/testlist.yaml b/dv/uvm/riscv_dv_extension/testlist.yaml index ef3f19ad..40ce371a 100644 --- a/dv/uvm/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/riscv_dv_extension/testlist.yaml @@ -137,7 +137,7 @@ sim_opts: > +require_signature_addr=1 +max_interval=500 - +enable_debug_stress_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 verbose: 1 @@ -156,7 +156,7 @@ iterations: 15 sim_opts: > +max_interval=250 - +enable_debug_stress_seq=1 + +enable_debug_seq=1 +require_signature_addr=1 compare_opts: verbose: 1 @@ -181,7 +181,7 @@ sim_opts: > +require_signature_addr=1 +max_interval=3000 - +enable_debug_stress_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 verbose: 1 @@ -204,7 +204,7 @@ rtl_test: core_ibex_debug_wfi_test sim_opts: > +require_signature_addr=1 - +enable_debug_single_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 verbose: 1 @@ -243,7 +243,7 @@ rtl_test: core_ibex_debug_ebreak_test sim_opts: > +require_signature_addr=1 - +enable_debug_single_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 @@ -267,7 +267,7 @@ rtl_test: core_ibex_debug_ebreakmu_test sim_opts: > +require_signature_addr=1 - +enable_debug_single_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 @@ -285,7 +285,7 @@ rtl_test: core_ibex_debug_csr_test sim_opts: > +require_signature_addr=1 - +enable_debug_single_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 @@ -413,7 +413,7 @@ sim_opts: > +require_signature_addr=1 +max_interval=1500 - +enable_debug_single_seq=1 + +enable_debug_seq=1 compare_opts: compare_final_value_only: 1 verbose: 1 diff --git a/dv/uvm/tests/core_ibex_base_test.sv b/dv/uvm/tests/core_ibex_base_test.sv index 5c316507..c29bce2b 100644 --- a/dv/uvm/tests/core_ibex_base_test.sv +++ b/dv/uvm/tests/core_ibex_base_test.sv @@ -192,8 +192,8 @@ class core_ibex_base_test extends uvm_test; begin : wait_timeout clk_vif.wait_clks(timeout); `uvm_fatal(`gfn, - $sformatf("Did not receive core_status 0x%0x within %0d cycle timeout period", - core_status, timeout)) + $sformatf("Did not receive core_status %0s within %0d cycle timeout period", + core_status.name(), timeout)) end join_any // Will only get here if we successfully beat the timeout period diff --git a/dv/uvm/tests/core_ibex_seq_lib.sv b/dv/uvm/tests/core_ibex_seq_lib.sv index d7d00856..2d6ebf53 100644 --- a/dv/uvm/tests/core_ibex_seq_lib.sv +++ b/dv/uvm/tests/core_ibex_seq_lib.sv @@ -12,6 +12,7 @@ class core_base_seq #(type REQ = uvm_sequence_item) extends uvm_sequence#(REQ); int unsigned max_interval; int unsigned max_delay = 500; virtual clk_if clk_vif; + bit is_started; bit stop_seq; bit seq_finished; @@ -36,6 +37,7 @@ class core_base_seq #(type REQ = uvm_sequence_item) extends uvm_sequence#(REQ); `DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay) clk_vif.wait_clks(delay); `uvm_info(get_full_name(), "Starting sequence...", UVM_LOW) + if (!is_started) is_started = 1'b1; while (!stop_seq) begin send_req(); iteration_cnt++; @@ -57,6 +59,7 @@ class core_base_seq #(type REQ = uvm_sequence_item) extends uvm_sequence#(REQ); stop_seq = 1'b1; `uvm_info(get_full_name(), "Stopping sequence", UVM_LOW) wait (seq_finished == 1'b1); + is_started = 1'b0; endtask endclass diff --git a/dv/uvm/tests/core_ibex_test_lib.sv b/dv/uvm/tests/core_ibex_test_lib.sv index 031f64af..d6575e5c 100644 --- a/dv/uvm/tests/core_ibex_test_lib.sv +++ b/dv/uvm/tests/core_ibex_test_lib.sv @@ -179,7 +179,7 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; end end begin - if (cfg.enable_debug_stress_seq) begin + if (cfg.enable_debug_seq) begin send_debug_stimulus(); end end @@ -260,10 +260,7 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; irq = {irq_txn.irq_nm, irq_txn.irq_fast, 4'b0, irq_txn.irq_external, 3'b0, irq_txn.irq_timer, 3'b0, irq_txn.irq_software, 3'b0}; `DV_CHECK_EQ_FATAL(irq, 0, "Interrupt lines have not been dropped") - wait (dut_vif.mret === 1'b1); - clk_vif.wait_clks(5); - // after mret, ibex should switch back to original privilege mode - check_priv_mode(operating_mode); + wait_ret("mret", 1000); endtask function int get_max_irq_id(bit [irq_agent_pkg::DATA_WIDTH-1:0] irq); @@ -278,7 +275,7 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; virtual task check_mcause(bit irq_or_exc, bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-2:0] cause); bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause; - wait_for_csr_write(CSR_MCAUSE, 750); + wait_for_csr_write(CSR_MCAUSE, 1000); mcause = signature_data; `DV_CHECK_EQ_FATAL(mcause[ibex_mem_intf_agent_pkg::DATA_WIDTH-1], irq_or_exc, $sformatf("mcause.interrupt is not set to 0x%0x", irq_or_exc)) @@ -298,28 +295,38 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; forever begin wait_for_core_status(IN_DEBUG_MODE); check_priv_mode(PRIV_LVL_M); - wait_dret(20000); + wait_ret("dret", 20000); end end join_none endtask - // Task that waits for dret to be asserted within a certain number of cycles - virtual task wait_dret(int timeout); + // Task that waits for xRET to be asserted within a certain number of cycles + virtual task wait_ret(string ret, int timeout); run.raise_objection(this); fork begin - wait(dut_vif.dret === 1'b1); - clk_vif.wait_clks(5); - check_priv_mode(operating_mode); + case (ret) + "dret": begin + wait (dut_vif.dret === 1'b1); + end + "mret": begin + wait (dut_vif.mret === 1'b1); + end + default: begin + `uvm_fatal(`gfn, $sformatf("Invalid xRET instruction %0s", ret)) + end + endcase + wait (dut_vif.priv_mode === operating_mode); end - begin : dret_timeout + begin : ret_timeout clk_vif.wait_clks(timeout); - `uvm_fatal(`gfn, $sformatf("No dret detected in timeout period of %0d cycles", timeout)) + `uvm_fatal(`gfn, $sformatf("No %0s detected, or incorrect privilege mode switch in \ + timeout period of %0d cycles", ret, timeout)) end join_any // Will only get here if dret successfully detected within timeout period - disable dret_timeout; + disable ret_timeout; run.drop_objection(this); endtask @@ -353,7 +360,7 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test; end end begin - if (cfg.enable_debug_stress_seq) begin + if (cfg.enable_debug_seq) begin send_debug_stimulus(); end end @@ -393,11 +400,9 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test; virtual task check_illegal_insn(string exception_msg); check_next_core_status(HANDLING_EXCEPTION, "Core did not jump to vectored exception handler", 1000); check_priv_mode(PRIV_LVL_M); - check_next_core_status(ILLEGAL_INSTR_EXCEPTION, exception_msg, 500); + check_next_core_status(ILLEGAL_INSTR_EXCEPTION, exception_msg, 1000); check_mcause(1'b0, EXC_CAUSE_ILLEGAL_INSN); - wait (dut_vif.mret === 1'b1); - clk_vif.wait_clks(5); - check_priv_mode(operating_mode); + wait_ret("mret", 1500); endtask // compares dcsr.ebreak against the privilege mode encoded in dcsr.prv @@ -492,7 +497,7 @@ class core_ibex_debug_wfi_test extends core_ibex_directed_test; wait_for_csr_write(CSR_DCSR, 500); check_dcsr_prv(operating_mode); check_dcsr_cause(DBG_CAUSE_HALTREQ); - wait_dret(5000); + wait_ret("dret", 5000); end endtask @@ -516,7 +521,7 @@ class core_ibex_debug_csr_test extends core_ibex_directed_test; wait_for_csr_write(CSR_DCSR, 500); check_dcsr_prv(operating_mode); check_dcsr_cause(DBG_CAUSE_HALTREQ); - wait_dret(5000); + wait_ret("dret", 5000); // wait for a dummy write to mie in the init code wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE && csr_vif.csr_op != CSR_OP_READ); @@ -527,7 +532,7 @@ class core_ibex_debug_csr_test extends core_ibex_directed_test; wait_for_csr_write(CSR_DCSR, 500); check_dcsr_prv(operating_mode); check_dcsr_cause(DBG_CAUSE_HALTREQ); - wait_dret(5000); + wait_ret("dret", 5000); endtask endclass @@ -578,7 +583,7 @@ class core_ibex_debug_ebreak_test extends core_ibex_directed_test; wait_for_csr_write(CSR_DPC, 500); `DV_CHECK_EQ_FATAL(dpc, signature_data, "ebreak inside the debug rom has changed the value of DPC") - wait_dret(1000); + wait_ret("dret", 1000); clk_vif.wait_clks($urandom_range(250, 500)); end endtask @@ -603,7 +608,7 @@ class core_ibex_debug_ebreakmu_test extends core_ibex_directed_test; check_dcsr_prv(operating_mode); check_dcsr_ebreak(); check_dcsr_cause(DBG_CAUSE_HALTREQ); - wait_dret(5000); + wait_ret("dret", 5000); forever begin wait (dut_vif.ebreak === 1'b1); check_next_core_status(IN_DEBUG_MODE, @@ -614,7 +619,7 @@ class core_ibex_debug_ebreakmu_test extends core_ibex_directed_test; check_dcsr_prv(operating_mode); check_dcsr_ebreak(); check_dcsr_cause(DBG_CAUSE_EBREAK); - wait_dret(5000); + wait_ret("dret", 5000); end endtask @@ -643,7 +648,7 @@ class core_ibex_debug_single_step_test extends core_ibex_directed_test; check_dcsr_prv(operating_mode); check_dcsr_cause(DBG_CAUSE_HALTREQ); `DV_CHECK_EQ_FATAL(signature_data[2], 1'b1, "dcsr.step is not set") - wait_dret(5000); + wait_ret("dret", 5000); // now we loop on the counter until we are done single stepping while (counter >= 0) begin counter = next_counter; @@ -668,7 +673,7 @@ class core_ibex_debug_single_step_test extends core_ibex_directed_test; end else begin `DV_CHECK_EQ_FATAL(signature_data[2], 1'b1, "dcsr.step is not set") end - wait_dret(5000); + wait_ret("dret", 5000); if (counter === 0) break; end clk_vif.wait_clks(2000); @@ -696,7 +701,7 @@ class core_ibex_mem_error_test extends core_ibex_directed_test; // Dmem interface error could be either a load or store operation check_dmem_fault(); // Random delay before injecting instruction fetch fault - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [25:100] };) + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(err_delay, err_delay inside { [50:200] };) clk_vif.wait_clks(err_delay); inject_imem_error(); check_imem_fault(); @@ -732,7 +737,7 @@ class core_ibex_mem_error_test extends core_ibex_directed_test; exc_type = EXC_CAUSE_STORE_ACCESS_FAULT; end check_mcause(1'b0, exc_type); - wait(dut_vif.mret === 1'b1); + wait (dut_vif.mret === 1'b1); `uvm_info(`gfn, "exiting mem fault checker", UVM_LOW) endtask @@ -768,7 +773,7 @@ class core_ibex_mem_error_test extends core_ibex_directed_test; "Core did not register correct memory fault type", 500); exc_type = EXC_CAUSE_INSTR_ACCESS_FAULT; check_mcause(1'b0, exc_type); - wait(dut_vif.mret === 1'b1); + wait (dut_vif.mret === 1'b1); `uvm_info(`gfn, "exiting mem fault checker", UVM_LOW) endtask diff --git a/dv/uvm/tests/core_ibex_vseq.sv b/dv/uvm/tests/core_ibex_vseq.sv index 0a63a92d..3a71d78b 100644 --- a/dv/uvm/tests/core_ibex_vseq.sv +++ b/dv/uvm/tests/core_ibex_vseq.sv @@ -38,11 +38,10 @@ class core_ibex_vseq extends uvm_sequence; irq_drop_seq_h.max_delay = 1; irq_drop_seq_h.interval = 0; end - if (cfg.enable_debug_stress_seq) begin + if (cfg.enable_debug_seq) begin debug_seq_stress_h = debug_seq::type_id::create("debug_seq_stress_h"); debug_seq_stress_h.max_interval = cfg.max_interval; - end - if (cfg.enable_debug_single_seq) begin + debug_seq_single_h = debug_seq::type_id::create("debug_seq_single_h"); debug_seq_single_h.num_of_iterations = 1; debug_seq_single_h.max_interval = 1; @@ -60,14 +59,12 @@ class core_ibex_vseq extends uvm_sequence; virtual task stop(); if (cfg.enable_irq_seq) begin - irq_single_seq_h.stop(); - irq_drop_seq_h.stop(); + if (irq_single_seq_h.is_started) irq_single_seq_h.stop(); + if (irq_drop_seq_h.is_started) irq_drop_seq_h.stop(); end - if (cfg.enable_debug_stress_seq) begin - debug_seq_stress_h.stop(); - end - if (cfg.enable_debug_single_seq) begin - debug_seq_single_h.stop(); + if (cfg.enable_debug_seq) begin + if (debug_seq_stress_h.is_started) debug_seq_stress_h.stop(); + if (debug_seq_single_h.is_started) debug_seq_single_h.stop(); end endtask