diff --git a/dv/uvm/Makefile b/dv/uvm/Makefile index 9c7557f9..82be1293 100644 --- a/dv/uvm/Makefile +++ b/dv/uvm/Makefile @@ -2,45 +2,49 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 -DV_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) -GEN_DIR := $(realpath ${DV_DIR}/../../vendor/google_riscv-dv) -TOOLCHAIN := ${RISCV_TOOLCHAIN} -OUT := "${DV_DIR}/out" +DV_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +GEN_DIR := $(realpath ${DV_DIR}/../../vendor/google_riscv-dv) +TOOLCHAIN := ${RISCV_TOOLCHAIN} +OUT := "${DV_DIR}/out" # Run time options for the instruction generator -GEN_OPTS := +GEN_OPTS := # Run time options for ibex RTL simulation -SIM_OPTS := +SIM_OPTS := # Enable waveform dumping -WAVES := 1 +WAVES := 1 # Enable coverage dump -COV := 0 +COV := 0 # RTL simulator -SIMULATOR := "vcs" +SIMULATOR := "vcs" # ISS (spike, ovpsim) -ISS := "spike" +ISS := "spike" # ISA -ISA := "rv32imc" +ISA := "rv32imc" # Test name (default: full regression) -TEST := "all" +TEST := "all" # Seed for instruction generator and RTL simulation -SEED := -1 +SEED := -1 # Verbose logging -VERBOSE := +VERBOSE := # Number of iterations for each test, assign a non-zero value to override the # iteration count in the test list -ITERATIONS := 0 +ITERATIONS := 0 # LSF CMD -LSF_CMD := +LSF_CMD := # Generator timeout limit in seconds -TIMEOUT := 1800 +TIMEOUT := 1800 # Privileged CSR YAML description file -CSR_FILE := ${DV_DIR}/riscv_dv_extension/csr_description.yaml +CSR_FILE := ${DV_DIR}/riscv_dv_extension/csr_description.yaml # Pass/fail signature address at the end of test -END_SIGNATURE_ADDR := 8ffffffc -# Value written to END_SIGNATURE_ADDR that indicates test success -PASS_VAL := 0x1 -# Value written to END_SIGNATURE_ADDR that indicates test failure -FAIL_VAL := 0x0 +SIGNATURE_ADDR := 8ffffffc +# Value written to SIGNATURE_ADDR that indicates test success +PASS_VAL := 0x1 +# Value written to SIGNATURE_ADDR that indicates test failure +FAIL_VAL := 0x0 +# Value written to SIGNATURE_ADDR to indicate that debug stimulus can safely be sent +DEBUG_START_REQ := 2 +# Value written to SIGNATURE_ADDR to indicate that interrupt stimulus can safely be sent +IRQ_START_REQ := 3 SHELL=/bin/bash @@ -66,14 +70,14 @@ endif # Options used for privileged CSR test generation CSR_OPTS=--csr_yaml=${CSR_FILE} \ --isa=${ISA} \ - --end_signature_addr=0x${END_SIGNATURE_ADDR} + --end_signature_addr=0x${SIGNATURE_ADDR} # Generate random instructions .SILENT gen: mkdir -p ${OUT} cd ${GEN_DIR}; \ python3 ./run.py \ - --o=${OUT}/instr_gen ${GEN_OPTS} \ + --output=${OUT}/instr_gen ${GEN_OPTS} \ --steps=gen \ --gen_timeout=${TIMEOUT} \ --lsf_cmd="${LSF_CMD}" \ @@ -82,7 +86,9 @@ CSR_OPTS=--csr_yaml=${CSR_FILE} \ --cmp_opts="+define+RISCV_CORE_SETTING=${DV_DIR}/riscv_dv_extension/ibex_core_setting.sv \ +define+RISCV_DV_EXT_FILE_LIST=${DV_DIR}/riscv_dv_extension/flist \ +incdir+${DV_DIR}/riscv_dv_extension/ " \ - --sim_opts="+uvm_set_type_override=riscv_asm_program_gen,ibex_asm_program_gen"; + --sim_opts="+uvm_set_type_override=riscv_asm_program_gen,ibex_asm_program_gen \ + +signature_addr=${SIGNATURE_ADDR} +debug_start_req=${DEBUG_START_REQ} \ + +irq_start_req=${IRQ_START_REQ}"; # Compile the generated assmebly programs to ELF/BIN gcc_compile: @@ -126,7 +132,8 @@ rtl_sim: --simulator=${SIMULATOR} \ --en_cov ${COV} \ --en_wave ${WAVES} \ - --sim_opts="+end_signature_addr=${END_SIGNATURE_ADDR} +pass_val=${PASS_VAL} +fail_val=${FAIL_VAL}" \ + --sim_opts="+signature_addr=0x${SIGNATURE_ADDR} +pass_val=${PASS_VAL} +fail_val=${FAIL_VAL} \ + +debug_start_req=0x${DEBUG_START_REQ} +irq_start_req=0x${IRQ_START_REQ}" \ ${SIM_OPTS} # Compare the regression result between ISS and RTL sim diff --git a/dv/uvm/env/core_ibex_env_cfg.sv b/dv/uvm/env/core_ibex_env_cfg.sv index 20ccf178..b8bdf23c 100644 --- a/dv/uvm/env/core_ibex_env_cfg.sv +++ b/dv/uvm/env/core_ibex_env_cfg.sv @@ -7,14 +7,18 @@ class core_ibex_env_cfg extends uvm_object; bit enable_irq_seq; bit enable_debug_seq; bit[31:0] pass_val, fail_val; - bit[31:0] end_signature_addr; + bit[31:0] signature_addr; + bit[31:0] debug_start_req; + bit[31:0] irq_start_req; `uvm_object_utils_begin(core_ibex_env_cfg) `uvm_field_int(enable_irq_seq, UVM_DEFAULT) `uvm_field_int(enable_debug_seq, UVM_DEFAULT) `uvm_field_int(pass_val, UVM_DEFAULT) `uvm_field_int(fail_val, UVM_DEFAULT) - `uvm_field_int(end_signature_addr, UVM_DEFAULT) + `uvm_field_int(signature_addr, UVM_DEFAULT) + `uvm_field_int(debug_start_req, UVM_DEFAULT) + `uvm_field_int(irq_start_req, UVM_DEFAULT) `uvm_object_utils_end function new(string name = ""); @@ -23,7 +27,9 @@ class core_ibex_env_cfg extends uvm_object; void'($value$plusargs("enable_debug_seq=%0d", enable_debug_seq)); void'($value$plusargs("pass_val=%0h", pass_val)); void'($value$plusargs("fail_val=%0h", fail_val)); - void'($value$plusargs("end_signature_addr=%0h", end_signature_addr)); + void'($value$plusargs("signature_addr=%0h", signature_addr)); + void'($value$plusargs("debug_start_req=%0h", debug_start_req)); + void'($value$plusargs("irq_start_req=%0h", irq_start_req)); endfunction endclass diff --git a/dv/uvm/env/core_ibex_vseqr.sv b/dv/uvm/env/core_ibex_vseqr.sv index 068b20a1..f3af18e7 100644 --- a/dv/uvm/env/core_ibex_vseqr.sv +++ b/dv/uvm/env/core_ibex_vseqr.sv @@ -7,9 +7,9 @@ // --------------------------------------------- class core_ibex_vseqr extends uvm_sequencer; - ibex_mem_intf_slave_sequencer data_if_seqr; - ibex_mem_intf_slave_sequencer instr_if_seqr; - irq_master_sequencer irq_seqr; + ibex_mem_intf_slave_sequencer data_if_seqr; + ibex_mem_intf_slave_sequencer instr_if_seqr; + irq_master_sequencer irq_seqr; `uvm_component_utils(core_ibex_vseqr) `uvm_component_new diff --git a/dv/uvm/riscv_dv_extension/testlist.yaml b/dv/uvm/riscv_dv_extension/testlist.yaml index ca5f0485..58fa4e69 100644 --- a/dv/uvm/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/riscv_dv_extension/testlist.yaml @@ -6,6 +6,7 @@ description: > Arithmetic instruction test, no load/store/branch instructions gen_opts: > + +empty_debug_section=1 +instr_cnt=10000 +num_of_sub_program=0 +no_fence=1 @@ -22,6 +23,7 @@ iterations: 10 gen_test: riscv_instr_base_test gen_opts: > + +empty_debug_section=1 +instr_cnt=10000 +num_of_sub_program=5 +boot_mode=m @@ -33,6 +35,7 @@ iterations: 10 gen_test: riscv_instr_base_test gen_opts: > + +empty_debug_section=1 +instr_cnt=10000 +num_of_sub_program=5 +directed_instr_0=riscv_load_store_rand_instr_stream,4 @@ -49,6 +52,7 @@ iterations: 10 gen_test: riscv_instr_base_test gen_opts: > + +empty_debug_section=1 +instr_cnt=15000 +num_of_sub_program=20 +directed_instr_0=riscv_load_store_rand_instr_stream,8 @@ -61,6 +65,7 @@ iterations: 10 gen_test: riscv_instr_base_test gen_opts: > + +empty_debug_section=1 +instr_cnt=10000 +num_of_sub_program=5 +directed_instr_0=riscv_load_store_rand_instr_stream,40 @@ -78,6 +83,7 @@ iterations: 10 gen_test: riscv_rand_instr_test gen_opts: > + +empty_debug_section=1 +enable_illegal_instruction=1 rtl_test: core_ibex_base_test @@ -88,6 +94,7 @@ iterations: 10 gen_test: riscv_rand_instr_test gen_opts: > + +empty_debug_section=1 +enable_hint_instruction=1 rtl_test: core_ibex_base_test @@ -98,6 +105,7 @@ iterations: 10 gen_test: riscv_rand_instr_test gen_opts: > + +empty_debug_section=1 +instr_cnt=6000 +no_ebreak=0 rtl_test: core_ibex_base_test @@ -109,12 +117,32 @@ gen_test: riscv_instr_base_test gen_opts: > +no_ebreak=1 - +instr_cnt=6000 +no_branch_jump=1 + +instr_cnt=6000 +no_csr_instr=1 +no_fence=1 +num_of_sub_program=0 - rtl_test: core_ibex_base_test + rtl_test: core_ibex_debug_test + sim_opts: > + +enable_debug_seq=1 + compare_opts: + compare_final_value_only: 1 + verbose: 1 + +- test: riscv_debug_branch_jump_test + description: > + Randomly assert debug_req_i, insert branch instructions and subprograms into debug_rom to make core + jump around within the debug_rom + iterations: 10 + gen_test: riscv_rand_instr_test + gen_opts: > + +no_ebreak=1 + +instr_cnt=10000 + +no_csr_instr=1 + +no_fence=1 + +num_of_sub_program=5 + +num_debug_sub_program=2 + rtl_test: core_ibex_debug_test sim_opts: > +enable_debug_seq=1 compare_opts: @@ -146,11 +174,14 @@ iterations: 2 gen_test: riscv_rand_instr_test gen_opts: > + +empty_debug_section=1 +skip_trap_handling=1 +no_wfi=0 rtl_test: core_ibex_base_test sim_opts: > +enable_irq_seq=1 + compare_opts: + compare_final_value_only: 1 - test: riscv_full_interrupt_test description: > @@ -177,6 +208,7 @@ iterations: 5 gen_test: riscv_instr_base_test gen_opts: > + +empty_debug_section=1 +instr_cnt=10000 +num_of_sub_program=5 +directed_instr_0=riscv_load_store_rand_instr_stream,20 diff --git a/dv/uvm/tests/core_ibex_base_test.sv b/dv/uvm/tests/core_ibex_base_test.sv index 9e780b78..57e7eaf4 100644 --- a/dv/uvm/tests/core_ibex_base_test.sv +++ b/dv/uvm/tests/core_ibex_base_test.sv @@ -4,17 +4,18 @@ class core_ibex_base_test extends uvm_test; - core_ibex_env env; - core_ibex_env_cfg cfg; - virtual clk_if clk_vif; - virtual core_ibex_dut_probe_if dut_vif; - virtual ibex_mem_intf dmem_vif; - mem_model_pkg::mem_model mem; - core_ibex_vseq vseq; - bit enable_irq_seq; - bit enable_debug_seq; - irq_seq irq_seq_h; - int unsigned timeout_in_cycles = 2000000; + core_ibex_env env; + core_ibex_env_cfg cfg; + virtual clk_if clk_vif; + virtual core_ibex_dut_probe_if dut_vif; + virtual ibex_mem_intf dmem_vif; + mem_model_pkg::mem_model mem; + core_ibex_vseq vseq; + bit enable_irq_seq; + bit enable_debug_seq; + irq_seq irq_seq_h; + int unsigned timeout_in_cycles = 2000000; + uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) addr_ph_port; `uvm_component_utils(core_ibex_base_test) @@ -23,6 +24,7 @@ class core_ibex_base_test extends uvm_test; super.new(name, parent); ibex_report_server = new(); uvm_report_server::set_server(ibex_report_server); + addr_ph_port = new("addr_ph_port_test", this); endfunction virtual function void build_phase(uvm_phase phase); @@ -47,6 +49,11 @@ class core_ibex_base_test extends uvm_test; vseq.cfg = cfg; endfunction + virtual function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + env.data_if_slave_agent.monitor.addr_ph_port.connect(this.addr_ph_port.analysis_export); + endfunction + virtual task run_phase(uvm_phase phase); phase.raise_objection(this); dut_vif.fetch_enable = 1'b0; @@ -104,4 +111,17 @@ class core_ibex_base_test extends uvm_test; join_any endtask + virtual task wait_for_mem_txn(input bit[ibex_mem_intf_agent_pkg::ADDR_WIDTH-1:0] ref_addr, + input bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] ref_val, + output bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] data); + ibex_mem_intf_seq_item mem_txn; + forever begin + addr_ph_port.get(mem_txn); + if (mem_txn.addr == ref_addr && mem_txn.data == ref_val && mem_txn.read_write == WRITE) begin + data = mem_txn.data; + return; + end + end + endtask + endclass diff --git a/dv/uvm/tests/core_ibex_csr_test.sv b/dv/uvm/tests/core_ibex_csr_test.sv deleted file mode 100644 index 82d5567d..00000000 --- a/dv/uvm/tests/core_ibex_csr_test.sv +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class core_ibex_csr_test extends core_ibex_base_test; - - `uvm_component_utils(core_ibex_csr_test) - - function new(string name="", uvm_component parent=null); - super.new(name, parent); - endfunction - - virtual task wait_for_test_done(); - fork - begin - wait(dmem_vif.request && dmem_vif.we && dmem_vif.grant && - dmem_vif.addr == cfg.end_signature_addr); - if (dmem_vif.wdata == cfg.pass_val) begin - `uvm_info(`gfn, "CSR test completed successfully!", UVM_LOW) - end else if (dmem_vif.wdata == cfg.fail_val) begin - `uvm_error(`gfn, "CSR TEST_FAILED!") - end else begin - `uvm_fatal(`gfn, "CSR test values are not configured properly") - end - end - begin - clk_vif.wait_clks(timeout_in_cycles); - `uvm_fatal(`gfn, "TEST TIMEOUT!!") - end - join_any - endtask - -endclass diff --git a/dv/uvm/tests/core_ibex_test_lib.sv b/dv/uvm/tests/core_ibex_test_lib.sv new file mode 100644 index 00000000..7db0c9b5 --- /dev/null +++ b/dv/uvm/tests/core_ibex_test_lib.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// CSR test class +class core_ibex_csr_test extends core_ibex_base_test; + + `uvm_component_utils(core_ibex_csr_test) + `uvm_component_new + + virtual task wait_for_test_done(); + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data; + fork + begin + fork + wait_for_mem_txn(cfg.signature_addr, cfg.pass_val, signature_data); + wait_for_mem_txn(cfg.signature_addr, cfg.fail_val, signature_data); + join_any + disable fork; + if (signature_data == cfg.pass_val) begin + `uvm_info(`gfn, "CSR test completed successfully!", UVM_LOW) + end else if (signature_data == cfg.fail_val) begin + `uvm_error(`gfn, "CSR TEST_FAILED!") + end else begin + `uvm_fatal(`gfn, "CSR test values are not configured properly") + end + end + begin + clk_vif.wait_clks(timeout_in_cycles); + `uvm_fatal(`gfn, "TEST TIMEOUT!!") + end + join_any + endtask + +endclass + +// Debug test class +class core_ibex_debug_test extends core_ibex_base_test; + + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] irq_data; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] debug_data; + + `uvm_component_utils(core_ibex_debug_test) + `uvm_component_new + + virtual task run_phase(uvm_phase phase); + phase.raise_objection(this); + dut_vif.fetch_enable = 1'b0; + clk_vif.wait_clks(100); + load_binary_to_mem(); + dut_vif.fetch_enable = 1'b1; + fork + vseq.start(env.vseqr); + if (cfg.enable_irq_seq) begin + wait_for_mem_txn(cfg.signature_addr, cfg.irq_start_req, irq_data); + vseq.start_irq_seq(); + end + if (cfg.enable_debug_seq) begin + wait_for_mem_txn(cfg.signature_addr, cfg.debug_start_req, debug_data); + vseq.start_debug_seq(); + end + join_none + wait_for_test_done(); + phase.drop_objection(this); + endtask + +endclass diff --git a/dv/uvm/tests/core_ibex_test_pkg.sv b/dv/uvm/tests/core_ibex_test_pkg.sv index 7028001f..e86acea3 100644 --- a/dv/uvm/tests/core_ibex_test_pkg.sv +++ b/dv/uvm/tests/core_ibex_test_pkg.sv @@ -16,6 +16,6 @@ package core_ibex_test_pkg; `include "core_ibex_seq_lib.sv" `include "core_ibex_vseq.sv" `include "core_ibex_base_test.sv" - `include "core_ibex_csr_test.sv" + `include "core_ibex_test_lib.sv" endpackage diff --git a/dv/uvm/tests/core_ibex_vseq.sv b/dv/uvm/tests/core_ibex_vseq.sv index 440a918b..4f3d7a89 100644 --- a/dv/uvm/tests/core_ibex_vseq.sv +++ b/dv/uvm/tests/core_ibex_vseq.sv @@ -8,12 +8,13 @@ class core_ibex_vseq extends uvm_sequence; - ibex_mem_intf_slave_seq instr_intf_seq; - ibex_mem_intf_slave_seq data_intf_seq; - mem_model_pkg::mem_model mem; - irq_seq irq_seq_h; - debug_seq debug_seq_h; - core_ibex_env_cfg cfg; + ibex_mem_intf_slave_seq instr_intf_seq; + ibex_mem_intf_slave_seq data_intf_seq; + mem_model_pkg::mem_model mem; + irq_seq irq_seq_h; + debug_seq debug_seq_h; + core_ibex_env_cfg cfg; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] data; `uvm_object_utils(core_ibex_vseq) `uvm_declare_p_sequencer(core_ibex_vseqr) @@ -22,20 +23,19 @@ class core_ibex_vseq extends uvm_sequence; virtual task body(); instr_intf_seq = ibex_mem_intf_slave_seq::type_id::create("instr_intf_seq"); data_intf_seq = ibex_mem_intf_slave_seq::type_id::create("data_intf_seq"); + if (cfg.enable_irq_seq) begin + irq_seq_h = irq_seq::type_id::create("irq_seq_h"); + end + if (cfg.enable_debug_seq) begin + debug_seq_h = debug_seq::type_id::create("debug_seq_h"); + end instr_intf_seq.m_mem = mem; data_intf_seq.m_mem = mem; + fork instr_intf_seq.start(p_sequencer.instr_if_seqr); data_intf_seq.start(p_sequencer.data_if_seqr); - if (cfg.enable_irq_seq) begin - irq_seq_h = irq_seq::type_id::create("irq_seq_h"); - irq_seq_h.start(p_sequencer.irq_seqr); - end - if (cfg.enable_debug_seq) begin - debug_seq_h = debug_seq::type_id::create("debug_seq_h"); - debug_seq_h.start(null); - end join_none endtask @@ -48,4 +48,12 @@ class core_ibex_vseq extends uvm_sequence; end endtask + virtual task start_debug_seq(); + debug_seq_h.start(null); + endtask + + virtual task start_irq_seq(); + irq_seq_h.start(p_sequencer.irq_seqr); + endtask + endclass