diff --git a/dv/uvm/Makefile b/dv/uvm/Makefile index c0579f32..b113a3ce 100644 --- a/dv/uvm/Makefile +++ b/dv/uvm/Makefile @@ -37,12 +37,6 @@ TIMEOUT := 1800 CSR_FILE := ${DV_DIR}/riscv_dv_extension/csr_description.yaml # Pass/fail signature address at the end of test 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 stimulus can safely be sent from testbench -CORE_START_REQ := 2 SHELL=/bin/bash @@ -129,8 +123,7 @@ rtl_sim: --simulator=${SIMULATOR} \ --en_cov ${COV} \ --en_wave ${WAVES} \ - --sim_opts="+signature_addr=0x${SIGNATURE_ADDR} +pass_val=${PASS_VAL} +fail_val=${FAIL_VAL} \ - +core_start_req=0x${CORE_START_REQ}" \ + --sim_opts="+signature_addr=0x${SIGNATURE_ADDR}" \ ${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 d58f351b..f624314b 100644 --- a/dv/uvm/env/core_ibex_env_cfg.sv +++ b/dv/uvm/env/core_ibex_env_cfg.sv @@ -7,18 +7,13 @@ class core_ibex_env_cfg extends uvm_object; bit enable_irq_seq; bit enable_debug_seq; bit require_signature_addr; - bit[31:0] pass_val, fail_val; bit[31:0] signature_addr; - bit[31:0] core_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(require_signature_addr, UVM_DEFAULT) - `uvm_field_int(pass_val, UVM_DEFAULT) - `uvm_field_int(fail_val, UVM_DEFAULT) `uvm_field_int(signature_addr, UVM_DEFAULT) - `uvm_field_int(core_start_req, UVM_DEFAULT) `uvm_object_utils_end function new(string name = ""); @@ -26,10 +21,7 @@ class core_ibex_env_cfg extends uvm_object; void'($value$plusargs("enable_irq_seq=%0d", enable_irq_seq)); void'($value$plusargs("enable_debug_seq=%0d", enable_debug_seq)); void'($value$plusargs("require_signature_addr=%0d", require_signature_addr)); - void'($value$plusargs("pass_val=%0h", pass_val)); - void'($value$plusargs("fail_val=%0h", fail_val)); void'($value$plusargs("signature_addr=%0h", signature_addr)); - void'($value$plusargs("core_start_req=%0h", core_start_req)); endfunction endclass diff --git a/dv/uvm/ibex_dv.f b/dv/uvm/ibex_dv.f index 4f260a8b..2ee06d27 100644 --- a/dv/uvm/ibex_dv.f +++ b/dv/uvm/ibex_dv.f @@ -31,6 +31,7 @@ ${PRJ_DIR}/ibex/rtl/ibex_core.sv ${PRJ_DIR}/ibex/rtl/ibex_core_tracing.sv // Core DV files +${PRJ_DIR}/ibex/vendor/google_riscv-dv/src/riscv_signature_pkg.sv +incdir+${PRJ_DIR}/ibex/dv/uvm/env +incdir+${PRJ_DIR}/ibex/dv/uvm/tests +incdir+${PRJ_DIR}/ibex/dv/uvm/common/ibex_mem_intf_agent diff --git a/dv/uvm/riscv_dv_extension/testlist.yaml b/dv/uvm/riscv_dv_extension/testlist.yaml index e98343bc..58af44fc 100644 --- a/dv/uvm/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/riscv_dv_extension/testlist.yaml @@ -140,7 +140,7 @@ +frequent_debug=1 +require_signature_addr=1 compare_opts: - compare_final_value_only : 1 + compare_final_value_only: 1 verbose: 1 - test: riscv_debug_branch_jump_test diff --git a/dv/uvm/tests/core_ibex_base_test.sv b/dv/uvm/tests/core_ibex_base_test.sv index 132974ee..7731b663 100644 --- a/dv/uvm/tests/core_ibex_base_test.sv +++ b/dv/uvm/tests/core_ibex_base_test.sv @@ -19,7 +19,7 @@ class core_ibex_base_test extends uvm_test; // testbench and the generated code, the test will wait for the specified // number of cycles before starting stimulus sequences (irq and debug) int unsigned stimulus_delay = 800; - uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) addr_ph_port; + uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) item_collected_port; `uvm_component_utils(core_ibex_base_test) @@ -28,7 +28,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); + item_collected_port = new("item_collected_port_test", this); endfunction virtual function void build_phase(uvm_phase phase); @@ -55,7 +55,7 @@ class core_ibex_base_test extends uvm_test; 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); + env.data_if_slave_agent.monitor.item_collected_port.connect(this.item_collected_port.analysis_export); endfunction virtual task run_phase(uvm_phase phase); @@ -116,13 +116,46 @@ class core_ibex_base_test extends uvm_test; 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); + input signature_type_t ref_type, + output bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] data[$]); ibex_mem_intf_seq_item mem_txn; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data; 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; + // The first write to this address is guaranteed to contain the + // signature type in bits [7:0] + item_collected_port.get(mem_txn); + if (mem_txn.addr == ref_addr && mem_txn.data[7:0] === ref_type && mem_txn.read_write == WRITE) begin + signature_data = mem_txn.data; + case (ref_type) + CORE_STATUS: begin + data.push_back(signature_data >> 8); + end + TEST_RESULT: begin + data.push_back(signature_data >> 8); + end + // The next 32 writes to the address are guaranteed to be a dump of + // all GPRs + WRITE_GPR: begin + for(int i = 0; i < 32; i++) begin + do begin + item_collected_port.get(mem_txn); + end while(!(mem_txn.addr == ref_addr && mem_txn.read_write == WRITE)); + data.push_back(mem_txn.data); + end + end + // The next write to this address is guaranteed to be the data held + // in the CSR + WRITE_CSR: begin + data.push_back(signature_data >> 8); + do begin + item_collected_port.get(mem_txn); + end while (!(mem_txn.addr == ref_addr && mem_txn.read_write == WRITE)); + data.push_back(mem_txn.data); + end + default: begin + `uvm_fatal(`gfn, $sformatf("The data 0x%0h written to the signature address is formatted incorrectly.", signature_data)) + end + endcase return; end end diff --git a/dv/uvm/tests/core_ibex_test_lib.sv b/dv/uvm/tests/core_ibex_test_lib.sv index 8f47094a..8d5f586c 100644 --- a/dv/uvm/tests/core_ibex_test_lib.sv +++ b/dv/uvm/tests/core_ibex_test_lib.sv @@ -9,17 +9,15 @@ class core_ibex_csr_test extends core_ibex_base_test; `uvm_component_new virtual task wait_for_test_done(); - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data[$]; + bit result; 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 + wait_for_mem_txn(cfg.signature_addr, TEST_RESULT, signature_data); + result = signature_data.pop_front(); + if (result == TEST_PASS) begin `uvm_info(`gfn, "CSR test completed successfully!", UVM_LOW) - end else if (signature_data == cfg.fail_val) begin + end else if (result == TEST_FAIL) begin `uvm_error(`gfn, "CSR TEST_FAILED!") end else begin `uvm_fatal(`gfn, "CSR test values are not configured properly") @@ -37,7 +35,8 @@ endclass // Debug test class class core_ibex_debug_intr_test extends core_ibex_base_test; - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] core_start_data; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] core_start_data[$]; + bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] initialized_data; `uvm_component_utils(core_ibex_debug_intr_test) `uvm_component_new @@ -52,7 +51,10 @@ class core_ibex_debug_intr_test extends core_ibex_base_test; vseq.start(env.vseqr); begin if (cfg.require_signature_addr) begin - wait_for_mem_txn(cfg.signature_addr, cfg.core_start_req, core_start_data); + do begin + wait_for_mem_txn(cfg.signature_addr, CORE_STATUS, core_start_data); + initialized_data = core_start_data.pop_front(); + end while(initialized_data != INITIALIZED); end else begin // If no signature_addr functionality is desired, then the test will // simply wait for an adequate number of cycles diff --git a/dv/uvm/tests/core_ibex_test_pkg.sv b/dv/uvm/tests/core_ibex_test_pkg.sv index e86acea3..b6a8d4f0 100644 --- a/dv/uvm/tests/core_ibex_test_pkg.sv +++ b/dv/uvm/tests/core_ibex_test_pkg.sv @@ -11,6 +11,7 @@ package core_ibex_test_pkg; import core_ibex_env_pkg::*; import ibex_mem_intf_agent_pkg::*; import irq_agent_pkg::*; + import riscv_signature_pkg::*; `include "core_ibex_report_server.sv" `include "core_ibex_seq_lib.sv"