Integrate risc-v stream generator handshake into Ibex sim flow (#264)

This commit is contained in:
udinator 2019-08-26 15:18:30 -07:00 committed by GitHub
parent ce8be4f2fd
commit 2421472395
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 35 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"