diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 9896f942..8a250605 100644 --- a/vendor/google_riscv-dv.lock.hjson +++ b/vendor/google_riscv-dv.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/google/riscv-dv - rev: 4b333ba1ef285ec4508c606efa64610136154a5e + rev: 39ca85903eea94350d3a610256307346da407e5b } } diff --git a/vendor/google_riscv-dv/cov.py b/vendor/google_riscv-dv/cov.py index 16d9dd0c..4e153c36 100644 --- a/vendor/google_riscv-dv/cov.py +++ b/vendor/google_riscv-dv/cov.py @@ -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) diff --git a/vendor/google_riscv-dv/run.py b/vendor/google_riscv-dv/run.py index 138b7be6..f2942b7a 100644 --- a/vendor/google_riscv-dv/run.py +++ b/vendor/google_riscv-dv/run.py @@ -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)) diff --git a/vendor/google_riscv-dv/scripts/lib.py b/vendor/google_riscv-dv/scripts/lib.py index 56852fd3..34fe797b 100644 --- a/vendor/google_riscv-dv/scripts/lib.py +++ b/vendor/google_riscv-dv/scripts/lib.py @@ -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, 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) diff --git a/vendor/google_riscv-dv/scripts/ovpsim_log_to_trace_csv.py b/vendor/google_riscv-dv/scripts/ovpsim_log_to_trace_csv.py index ca9fd053..e9e49a91 100644 --- a/vendor/google_riscv-dv/scripts/ovpsim_log_to_trace_csv.py +++ b/vendor/google_riscv-dv/scripts/ovpsim_log_to_trace_csv.py @@ -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[a-z]*?)\s(?P.*)", 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 = [] diff --git a/vendor/google_riscv-dv/scripts/riscv_trace_csv.py b/vendor/google_riscv-dv/scripts/riscv_trace_csv.py index a909265a..27036baf 100644 --- a/vendor/google_riscv-dv/scripts/riscv_trace_csv.py +++ b/vendor/google_riscv-dv/scripts/riscv_trace_csv.py @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv index fdbdfcf8..ac68d128 100644 --- a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv +++ b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv @@ -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], diff --git a/vendor/google_riscv-dv/src/riscv_instr_base.sv b/vendor/google_riscv-dv/src/riscv_instr_base.sv index 0cf2266c..de58abea 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_base.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_base.sv @@ -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) diff --git a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv index f101baf9..a0528db0 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv @@ -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; diff --git a/vendor/google_riscv-dv/src/riscv_instr_stream.sv b/vendor/google_riscv-dv/src/riscv_instr_stream.sv index 7b9dfd1b..a38c4e9a 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_stream.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_stream.sv @@ -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(); diff --git a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv index e26e9350..92b05706 100644 --- a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv @@ -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 - 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: /yaml/base_testlist.yaml diff --git a/vendor/google_riscv-dv/target/rv32imc/testlist.yaml b/vendor/google_riscv-dv/target/rv32imc/testlist.yaml index 688bb666..4d1b24bb 100644 --- a/vendor/google_riscv-dv/target/rv32imc/testlist.yaml +++ b/vendor/google_riscv-dv/target/rv32imc/testlist.yaml @@ -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: /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 diff --git a/vendor/google_riscv-dv/target/rv64gc/testlist.yaml b/vendor/google_riscv-dv/target/rv64gc/testlist.yaml index 6642b34f..27db94dd 100644 --- a/vendor/google_riscv-dv/target/rv64gc/testlist.yaml +++ b/vendor/google_riscv-dv/target/rv64gc/testlist.yaml @@ -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: /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: > diff --git a/vendor/google_riscv-dv/target/rv64imc/testlist.yaml b/vendor/google_riscv-dv/target/rv64imc/testlist.yaml index 944da6e4..726fb13f 100644 --- a/vendor/google_riscv-dv/target/rv64imc/testlist.yaml +++ b/vendor/google_riscv-dv/target/rv64imc/testlist.yaml @@ -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: /target/rv32imc/testlist.yaml diff --git a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv index 01eb2638..373f566f 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv @@ -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 diff --git a/vendor/google_riscv-dv/test/riscv_instr_test_lib.sv b/vendor/google_riscv-dv/test/riscv_instr_test_lib.sv index 8d93b8b4..9f35d557 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_test_lib.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_test_lib.sv @@ -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); diff --git a/vendor/google_riscv-dv/yaml/base_testlist.yaml b/vendor/google_riscv-dv/yaml/base_testlist.yaml new file mode 100644 index 00000000..e02753f9 --- /dev/null +++ b/vendor/google_riscv-dv/yaml/base_testlist.yaml @@ -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