Update google_riscv-dv to google/riscv-dv@39ca859 (#486)

Update code from upstream repository https://github.com/google/riscv-
dv to revision 39ca85903eea94350d3a610256307346da407e5b

* Add directed stream to access higher privilege CSRs (google/riscv-
  dv#316) (udinator)
* add config knob for mstatus.tw (Udi Jonnalagadda)
* Fix ovpsim floating point instruction parsing issue (google/riscv-
  dv#313) (taoliug)
* Fix SATP configure issue (google/riscv-dv#312) (taoliug)
* Support import testlist (google/riscv-dv#311) (taoliug)
* Add a rand address load/store test (google/riscv-dv#310) (taoliug)
* Fix ovpsim log parsing issue (google/riscv-dv#309) (taoliug)
* Add a generic approach to check command return value (google/riscv-
  dv#308) (taoliug)
* Fix compile issue (google/riscv-dv#307) (taoliug)
* Basic U-mode support (Udi Jonnalagadda)

Signed-off-by: Udi <udij@google.com>
This commit is contained in:
udinator 2019-11-21 11:22:34 -08:00 committed by GitHub
parent 2a01d1ce4c
commit 6a582cc11f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 523 additions and 801 deletions

View file

@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: 4b333ba1ef285ec4508c606efa64610136154a5e
rev: 39ca85903eea94350d3a610256307346da407e5b
}
}

View file

@ -109,7 +109,6 @@ def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \
base_sim_cmd += (" --custom_target %s" % custom_target)
logging.info("Building the coverage collection framework")
output = run_cmd(build_cmd)
check_simulator_return(output, simulator, stop_on_first_error)
file_idx = 0
trace_idx = 0
trace_csv_opts = ""
@ -133,7 +132,6 @@ def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \
if lsf_cmd == "":
logging.info("Processing batch %0d/%0d" % (file_idx+1, batch_cnt))
run_cmd(sim_cmd)
check_simulator_return(output, simulator, stop_on_first_error)
else:
sim_cmd += (" --lsf_cmd \"%s\"" % lsf_cmd)
sim_cmd_list.append(sim_cmd)

View file

@ -183,8 +183,6 @@ def gen(test_list, csr_file, end_signature_addr, isa, simulator,
logging.debug("Compile command: %s" % cmd)
output = run_cmd(cmd)
logging.debug(output)
check_simulator_return(output, simulator, stop_on_first_error)
# Run the instruction generator
if not compile_only:
cmd_list = []
@ -216,7 +214,6 @@ def gen(test_list, csr_file, end_signature_addr, isa, simulator,
cmd_list.append(cmd)
else:
output = run_cmd(cmd, timeout_s)
check_simulator_return(output, simulator, stop_on_first_error)
else:
if batch_size > 0:
batch_cnt = int((iterations + batch_size - 1) / batch_size);
@ -253,7 +250,6 @@ def gen(test_list, csr_file, end_signature_addr, isa, simulator,
logging.info("Running %s, batch %0d/%0d, test_cnt:%0d" %
(test['test'], i+1, batch_cnt, test_cnt))
output = run_cmd(cmd, timeout_s)
check_simulator_return(output, simulator, stop_on_first_error)
if sim_seed:
with open(('%s/seed.yaml' % os.path.abspath(output_dir)) , 'w') as outfile:
yaml.dump(sim_seed, outfile, default_flow_style=False)
@ -582,7 +578,7 @@ def main():
matched_list = []
if not args.co:
process_regression_list(args.testlist, args.test, args.iterations, matched_list)
process_regression_list(args.testlist, args.test, args.iterations, matched_list, cwd)
if len(matched_list) == 0:
sys.exit("Cannot find %s in %s" % (args.test, args.testlist))

View file

@ -19,6 +19,7 @@ Parse the regression testlist in YAML format
import os
import random
import sys
import re
import subprocess
import time
import yaml
@ -90,7 +91,7 @@ def get_seed(seed):
return random.getrandbits(32)
def run_cmd(cmd, timeout_s = 999):
def run_cmd(cmd, timeout_s = 999, exit_on_error = 1):
"""Run a command and return output
Args:
@ -116,11 +117,18 @@ def run_cmd(cmd, timeout_s = 999):
logging.error("Timeout[%ds]: %s" % (timeout_s, cmd))
output = ""
ps.kill()
rc = ps.returncode
if rc:
if rc > 0:
logging.info(output)
logging.error("ERROR return code: %d, cmd:%s" % (rc, cmd))
if exit_on_error:
sys.exit(1)
logging.debug(output)
return output
def run_parallel_cmd(cmd_list, timeout_s = 999):
def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0):
"""Run a list of commands in parallel
Args:
@ -146,18 +154,26 @@ def run_parallel_cmd(cmd_list, timeout_s = 999):
except subprocess.TimeoutExpired:
logging.error("Timeout[%ds]: %s" % (timeout_s, cmd))
children[i].kill()
rc = children[i].returncode
if rc:
if rc > 0:
logging.info(output)
logging.error("ERROR return code: %d, cmd:%s" % (rc, cmd))
if exit_on_error:
sys.exit(1)
# Restore stty setting otherwise the terminal may go crazy
os.system("stty sane")
logging.debug(output)
def process_regression_list(testlist, test, iterations, matched_list):
def process_regression_list(testlist, test, iterations, matched_list, riscv_dv_root):
""" Get the matched tests from the regression test list
Args:
testlist : Regression test list
test : Test to run, "all" means all tests in the list
iterations : Number of iterations for each test
testlist : Regression test list
test : Test to run, "all" means all tests in the list
iterations : Number of iterations for each test
riscv_dv_root : Root directory of RISCV-DV
Returns:
matched_list : A list of matched tests
@ -165,28 +181,14 @@ def process_regression_list(testlist, test, iterations, matched_list):
logging.info("Processing regression test list : %s, test: %s" % (testlist, test))
yaml_data = read_yaml(testlist)
for entry in yaml_data:
if (entry['test'] == test) or (test == "all"):
if (iterations > 0 and entry['iterations'] > 0):
entry['iterations'] = iterations
if entry['iterations'] > 0:
logging.info("Found matched tests: %s, iterations:%0d" %
(entry['test'], entry['iterations']))
matched_list.append(entry)
def check_simulator_return(output, simulator, stop_on_first_error):
"""
tests simulator output for errors and terminates run if found
ONLY works when verbose is on (as output not returned otherwise)
TODO add other simulators
"""
if not stop_on_first_error: return
if "questa" in simulator:
for line in output.splitlines():
if "Errors: " in line:
if not "Errors: 0" in line:
logging.fatal (
"check_simulator_return (%s): TERMINATING as got errors: [%s]" %
(simulator, line))
sys.exit(-1)
if 'import' in entry:
sub_list = re.sub('<riscv_dv_root>', riscv_dv_root, entry['import'])
process_regression_list(sub_list, test, iterations, matched_list, riscv_dv_root)
else:
if (entry['test'] == test) or (test == "all"):
if (iterations > 0 and entry['iterations'] > 0):
entry['iterations'] = iterations
if entry['iterations'] > 0:
logging.info("Found matched tests: %s, iterations:%0d" %
(entry['test'], entry['iterations']))
matched_list.append(entry)

View file

@ -63,7 +63,7 @@ def process_jal(trace, operands, gpr):
if len(operands) == 2:
trace.rd = operands[0]
trace.rd_val = gpr[trace.rd]
trace.imm = get_imm_hex_val(operands[1])
trace.imm = get_imm_hex_val("0x" + operands[1])
else:
fatal("process_jal(%s) wrong num operands (%d)" %
(trace.instr, len(operands)))
@ -173,7 +173,7 @@ def check_num_operands(instr_str, num_operands, n):
def is_csr(r):
""" see if r is a csr """
# add more as needed
if r in ["mtvec","pmpaddr0","pmpcfg0","mstatus","mepc","mscratch","mcause",
"mtval","vl","vtype"]:
@ -189,7 +189,7 @@ def process_branch_offset (opn, operands, prev_trace):
offset = hex(offset_dec)
operands[opn] = offset
def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
dont_truncate_after_first_ecall = 0,
verbose2 = False):
"""Process OVPsim simulation log.
@ -217,14 +217,13 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
os.system(cmd)
# storage and initial values of gpr and csr
gpr = {}
csr = {}
for g in REGS: # base base isa gprs
gpr[g] = 0
for i in range(32): # add in v0-v31 gprs
gpr["v"+str(i)] = 0
csr["vl"] = 0
@ -283,6 +282,8 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
"flw" in line:
logging.debug ("Ignoring ins...(%s) " % (line))
continue
logging.debug("Processing [%s]: %s" %
(prev_trace.instr, prev_trace.instr_str))
process_if_compressed(prev_trace)
o = re.search (r"(?P<instr>[a-z]*?)\s(?P<operand>.*)",
prev_trace.instr_str)
@ -295,8 +296,7 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
process_jal(prev_trace, operands, gpr)
else:
if 'v' in prev_trace.instr[0]:
assign_operand_vector(prev_trace, operands, gpr,
stop_on_first_error)
assign_operand_vector(prev_trace, operands, gpr, stop_on_first_error)
elif 'f' in prev_trace.instr[0] or "c.f" in prev_trace.instr[0:3]:
pass # ignore floating point. TODO include them
else:
@ -307,8 +307,9 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
'c.beqz', 'c.bnez', 'beqz', 'bnez', 'bgez',
'bltz', 'blez', 'bgtz']:
process_branch_offset (1, operands, prev_trace)
assign_operand(prev_trace, operands, gpr,
stop_on_first_error)
if prev_trace.instr in ['j', 'c.j']:
operands[0] = "0x" + operands[0]
assign_operand(prev_trace, operands, gpr, stop_on_first_error)
else:
# logging.debug("no operand for [%s] in [%s]" % (trace_instr,
# trace_instr_str))
@ -339,8 +340,9 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
gpr[n.group("r")] = n.group("val")
else:
# backwards compatible
prev_trace.rd_val = n.group("val")
gpr[prev_trace.rd] = prev_trace.rd_val
prev_trace.rd = n.group("r")
prev_trace.rd_val = n.group("val")
gpr[prev_trace.rd] = prev_trace.rd_val
if 0:
print (
"write entry [[%d]]: rd[%s] val[%s] instr(%s) bin(%s) addr(%s)"
@ -363,7 +365,7 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
logging.debug("Ignoring: [%d] [[%s]]" % (instr_cnt, line))
pass
elif "Warning (RISCV_" in line:
logging.debug("Skipping: [%d] (%s) [[%s]]" %
logging.debug("Skipping: [%d] (%s) [[%s]]" %
(instr_cnt, prev_trace.instr_str, line))
prev_trace.instr = "nop"
prev_trace.instr_str = "nop"
@ -378,6 +380,7 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0,
sys.exit(-1)
logging.info("CSV saved to : %s" % csv)
def main():
""" if used standalone set up for testing """
instr_trace = []

View file

@ -209,8 +209,6 @@ def get_imm_hex_val(imm):
imm = imm[1:]
else:
is_negative = 0
if len(imm) > 1 and imm[1] != 'x':
imm = "0x"+imm
imm_val = int(imm, 0)
if is_negative:
imm_val = -imm_val

View file

@ -340,7 +340,7 @@ class riscv_asm_program_gen extends uvm_object;
init_floating_point_gpr();
end
core_is_initialized();
gen_dummy_csr_write(); // comment out if not want to read incorrect values from csr
gen_dummy_csr_write();
endfunction
// Setup MISA based on supported extensions
@ -389,31 +389,36 @@ class riscv_asm_program_gen extends uvm_object;
// repeated writes to these CSRs.
virtual function void gen_dummy_csr_write();
string instr[$];
case (cfg.init_privileged_mode)
MACHINE_MODE: begin
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MSTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], MIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", MSTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", MIE, cfg.gpr[1]));
end
SUPERVISOR_MODE: begin
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], SSTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], SIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", SSTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", SIE, cfg.gpr[1]));
end
USER_MODE: begin
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], USTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], UIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", USTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", UIE, cfg.gpr[1]));
end
default: begin
`uvm_fatal(`gfn, "Unsupported boot mode")
end
endcase
format_section(instr);
instr_stream = {instr_stream, instr};
if (cfg.enable_dummy_csr_write) begin
case (cfg.init_privileged_mode)
MACHINE_MODE: begin
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MSTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], MIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", MSTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", MIE, cfg.gpr[1]));
end
SUPERVISOR_MODE: begin
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], SSTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], SIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", SSTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", SIE, cfg.gpr[1]));
end
USER_MODE: begin
if (!riscv_instr_pkg::support_umode_trap) begin
return;
end
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], USTATUS));
instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], UIE));
instr.push_back($sformatf("csrw 0x%0x, x%0d", USTATUS, cfg.gpr[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", UIE, cfg.gpr[1]));
end
default: begin
`uvm_fatal(`gfn, "Unsupported boot mode")
end
endcase
format_section(instr);
instr_stream = {instr_stream, instr};
end
endfunction
// Initialize general purpose registers with random value
@ -529,10 +534,6 @@ class riscv_asm_program_gen extends uvm_object;
// Want to write the main system CSRs to the testbench before indicating that initialization
// is complete, for any initial state analysis
case(riscv_instr_pkg::supported_privileged_mode[i])
MACHINE_MODE: begin
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(MSTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(MIE));
end
SUPERVISOR_MODE: begin
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(SSTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(SIE));
@ -542,6 +543,9 @@ class riscv_asm_program_gen extends uvm_object;
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(UIE));
end
endcase
// Write M-mode CSRs to testbench by default, as these should be implemented
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(MSTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(MIE));
format_section(csr_handshake);
instr = {instr, csr_handshake, ret_instr};
end
@ -1108,6 +1112,9 @@ class riscv_asm_program_gen extends uvm_object;
// It is followed by a second write to the signature address,
// containing the data stored in the specified CSR.
WRITE_CSR: begin
if (!(csr inside {implemented_csr})) begin
return;
end
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[0], csr),
$sformatf("slli x%0d, x%0d, 8", cfg.gpr[0], cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 0x%0h", cfg.gpr[0],

View file

@ -471,6 +471,7 @@ class riscv_instr_base extends uvm_object;
has_rs1 = 1'b1;
end else if (instr_name inside {C_JR, C_JALR}) begin
has_rs1 = 1'b1;
has_rs2 = 1'b0;
end
if (!(format inside {CJ_FORMAT, CB_FORMAT, CS_FORMAT, CSS_FORMAT, B_FORMAT, S_FORMAT})) begin
has_rd = 1'b1;
@ -609,11 +610,15 @@ class riscv_instr_base extends uvm_object;
endfunction
function void gen_rand_csr(bit illegal_csr_instr = 0,
bit legal_invalid_csr_instr = 0,
privileged_reg_t invalid_csrs[$] = {},
bit enable_floating_point = 0,
privileged_mode_t privileged_mode = MACHINE_MODE);
privileged_reg_t preg[$];
if (illegal_csr_instr) begin
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(csr, !(csr inside {implemented_csr});)
end else if (legal_invalid_csr_instr) begin
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(csr, csr inside {invalid_csrs};)
end else begin
// Use scratch register to avoid the side effect of modifying other privileged mode CSR.
if (privileged_mode == MACHINE_MODE)

View file

@ -124,6 +124,10 @@ class riscv_instr_gen_config extends uvm_object;
riscv_instr_name_t instr_group[riscv_instr_group_t][$];
riscv_instr_name_t instr_category[riscv_instr_category_t][$];
// Queue of all the main implemented CSRs that the boot privilege mode cannot access
// e.g. these CSRs are in higher privilege modes - access should raise an exception
privileged_reg_t invalid_priv_mode_csrs[$];
//-----------------------------------------------------------------------------
// Command line options or control knobs
//-----------------------------------------------------------------------------
@ -164,6 +168,11 @@ class riscv_instr_gen_config extends uvm_object;
// - Accessing non-existence CSR
// - Accessing CSR with wrong privileged mode
bit enable_illegal_csr_instruction;
// Enable accessing CSRs at an invalid privilege level
bit enable_access_invalid_csr_level;
// Enable some dummy writes to main system CSRs (xSTATUS/xIE) at beginning of test
// to check repeated writes
bit enable_dummy_csr_write;
bit randomize_csr = 0;
// sfence support
bit allow_sfence_exception = 0;
@ -194,6 +203,8 @@ class riscv_instr_gen_config extends uvm_object;
bit enable_debug_single_step = 0;
// Number of single stepping iterations
rand int single_step_iterations;
// Enable mstatus.tw bit - causes u-mode WFI to raise illegal instruction exceptions
bit set_mstatus_tw;
// Stack space allocated to each program, need to be enough to store necessary context
// Example: RA, SP, T0
int min_stack_len_per_program = 10 * (XLEN/8);
@ -268,12 +279,12 @@ class riscv_instr_gen_config extends uvm_object;
constraint boot_privileged_mode_dist_c {
// Boot to higher privileged mode more often
if(riscv_instr_pkg::supported_privileged_mode.size() == 2) {
init_privileged_mode dist {riscv_instr_pkg::supported_privileged_mode[0] := 9,
riscv_instr_pkg::supported_privileged_mode[1] := 1};
} else if (riscv_instr_pkg::supported_privileged_mode.size() == 3) {
init_privileged_mode dist {riscv_instr_pkg::supported_privileged_mode[0] := 6,
riscv_instr_pkg::supported_privileged_mode[1] := 4};
} else if (riscv_instr_pkg::supported_privileged_mode.size() == 3) {
init_privileged_mode dist {riscv_instr_pkg::supported_privileged_mode[0] := 4,
riscv_instr_pkg::supported_privileged_mode[1] := 3,
riscv_instr_pkg::supported_privileged_mode[2] := 1};
riscv_instr_pkg::supported_privileged_mode[2] := 3};
} else {
init_privileged_mode == riscv_instr_pkg::supported_privileged_mode[0];
}
@ -401,6 +412,8 @@ class riscv_instr_gen_config extends uvm_object;
get_bool_arg_value("+no_load_store=", no_load_store);
get_bool_arg_value("+no_csr_instr=", no_csr_instr);
get_bool_arg_value("+enable_illegal_csr_instruction=", enable_illegal_csr_instruction);
get_bool_arg_value("+enable_access_invalid_csr_level=", enable_access_invalid_csr_level);
get_bool_arg_value("+enable_dummy_csr_write=", enable_dummy_csr_write);
get_bool_arg_value("+allow_sfence_exception=", allow_sfence_exception);
get_bool_arg_value("+no_data_page=", no_data_page);
get_bool_arg_value("+no_directed_instr=", no_directed_instr);
@ -423,6 +436,7 @@ class riscv_instr_gen_config extends uvm_object;
get_bool_arg_value("+enable_ebreak_in_debug_rom=", enable_ebreak_in_debug_rom);
get_bool_arg_value("+set_dcsr_ebreak=", set_dcsr_ebreak);
get_bool_arg_value("+enable_debug_single_step=", enable_debug_single_step);
get_bool_arg_value("+set_mstatus_tw=", set_mstatus_tw);
get_bool_arg_value("+enable_floating_point=", enable_floating_point);
if(inst.get_arg_value("+boot_mode=", boot_mode_opts)) begin
`uvm_info(get_full_name(), $sformatf(
@ -460,6 +474,7 @@ class riscv_instr_gen_config extends uvm_object;
disable_compressed_instr = 1;
end
setup_instr_distribution();
get_invalid_priv_lvl_csr();
endfunction
function void setup_instr_distribution();
@ -550,6 +565,35 @@ class riscv_instr_gen_config extends uvm_object;
end
endfunction
// Populate invalid_priv_mode_csrs with the main implemented CSRs for each supported privilege mode
// TODO(udi) - include performance/pmp/trigger CSRs?
virtual function void get_invalid_priv_lvl_csr();
string invalid_lvl[$];
string csr;
// Debug CSRs are inaccessible from all but Debug Mode, and we cannot boot into Debug Mode
invalid_lvl.push_back("D");
case (init_privileged_mode)
MACHINE_MODE: begin
end
SUPERVISOR_MODE: begin
invalid_lvl.push_back("M");
end
USER_MODE: begin
invalid_lvl.push_back("S");
invalid_lvl.push_back("M");
end
default: begin
`uvm_fatal(`gfn, "Unsupported initialization privilege mode")
end
endcase
foreach (implemented_csr[i]) begin
csr = implemented_csr[i].name();
if (csr[0] inside {invalid_lvl}) begin
invalid_priv_mode_csrs.push_back(implemented_csr[i]);
end
end
endfunction
// Get an integer argument from comand line
function void get_int_arg_value(string cmdline_str, ref int val);
string s;

View file

@ -54,7 +54,11 @@ class riscv_instr_stream extends uvm_object;
if(idx == -1) begin
idx = $urandom_range(0, current_instr_cnt-1);
while(instr_list[idx].atomic) begin
idx = $urandom_range(0, current_instr_cnt-1);
idx += 1;
if (idx == current_instr_cnt - 1) begin
instr_list = {instr_list, instr};
return;
end
end
end else if((idx > current_instr_cnt) || (idx < 0)) begin
`uvm_error(`gfn, $sformatf("Cannot insert instr:%0s at idx %0d",
@ -281,7 +285,9 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
if ((instr.category == CSR) && !skip_csr) begin
instr.gen_rand_csr(.privileged_mode(cfg.init_privileged_mode),
.enable_floating_point(cfg.enable_floating_point),
.illegal_csr_instr(cfg.enable_illegal_csr_instruction));
.illegal_csr_instr(cfg.enable_illegal_csr_instruction),
.legal_invalid_csr_instr(cfg.enable_access_invalid_csr_level),
.invalid_csrs(cfg.invalid_priv_mode_csrs));
end
if (instr.has_fs1) begin
instr.fs1 = instr.gen_rand_fpr();

View file

@ -30,6 +30,7 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
rand int base;
int offset[];
int addr[];
riscv_instr_base load_store_instr[$];
rand int unsigned data_page_id;
rand riscv_reg_t rs1_reg;
rand locality_e locality;
@ -169,6 +170,7 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
instr.set_imm(offset[i]);
instr.process_load_store = 0;
instr_list.push_back(instr);
load_store_instr.push_back(instr);
end
endfunction
@ -355,3 +357,98 @@ class riscv_mem_region_stress_test extends riscv_multi_page_load_store_instr_str
}
endclass
// Random load/store sequence to full address range
// The address range is not preloaded with data pages, use store instruction to initialize first
class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_instr_stream;
rand bit [XLEN-1:0] addr_offset;
// Find an unused 4K page from address 1M onward
constraint addr_offset_c {
|addr_offset[XLEN-1:20] == 1'b1;
// TODO(taliu) Support larger address range
addr_offset[XLEN-1:31] == 0;
addr_offset[11:0] == 0;
}
constraint legal_c {
num_load_store inside {[5:10]};
num_mixed_instr inside {[5:10]};
}
`uvm_object_utils(riscv_load_store_rand_addr_instr_stream)
virtual function void randomize_offset();
int offset_, addr_;
offset = new[num_load_store];
addr = new[num_load_store];
for (int i=0; i<num_load_store; i++) begin
if (!std::randomize(offset_) with {
offset_ inside {[-2048:2047]};
}
) begin
`uvm_fatal(`gfn, "Cannot randomize load/store offset")
end
offset[i] = offset_;
addr[i] = addr_offset + offset_;
end
endfunction `uvm_object_new
virtual function void add_rs1_init_la_instr(riscv_reg_t gpr, int id, int base = 0);
riscv_instr_base instr[$];
riscv_pseudo_instr li_instr;
riscv_instr_base store_instr;
riscv_instr_base add_instr;
int min_offset[$];
int max_offset[$];
min_offset = offset.min();
max_offset = offset.max();
// Use LI to initialize the address offset
li_instr = riscv_pseudo_instr::type_id::create("li_instr");
`DV_CHECK_RANDOMIZE_WITH_FATAL(li_instr,
pseudo_instr_name == LI;
rd inside {cfg.gpr};
rd != gpr;
)
li_instr.imm_str = $sformatf("0x%0x", addr_offset);
// Add offset to the base address
add_instr = riscv_instr_base::type_id::create("add_instr");
`DV_CHECK_RANDOMIZE_WITH_FATAL(add_instr,
instr_name == ADD;
rs1 == gpr;
rs2 == li_instr.rd;
rd == gpr;
)
instr.push_back(li_instr);
instr.push_back(add_instr);
// Create SW instruction template
store_instr = riscv_instr_base::type_id::create("store_instr");
`DV_CHECK_RANDOMIZE_WITH_FATAL(store_instr,
instr_name == SB;
rs1 == gpr;
)
// Initialize the location which used by load instruction later
foreach (load_store_instr[i]) begin
if (load_store_instr[i].category == LOAD) begin
riscv_instr_base store;
store = riscv_instr_base::type_id::create("store");
store.copy_base_instr(store_instr);
store.rs2 = riscv_reg_t'(i % 32);
store.imm_str = load_store_instr[i].imm_str;
case (load_store_instr[i].instr_name) inside
LB, LBU : store.instr_name = SB;
LH, LHU : store.instr_name = SH;
LW, C_LW, FLW, C_FLW : store.instr_name = SW;
LD, C_LD, FLD, C_FLD, LWU : store.instr_name = SD;
default : `uvm_fatal(`gfn, $sformatf("Unexpected op: %0s",
load_store_instr[i].convert2asm()))
endcase
instr.push_back(store);
end
end
instr_list = {instr, instr_list};
super.add_rs1_init_la_instr(gpr, id, 0);
endfunction
endclass

View file

@ -38,10 +38,14 @@ class riscv_privileged_common_seq extends uvm_sequence;
riscv_privil_reg regs[$];
label = label.tolower();
setup_mmode_reg(mode, regs);
if(mode != MACHINE_MODE) begin
if(mode == SUPERVISOR_MODE) begin
setup_smode_reg(mode, regs);
end
if(mode == USER_MODE) begin
setup_umode_reg(mode, regs);
end
if(cfg.virtual_addr_translation_on) begin
setup_satp(instrs);
ret_instr.shuffle();
end
gen_csr_instr(regs, instrs);
// Use mret/sret to switch to the target privileged mode
@ -62,6 +66,7 @@ class riscv_privileged_common_seq extends uvm_sequence;
mstatus.set_field("MXR", cfg.mstatus_mxr);
mstatus.set_field("SUM", cfg.mstatus_sum);
mstatus.set_field("TVM", cfg.mstatus_tvm);
mstatus.set_field("TW", cfg.set_mstatus_tw);
mstatus.set_field("FS", cfg.mstatus_fs);
if(XLEN==64) begin
mstatus.set_field("UXL", 2'b10);
@ -140,6 +145,10 @@ class riscv_privileged_common_seq extends uvm_sequence;
endfunction
virtual function void setup_umode_reg(privileged_mode_t mode, ref riscv_privil_reg regs[$]);
// For implementations that do not provide any U-mode CSRs, return immediately
if (!riscv_instr_pkg::support_umode_trap) begin
return;
end
ustatus = riscv_privil_reg::type_id::create("ustatus");
ustatus.init_reg(USTATUS);
`DV_CHECK_RANDOMIZE_FATAL(ustatus, "cannot randomize ustatus")

View file

@ -95,19 +95,27 @@ class riscv_rand_instr extends riscv_instr_base;
constraint csr_instr_c {
// TODO: support CSR instruction in other modes
if(cfg.no_csr_instr || (cfg.init_privileged_mode != MACHINE_MODE)) {
if(cfg.no_csr_instr) {
category != CSR;
} else {
if (cfg.enable_illegal_csr_instruction) {
!(csr inside {implemented_csr});
} else if (cfg.enable_access_invalid_csr_level) {
csr inside {cfg.invalid_priv_mode_csrs};
} else {
// Use scratch register to avoid the side effect of modifying other privileged mode CSR.
if (cfg.init_privileged_mode == MACHINE_MODE) {
csr == MSCRATCH;
if (MSCRATCH inside {implemented_csr}) {
csr == MSCRATCH;
}
} else if (cfg.init_privileged_mode == SUPERVISOR_MODE) {
csr == SSCRATCH;
if (SSCRATCH inside {implemented_csr}) {
csr == SSCRATCH;
}
} else {
csr == USCRATCH;
if (USCRATCH inside {implemented_csr}) {
csr == USCRATCH;
}
}
}
}

View file

@ -29,169 +29,4 @@
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_arithmetic_basic_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_rand_instr_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
rtl_test: core_base_test
- test: riscv_jump_stress_test
description: >
Stress back-to-back jump instruction test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_1=riscv_jal_instr,20
rtl_test: core_base_test
- test: riscv_loop_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_1=riscv_loop_instr,20
rtl_test: core_base_test
- test: riscv_rand_jump_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=20
+directed_instr_0=riscv_load_store_rand_instr_stream,8
rtl_test: core_base_test
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test
- test: riscv_no_fence_test
description: >
Random instruction with FENCE disabled, used to test processor pipeline with
less stall/flush operations caused by FENCE instruction.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+no_fence=1
rtl_test: core_base_test
- test: riscv_illegal_instr_test
description: >
Illegal instruction test, verify the processor can detect illegal
instruction and handle corresponding exception properly. An exception
handling routine is designed to resume execution after illegal
instruction exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+illegal_instr_ratio=5
rtl_test: core_base_test
- test: riscv_ebreak_test
description: >
Random instruction test with ebreak instruction enabled. Debug mode is not
enabled for this test, processor should raise ebreak exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
- test: riscv_ebreak_debug_mode_test
description: >
Ebreak instruction test with debug mode enabled.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
sim_opts: >
+require_signature_addr=1
+enable_debug_seq=1
compare_opts: >
+compare_final_value_only=1
- test: riscv_full_interrupt_test
description: >
Random instruction test with complete interrupt handling
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+enable_interrupt=1
rtl_test: core_base_test
sim_opts: >
+enable_irq_seq=1
compare_opts: >
+compare_final_value_only=1
# Please enable this test for your RTL simulation
- test: riscv_csr_test
description: >
Test all CSR instructions on all implemented CSR registers
iterations: 0
no_iss: 1
rtl_test: core_csr_test
no_post_compare: 1
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
iterations: 1
gen_test: riscv_instr_base_test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=6000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
+directed_instr_3=riscv_mem_region_stress_test,5
+enable_unaligned_load_store=1
rtl_test: core_base_test
- import: <riscv_dv_root>/yaml/base_testlist.yaml

View file

@ -29,59 +29,8 @@
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_arithmetic_basic_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- import: <riscv_dv_root>/yaml/base_testlist.yaml
- test: riscv_rand_instr_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
rtl_test: core_base_test
- test: riscv_jump_stress_test
description: >
Back to back jump instruction test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_1=riscv_jal_instr,20
rtl_test: core_base_test
- test: riscv_loop_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_1=riscv_loop_instr,20
rtl_test: core_base_test
- test: riscv_non_compressed_instr_test
description: >
@ -92,53 +41,6 @@
+disable_compressed_instr=1
rtl_test: core_base_test
- test: riscv_rand_jump_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=20
+directed_instr_0=riscv_load_store_rand_instr_stream,8
rtl_test: core_base_test
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test
- test: riscv_no_fence_test
description: >
Random instruction with FENCE disabled, used to test processor pipeline with
less stall/flush operations caused by FENCE instruction.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+no_fence=1
rtl_test: core_base_test
- test: riscv_illegal_instr_test
description: >
Illegal instruction test, verify the processor can detect illegal
instruction and handle corresponding exception properly. An exception
handling routine is designed to resume execution after illegal
instruction exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+illegal_instr_ratio=5
rtl_test: core_base_test
- test: riscv_hint_instr_test
description: >
@ -150,67 +52,3 @@
+hint_instr_ratio=5
rtl_test: core_base_test
- test: riscv_ebreak_test
description: >
Random instruction test with ebreak instruction enabled. Debug mode is not
enabled for this test, processor should raise ebreak exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
- test: riscv_ebreak_debug_mode_test
description: >
Ebreak instruction test with debug mode enabled.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
sim_opts: >
+require_signature_addr=1
+enable_debug_seq=1
compare_opts: >
+compare_final_value_only=1
- test: riscv_full_interrupt_test
description: >
Random instruction test with complete interrupt handling
iterations: 2
gen_test: riscv_rand_instr_test
+enable_interrupt=1
gen_opts: >
rtl_test: core_base_test
sim_opts: >
+enable_irq_seq=1
compare_opts: >
+compare_final_value_only=1
# Please enable this test for your RTL simulation
- test: riscv_csr_test
description: >
Test all CSR instructions on all implemented CSR registers
iterations: 0
no_iss: 1
rtl_test: core_csr_test
no_post_compare: 1
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
iterations: 1
gen_test: riscv_instr_base_test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=6000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
+directed_instr_3=riscv_mem_region_stress_test,5
+enable_unaligned_load_store=1
rtl_test: core_base_test

View file

@ -29,20 +29,8 @@
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_arithmetic_basic_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- import: <riscv_dv_root>/target/rv64imc/testlist.yaml
- test: riscv_machine_mode_rand_test
description: >
@ -65,80 +53,21 @@
+num_of_sub_program=5
rtl_test: core_base_test
- test: riscv_rand_instr_test
# TODO: Only enable booting into U-mode for now, as OVPsim doesn't support some debug CSRs
- test: riscv_invalid_csr_test
description: >
Random instruction stress test
Boot core into random privileged mode and generate csr accesses to invalid CSRs (at a higher priv mode)
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
rtl_test: core_base_test
- test: riscv_jump_stress_test
description: >
Stress back-to-back jump instruction test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+stream_name_0=riscv_jal_instr
+stream_freq_0=10
rtl_test: core_base_test
- test: riscv_loop_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_1=riscv_loop_instr,20
rtl_test: core_base_test
- test: riscv_non_compressed_instr_test
description: >
Random instruction test without compressed instructions
iterations: 1
gen_test: riscv_rand_instr_test
gen_opts: >
+disable_compressed_instr=1
rtl_test: core_base_test
- test: riscv_rand_jump_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=20
+directed_instr_0=riscv_load_store_rand_instr_stream,8
rtl_test: core_base_test
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test
+require_signature_addr=1
+instr_cnt=6000
+num_of_sub_program=0
+enable_access_invalid_csr_level=1
+boot_mode=u
rtl_test: core_invalid_csr_test
sim_opts: >
+require_signature_addr=1
# TODO: Re-enable this test after all the data/instruction page organization changes are done
- test: riscv_page_table_exception_test
@ -151,16 +80,6 @@
+enable_page_table_exception=1
rtl_test: core_base_test
- test: riscv_no_fence_test
description: >
Random instruction with FENCE disabled, used to test processor pipeline with
less stall/flush operations caused by FENCE instruction.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+no_fence=1
rtl_test: core_base_test
- test: riscv_sfence_exception_test
description: >
Random instruction test with S.FENCE exceptions
@ -170,92 +89,6 @@
+allow_sfence_exception=1
rtl_test: core_base_test
- test: riscv_illegal_instr_test
description: >
Illegal instruction test, verify the processor can detect illegal
instruction and handle corresponding exception properly. An exception
handling routine is designed to resume execution after illegal
instruction exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+illegal_instr_ratio=5
rtl_test: core_base_test
- test: riscv_hint_instr_test
description: >
HINT instruction test, verify the processor can detect HINT instruction
treat it as NOP. No illegal instruction exception is expected
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+hint_instr_ratio=5
rtl_test: core_base_test
- test: riscv_ebreak_test
description: >
Random instruction test with ebreak instruction enabled. Debug mode is not
enabled for this test, processor should raise ebreak exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
- test: riscv_ebreak_debug_mode_test
description: >
Ebreak instruction test with debug mode enabled.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
sim_opts: >
+require_signature_addr=1
+enable_debug_seq=1
compare_opts: >
+compare_final_value_only=1
- test: riscv_full_interrupt_test
description: >
Random instruction test with complete interrupt handling
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+enable_interrupt=1
rtl_test: core_base_test
sim_opts: >
+enable_irq_seq=1
compare_opts: >
+compare_final_value_only=1
# Please enable this test for your RTL simulation
- test: riscv_csr_test
description: >
Test all CSR instructions on all implemented CSR registers
iterations: 0
no_iss: 1
rtl_test: core_csr_test
no_post_compare: 1
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
iterations: 1
gen_test: riscv_instr_base_test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=6000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
+directed_instr_3=riscv_mem_region_stress_test,5
+enable_unaligned_load_store=1
rtl_test: core_base_test
- test: riscv_amo_test
description: >

View file

@ -29,189 +29,4 @@
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_arithmetic_basic_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_rand_instr_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
rtl_test: core_base_test
- test: riscv_jump_stress_test
description: >
Stress back-to-back jump instruction test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_1=riscv_jal_instr,20
rtl_test: core_base_test
- test: riscv_loop_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_1=riscv_loop_instr,20
rtl_test: core_base_test
- test: riscv_non_compressed_instr_test
description: >
Random instruction test without compressed instructions
iterations: 1
gen_test: riscv_rand_instr_test
gen_opts: >
+disable_compressed_instr=1
rtl_test: core_base_test
- test: riscv_rand_jump_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=20
+directed_instr_0=riscv_load_store_rand_instr_stream,8
rtl_test: core_base_test
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test
- test: riscv_no_fence_test
description: >
Random instruction with FENCE disabled, used to test processor pipeline with
less stall/flush operations caused by FENCE instruction.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+no_fence=1
rtl_test: core_base_test
- test: riscv_illegal_instr_test
description: >
Illegal instruction test, verify the processor can detect illegal
instruction and handle corresponding exception properly. An exception
handling routine is designed to resume execution after illegal
instruction exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+illegal_instr_ratio=5
rtl_test: core_base_test
- test: riscv_hint_instr_test
description: >
HINT instruction test, verify the processor can detect HINT instruction
treat it as NOP. No illegal instruction exception is expected
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+hint_instr_ratio=5
rtl_test: core_base_test
- test: riscv_ebreak_test
description: >
Random instruction test with ebreak instruction enabled. Debug mode is not
enabled for this test, processor should raise ebreak exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
- test: riscv_ebreak_debug_mode_test
description: >
Ebreak instruction test with debug mode enabled.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
sim_opts: >
+require_signature_addr=1
+enable_debug_seq=1
compare_opts: >
+compare_final_value_only=1
- test: riscv_full_interrupt_test
description: >
Random instruction test with complete interrupt handling
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+enable_interrupt=1
rtl_test: core_base_test
sim_opts: >
+enable_irq_seq=1
compare_opts: >
+compare_final_value_only=1
# Please enable this test for your RTL simulation
- test: riscv_csr_test
description: >
Test all CSR instructions on all implemented CSR registers
iterations: 0
no_iss: 1
rtl_test: core_csr_test
no_post_compare: 1
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
iterations: 1
gen_test: riscv_instr_base_test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=6000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
+directed_instr_3=riscv_mem_region_stress_test,5
+enable_unaligned_load_store=1
rtl_test: core_base_test
- import: <riscv_dv_root>/target/rv32imc/testlist.yaml

View file

@ -13,7 +13,7 @@ class riscv_instr_cov_test extends uvm_test;
int unsigned entry_cnt;
int unsigned total_entry_cnt;
int unsigned skipped_cnt;
int unsigned illegal_instr_cnt;
int unsigned unexpected_illegal_instr_cnt;
`uvm_component_utils(riscv_instr_cov_test)
`uvm_component_new
@ -46,8 +46,12 @@ class riscv_instr_cov_test extends uvm_test;
instr_cg = new(cfg);
`uvm_info(`gfn, $sformatf("%0d CSV trace files to be processed", trace_csv.size()), UVM_LOW)
foreach (trace_csv[i]) begin
bit expect_illegal_instr;
entry_cnt = 0;
instr_cg.reset();
if (uvm_is_match("*illegal*", trace_csv[i])) begin
expect_illegal_instr = 1;
end
`uvm_info(`gfn, $sformatf("Processing CSV trace[%0d]: %s", i, trace_csv[i]), UVM_LOW)
fd = $fopen(trace_csv[i], "r");
if (fd) begin
@ -77,9 +81,17 @@ class riscv_instr_cov_test extends uvm_test;
// TODO: Enable functional coverage for AMO test
continue;
end
`uvm_info(`gfn, $sformatf("Processing line[%0d] : %0s",
entry_cnt, trace["str"]), UVM_FULL)
if (!sample()) begin
`uvm_info(`gfn, $sformatf("Found illegal instr: %0s [%0s]",
trace["instr"], line), UVM_LOW)
if (expect_illegal_instr) begin
`uvm_info(`gfn, $sformatf("Found illegal instr: %0s [%0s]",
trace["instr"], line), UVM_HIGH)
end else begin
unexpected_illegal_instr_cnt += 1;
`uvm_error(`gfn, $sformatf("Found illegal instr: %0s [%0s]",
trace["instr"], line))
end
end
end
entry_cnt += 1;
@ -93,12 +105,9 @@ class riscv_instr_cov_test extends uvm_test;
end
`uvm_info(`gfn, $sformatf("Finished processing %0d trace CSV, %0d instructions",
trace_csv.size(), total_entry_cnt), UVM_LOW)
if ((skipped_cnt > 0) || (illegal_instr_cnt > 0)) begin
if ((skipped_cnt > 0) || (unexpected_illegal_instr_cnt > 0)) begin
`uvm_error(`gfn, $sformatf("%0d instructions skipped, %0d illegal instruction",
skipped_cnt, illegal_instr_cnt))
end else begin
`uvm_info(`gfn, "TEST PASSED", UVM_NONE);
skipped_cnt, unexpected_illegal_instr_cnt))
end
endtask
@ -127,7 +136,6 @@ class riscv_instr_cov_test extends uvm_test;
val[6:2], trace["instr_str"]), UVM_LOW)
instr_cg.opcode_cg.sample(val[6:2]);
end
illegal_instr_cnt++;
return 1'b0;
endfunction
@ -242,4 +250,23 @@ class riscv_instr_cov_test extends uvm_test;
end
endfunction
function void report_phase(uvm_phase phase);
uvm_report_server rs;
int error_count;
rs = uvm_report_server::get_server();
error_count = rs.get_severity_count(UVM_WARNING) +
rs.get_severity_count(UVM_ERROR) +
rs.get_severity_count(UVM_FATAL);
if (error_count == 0) begin
`uvm_info("", "TEST PASSED", UVM_NONE);
end else begin
`uvm_info("", "TEST FAILED", UVM_NONE);
end
`uvm_info("", "TEST GENERATION DONE", UVM_NONE);
super.report_phase(phase);
endfunction
endclass

View file

@ -31,7 +31,7 @@ class riscv_rand_instr_test extends riscv_instr_base_test;
virtual function void apply_directed_instr();
// Mix below directed instructino streams with the random instructions
asm_gen.add_directed_instr_stream("riscv_load_store_rand_instr_stream", 4);
asm_gen.add_directed_instr_stream("riscv_loop_instr", 4);
asm_gen.add_directed_instr_stream("riscv_loop_instr", 3);
asm_gen.add_directed_instr_stream("riscv_jal_instr", 4);
asm_gen.add_directed_instr_stream("riscv_hazard_instr_stream", 4);
asm_gen.add_directed_instr_stream("riscv_load_store_hazard_instr_stream", 4);

View file

@ -0,0 +1,201 @@
# Copyright Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ================================================================================
# Regression test list format
# --------------------------------------------------------------------------------
# test : Assembly test name
# description : Description of this test
# gen_opts : Instruction generator options
# iterations : Number of iterations of this test
# no_iss : Enable/disable ISS simulator (Optional)
# gen_test : Test name used by the instruction generator
# rtl_test : RTL simulation test name
# cmp_opts : Compile options passed to the instruction generator
# sim_opts : Simulation options passed to the instruction generator
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
# compare_opts : Options for the RTL & ISS trace comparison
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_arithmetic_basic_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_rand_instr_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
+directed_instr_7=riscv_load_store_rand_addr_instr_stream,4
rtl_test: core_base_test
- test: riscv_jump_stress_test
description: >
Stress back-to-back jump instruction test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_1=riscv_jal_instr,20
rtl_test: core_base_test
- test: riscv_loop_test
description: >
Random instruction stress test
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=5
+directed_instr_1=riscv_loop_instr,20
rtl_test: core_base_test
- test: riscv_rand_jump_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=20
+directed_instr_0=riscv_load_store_rand_instr_stream,8
rtl_test: core_base_test
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test
- test: riscv_no_fence_test
description: >
Random instruction with FENCE disabled, used to test processor pipeline with
less stall/flush operations caused by FENCE instruction.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+no_fence=1
rtl_test: core_base_test
- test: riscv_illegal_instr_test
description: >
Illegal instruction test, verify the processor can detect illegal
instruction and handle corresponding exception properly. An exception
handling routine is designed to resume execution after illegal
instruction exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+illegal_instr_ratio=5
rtl_test: core_base_test
- test: riscv_ebreak_test
description: >
Random instruction test with ebreak instruction enabled. Debug mode is not
enabled for this test, processor should raise ebreak exception.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
rtl_test: core_base_test
- test: riscv_ebreak_debug_mode_test
description: >
Ebreak instruction test with debug mode enabled.
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+instr_cnt=6000
+no_ebreak=0
+require_signature_addr=1
rtl_test: core_base_test
sim_opts: >
+require_signature_addr=1
+enable_debug_seq=1
compare_opts: >
+compare_final_value_only=1
- test: riscv_full_interrupt_test
description: >
Random instruction test with complete interrupt handling
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+enable_interrupt=1
+require_signature_addr=1
rtl_test: core_base_test
sim_opts: >
+enable_irq_seq=1
+require_signature_addr=1
compare_opts: >
+compare_final_value_only=1
# Please enable this test for your RTL simulation
- test: riscv_csr_test
description: >
Test all CSR instructions on all implemented CSR registers
iterations: 0
no_iss: 1
rtl_test: core_csr_test
no_post_compare: 1
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
iterations: 1
gen_test: riscv_instr_base_test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=6000
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
+directed_instr_3=riscv_mem_region_stress_test,5
+enable_unaligned_load_store=1
rtl_test: core_base_test