diff --git a/dv/uvm/env/core_ibex_csr_if.sv b/dv/uvm/env/core_ibex_csr_if.sv new file mode 100644 index 00000000..16f3fbc2 --- /dev/null +++ b/dv/uvm/env/core_ibex_csr_if.sv @@ -0,0 +1,12 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Interface to probe CSR accesses +interface core_ibex_csr_if(input logic clk); + logic csr_access; + ibex_pkg::csr_num_e csr_addr; + logic [31:0] csr_wdata; + logic [31:0] csr_rdata; + ibex_pkg::csr_op_e csr_op; +endinterface diff --git a/dv/uvm/env/core_ibex_env_pkg.sv b/dv/uvm/env/core_ibex_env_pkg.sv index 63ee6310..5f923217 100644 --- a/dv/uvm/env/core_ibex_env_pkg.sv +++ b/dv/uvm/env/core_ibex_env_pkg.sv @@ -8,6 +8,7 @@ `include "core_ibex_dut_probe_if.sv" `include "core_ibex_rvfi_if.sv" +`include "core_ibex_csr_if.sv" package core_ibex_env_pkg; diff --git a/dv/uvm/riscv_dv_extension/testlist.yaml b/dv/uvm/riscv_dv_extension/testlist.yaml index f1377c11..d9a05f10 100644 --- a/dv/uvm/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/riscv_dv_extension/testlist.yaml @@ -270,6 +270,22 @@ compare_opts: compare_final_value_only: 1 +- test: riscv_debug_csr_entry_test + description: > + Inject debug stimulus during writes to xSTATUS and xIE + iterations: 10 + gen_test: riscv_rand_instr_test + gen_opts: > + +require_signature_addr=1 + +gen_debug_section=1 + +randomize_csr=1 + rtl_test: core_ibex_debug_csr_test + sim_opts: > + +require_signature_addr=1 + +enable_debug_single_seq=1 + compare_opts: + compare_final_value_only: 1 + - test: riscv_interrupt_test description: > Random instruction test with complete interrupt handling @@ -305,6 +321,22 @@ compare_opts: compare_final_value_only: 1 +- test: riscv_interrupt_csr_test + description: > + Inject interrupts during dummy writes to xSTATUS and xIE + iterations: 10 + gen_test: riscv_rand_instr_test + gen_opts: > + +require_signature_addr=1 + +enable_interrupt=1 + +randomize_csr=1 + rtl_test: core_ibex_irq_csr_test + sim_opts: > + +require_signature_addr=1 + +enable_irq_seq=1 + compare_opts: + compare_final_value_only: 1 + - test: riscv_csr_test description: > Test all CSR instructions on all implemented CSR registers diff --git a/dv/uvm/tb/core_ibex_tb_top.sv b/dv/uvm/tb/core_ibex_tb_top.sv index 8b1fb9ba..aa15488f 100644 --- a/dv/uvm/tb/core_ibex_tb_top.sv +++ b/dv/uvm/tb/core_ibex_tb_top.sv @@ -23,6 +23,9 @@ module core_ibex_tb_top; // RVFI interface core_ibex_rvfi_if rvfi_if(.clk(clk)); + // CSR access interface + core_ibex_csr_if csr_if(.clk(clk)); + // TODO(taliu) Resolve the tied-off ports ibex_core_tracing #(.DmHaltAddr(`BOOT_ADDR + 'h0), .DmExceptionAddr(`BOOT_ADDR + 'h4)) dut ( @@ -95,11 +98,17 @@ module core_ibex_tb_top; assign dut_if.mret = dut.u_ibex_core.id_stage_i.mret_insn_dec; assign dut_if.core_sleep = dut.u_ibex_core.core_sleep_o; assign dut_if.reset = ~rst_n; - + // CSR interface connections + assign csr_if.csr_access = dut.u_ibex_core.csr_access; + assign csr_if.csr_addr = dut.u_ibex_core.csr_addr; + assign csr_if.csr_wdata = dut.u_ibex_core.csr_wdata; + assign csr_if.csr_rdata = dut.u_ibex_core.csr_rdata; + assign csr_if.csr_op = dut.u_ibex_core.csr_op; initial begin uvm_config_db#(virtual clk_if)::set(null, "*", "clk_if", ibex_clk_if); uvm_config_db#(virtual core_ibex_dut_probe_if)::set(null, "*", "dut_if", dut_if); + uvm_config_db#(virtual core_ibex_csr_if)::set(null, "*", "csr_if", csr_if); uvm_config_db#(virtual core_ibex_rvfi_if)::set(null, "*", "rvfi_if", rvfi_if); uvm_config_db#(virtual ibex_mem_intf)::set(null, "*data_if_slave*", "vif", data_mem_vif); uvm_config_db#(virtual ibex_mem_intf)::set(null, "*instr_if_slave*", "vif", instr_mem_vif); diff --git a/dv/uvm/tests/core_ibex_base_test.sv b/dv/uvm/tests/core_ibex_base_test.sv index 2539285c..181a6e14 100644 --- a/dv/uvm/tests/core_ibex_base_test.sv +++ b/dv/uvm/tests/core_ibex_base_test.sv @@ -8,6 +8,7 @@ class core_ibex_base_test extends uvm_test; core_ibex_env_cfg cfg; virtual clk_if clk_vif; virtual core_ibex_dut_probe_if dut_vif; + virtual core_ibex_csr_if csr_vif; mem_model_pkg::mem_model mem; core_ibex_vseq vseq; int unsigned timeout_in_cycles = 10000000; @@ -41,6 +42,9 @@ class core_ibex_base_test extends uvm_test; if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if", dut_vif)) begin `uvm_fatal(get_full_name(), "Cannot get dut_if") end + if (!uvm_config_db#(virtual core_ibex_csr_if)::get(null, "", "csr_if", csr_vif)) begin + `uvm_fatal(get_full_name(), "Cannot get csr_if") + end env = core_ibex_env::type_id::create("env", this); cfg = core_ibex_env_cfg::type_id::create("cfg", this); uvm_config_db#(core_ibex_env_cfg)::set(this, "*", "cfg", cfg); diff --git a/dv/uvm/tests/core_ibex_test_lib.sv b/dv/uvm/tests/core_ibex_test_lib.sv index 26ee8667..143b3e54 100644 --- a/dv/uvm/tests/core_ibex_test_lib.sv +++ b/dv/uvm/tests/core_ibex_test_lib.sv @@ -415,6 +415,28 @@ class core_ibex_irq_wfi_test extends core_ibex_directed_test; endclass +// Interrupt CSR test class +class core_ibex_irq_csr_test extends core_ibex_directed_test; + + `uvm_component_utils(core_ibex_irq_csr_test) + `uvm_component_new + + virtual task check_stimulus(); + vseq.irq_single_seq_h.max_delay = 0; + // wait for a write to mstatus - should be in init code + wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS && + csr_vif.csr_op != CSR_OP_READ); + // send interrupt immediately after detection + send_irq_stimulus(); + // wait for a write to mie - should be in init code + wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE && + csr_vif.csr_op != CSR_OP_READ); + // send interrupt immediately after detection + send_irq_stimulus(); + endtask + +endclass + // Debug WFI test class class core_ibex_debug_wfi_test extends core_ibex_directed_test; @@ -445,6 +467,36 @@ class core_ibex_debug_wfi_test extends core_ibex_directed_test; endclass +// Debug CSR entry test +class core_ibex_debug_csr_test extends core_ibex_directed_test; + + `uvm_component_utils(core_ibex_debug_csr_test) + `uvm_component_new + + virtual task check_stimulus(); + vseq.debug_seq_single_h.max_delay = 0; + // wait for a dummy write to mstatus in init code + wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS && + csr_vif.csr_op != CSR_OP_READ); + vseq.start_debug_single_seq(); + check_next_core_status(IN_DEBUG_MODE, "Core did not jump into debug mode from WFI state", + 1000); + wait_for_csr_write(CSR_DCSR, 500); + check_dcsr_cause(DBG_CAUSE_HALTREQ); + wait_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); + vseq.start_debug_single_seq(); + check_next_core_status(IN_DEBUG_MODE, "Core did not jump into debug mode from WFI state", + 1000); + wait_for_csr_write(CSR_DCSR, 500); + check_dcsr_cause(DBG_CAUSE_HALTREQ); + wait_dret(5000); + endtask + +endclass + // DRET test class class core_ibex_dret_test extends core_ibex_directed_test;