diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 98ec2123..9aa2fa0d 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: d69190682078470bc6d5661d72f873ae9850ae53 + rev: 5b1dd4e2eb11d49d3275da80953efc0c50f90447 } } diff --git a/vendor/google_riscv-dv/.gitignore b/vendor/google_riscv-dv/.gitignore index 6e29a600..f2494913 100644 --- a/vendor/google_riscv-dv/.gitignore +++ b/vendor/google_riscv-dv/.gitignore @@ -7,3 +7,7 @@ work/ /.project /outdir/ ucli.key +qrun.out/ +qrun.log +*.ucdb +*.vstf diff --git a/vendor/google_riscv-dv/README.md b/vendor/google_riscv-dv/README.md index 0a165195..1025abf4 100644 --- a/vendor/google_riscv-dv/README.md +++ b/vendor/google_riscv-dv/README.md @@ -23,6 +23,14 @@ A CSR test generation script written in Python is also provided, to generate a directed test suite that stresses all CSR instructions on all of the CSRs that the core implements. +## External contributions and collaborations + +This repository is still under active development. We hope the RISC-V processor +verification platform development to be a collaborative effort of the RISC-V +community. Free feel to submit issues, feature requests, pull requests through +Github. You can also send your private collaboration request to [riscv_dv_dev@google.com](riscv_dv_dev@google.com). +Please refer to CONTRIBUTING.md for license related questions. + ## Getting Started ### Prerequisites @@ -32,10 +40,10 @@ which supports SystemVerilog and UVM 1.2. This generator has been verified with Synopsys VCS, Cadence Incisive/Xcelium, and Mentor Questa simulators. Please make sure the EDA tool environment is properly setup before running the generator. -Install YAML python package: +Install dependencies needed for running: ```bash -pip3 install PyYAML +pip3 install -r requirements.txt ``` ### Setup RISCV-GCC compiler toolchain @@ -101,8 +109,9 @@ python3 run.py --test riscv_arithmetic_basic_test --simulator ius python3 run.py --test riscv_arithmetic_basic_test --simulator vcs python3 run.py --test riscv_arithmetic_basic_test --simulator questa python3 run.py --test riscv_arithmetic_basic_test --simulator dsim +python3 run.py --test riscv_arithmetic_basic_test --simulator qrun ``` -The complete test list can be found in [yaml/testlist.yaml](https://github.com/google/riscv-dv/blob/master/yaml/testlist.yaml). To run a full +The complete test list can be found in [yaml/base_testlist.yaml](https://github.com/google/riscv-dv/blob/master/yaml/base_testlist.yaml). To run a full regression, simply use below command ```bash @@ -121,6 +130,9 @@ Here's a few more examples of the run command: # Run a single test 10 times python3 run.py --test riscv_arithmetic_basic_test --iterations 10 +# Run multiple tests +python3 run.py --test riscv_arithmetic_basic_test,riscv_rand_instr_test + # Run a test with verbose logging python3 run.py --test riscv_arithmetic_basic_test --verbose @@ -373,16 +385,6 @@ matching rv32/rv64/rv128 entry and fill in the appropriate CSR field entries. ### Privileged CSR Test Generation (optional) -To be able to run the CSR generation script, the open-source `bitstring` -Python library is required ([bitstring](https://github.com/scott-griffiths/bitstring)). -To install this library, either clone the repository and run the `setup.py` -setup script, or run only one of the below commands: - -```bash -sudo apt-get install python3-bitstring (or your OS-specific package manager) -pip install bitstring -``` - The CSR generation script is located at [scripts/gen_csr_test.py](https://github.com/google/riscv-dv/blob/master/scripts/gen_csr_test.py). The CSR test code that this script generates will execute every CSR instruction @@ -446,9 +448,13 @@ upstream changes to a minimum. different directory, you can use "-ext " to override the user extension path. - Create a new target directory and customize the setting and testlist -- Run the generator with "--custom_target --isa --mabi " +- Run the generator with `--custom_target --isa --mabi ` - Use command line type override to use your extended classes. - --sim_opts="+uvm_set_type_override=," + `--sim_opts="+uvm_set_type_override=,"` +- If extending `riscv_asm_program_gen` class is desired, must use this command + line override: + `--sim_opts="+uvm_set_inst_override=riscv_asm_program_gen,,'uvm_test_top.asm_gen'"` You can refer to [riscv-dv extension for ibex](https://github.com/lowRISC/ibex/blob/master/dv/uvm/Makefile#L68) for a working example. @@ -521,7 +527,7 @@ implmentation. ```bash # Randomly generate 100000 instructions, split to 20000 instructions per batch -python3 cov.py -d -i 100000 -bz 20000 +python3 cov.py -d -i 100000 -bz 20000 --isa rv32imc ``` @@ -531,13 +537,6 @@ Please file an issue under this repository for any bug report / integration issue / feature request. We are looking forward to knowing your experience of using this flow and how we can make it better together. -## External contributions - -We definitely welcome external contributions. We hope it could be a -collaborative effort to build a strong open source RISC-V processor -verification platform. Free feel to submit your pull request for review. -Please refer to CONTRIBUTING.md for license related questions. - ## Disclaimer This is not an officially supported Google product. diff --git a/vendor/google_riscv-dv/cov.py b/vendor/google_riscv-dv/cov.py index 4e153c36..a85ebef3 100644 --- a/vendor/google_riscv-dv/cov.py +++ b/vendor/google_riscv-dv/cov.py @@ -23,7 +23,6 @@ import re import sys import logging -from datetime import date from scripts.lib import * from scripts.spike_log_to_trace_csv import * from scripts.ovpsim_log_to_trace_csv import * @@ -31,11 +30,13 @@ from scripts.sail_log_to_trace_csv import * LOGGER = logging.getLogger() + def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \ opts, timeout, simulator, simulator_yaml, custom_target, \ - isa, target, stop_on_first_error): + isa, target, stop_on_first_error, + dont_truncate_after_first_ecall, + vector_options, coverage_options, compliance_mode): """Collect functional coverage from the instruction trace - Args: log_dir : Trace log directory out : Output directory @@ -53,6 +54,9 @@ def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \ isa : RISC-V ISA variant target : Predefined target stop_on_first_error : will end run on first error detected + vector_options : Enable Vectors and set vector config options + coverage_options : Set coverage config options + compliance_mode : Run coverage model for compliance test """ cwd = os.path.dirname(os.path.realpath(__file__)) log_list = [] @@ -87,28 +91,40 @@ def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \ if iss == "spike": process_spike_sim_log(log, csv, 1) elif iss == "ovpsim": - process_ovpsim_sim_log(log, csv, 1, stop_on_first_error) + process_ovpsim_sim_log(log, csv, 1, stop_on_first_error, + dont_truncate_after_first_ecall) else: logging.error("Full trace for %s is not supported yet" % iss) - sys.exit(1) + sys.exit(RET_FAIL) if steps == "all" or re.match("cov", steps): + opts_vec = "" + opts_cov = "" + if vector_options: + opts_vec = ("%0s" % vector_options) + if coverage_options: + opts_cov = ("%0s" % coverage_options) + if compliance_mode: + opts_cov += " +define+COMPLIANCE_MODE" build_cmd = ("python3 %s/run.py --simulator %s --simulator_yaml %s " - " --co -o %s --cov -tl %s %s " % - (cwd, simulator, simulator_yaml, out, testlist, opts)) + " --co -o %s --cov -tl %s %s --cmp_opts \"%s %s\" " % + (cwd, simulator, simulator_yaml, out, testlist, opts, + opts_vec, opts_cov)) base_sim_cmd = ("python3 %s/run.py --simulator %s --simulator_yaml %s " "--so -o %s --cov -tl %s %s " - "-tn riscv_instr_cov_test --steps gen --sim_opts \"\"" % - (cwd, simulator, simulator_yaml, out, testlist, opts)) + "-tn riscv_instr_cov_test --steps gen --sim_opts \" %s %s\" " % + (cwd, simulator, simulator_yaml, out, testlist, opts, + opts_vec, opts_cov)) if target: build_cmd += (" --target %s" % target) - if custom_target: - build_cmd += (" --custom_target %s" % custom_target) - if target: base_sim_cmd += (" --target %s" % target) if custom_target: + build_cmd += (" --custom_target %s" % custom_target) base_sim_cmd += (" --custom_target %s" % custom_target) + if stop_on_first_error: + build_cmd += (" --stop_on_first_error") + base_sim_cmd += (" --stop_on_first_error") logging.info("Building the coverage collection framework") - output = run_cmd(build_cmd) + run_cmd(build_cmd) file_idx = 0 trace_idx = 0 trace_csv_opts = "" @@ -119,12 +135,11 @@ def collect_cov(log_dir, out, core, iss, testlist, batch_size, lsf_cmd, steps, \ batch_cnt = (len(csv_list)+batch_size-1)/batch_size; logging.info("Batch size: %0d, Batch cnt:%0d" % (batch_size, batch_cnt)) for i in range(len(csv_list)): + file_idx = 0 + trace_idx = i if batch_size > 0: file_idx = i / batch_size; trace_idx = i % batch_size; - else: - file_idx = 0 - trace_idx = i trace_csv_opts += (" +trace_csv_%0d=%s" % (trace_idx, csv_list[i])) if ((i == len(csv_list)-1) or ((batch_size > 0) and (trace_idx == batch_size-1))): sim_cmd = base_sim_cmd.replace("", trace_csv_opts) @@ -165,34 +180,30 @@ def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd,\ build_cmd = ("python3 %s/run.py --simulator %s --simulator_yaml %s " "--co -o %s --cov -tl %s %s" % (cwd, simulator, simulator_yaml, out, testlist, opts)) - if target: - build_cmd += (" --target %s" % target) - if custom_target: - build_cmd += (" --custom_target %s" % custom_target) - run_cmd(build_cmd) base_sim_cmd = ("python3 %s/run.py --simulator %s --simulator_yaml %s " - "--so -o %s --cov -tl %s --isa %s%s " + "--so -o %s --cov -tl %s --isa %s %s " "-tn riscv_instr_cov_debug_test --steps gen " "--sim_opts \"+num_of_iterations=\"" % (cwd, simulator, simulator_yaml, out, testlist, isa, opts)) if target: + build_cmd += (" --target %s" % target) base_sim_cmd += (" --target %s" % target) if custom_target: + build_cmd += (" --custom_target %s" % custom_target) base_sim_cmd += (" --custom_target %s" % custom_target) + logging.info("Building the coverage collection framework") + run_cmd(build_cmd) + batch_cnt = 1 if batch_size > 0: batch_cnt = int((instr_cnt+batch_size-1)/batch_size) logging.info("Batch size: %0d, Batch cnt:%0d" % (batch_size, batch_cnt)) - else: - batch_cnt = 1 logging.info("Randomizing %0d instructions in %0d batches", instr_cnt, batch_cnt) for i in range(batch_cnt): + batch_instr_cnt = instr_cnt if batch_size > 0: + batch_instr_cnt = batch_size if i == batch_cnt - 1: batch_instr_cnt = instr_cnt - batch_size * (batch_cnt - 1) - else: - batch_instr_cnt = batch_size - else: - batch_instr_cnt = instr_cnt sim_cmd = base_sim_cmd.replace("", str(batch_instr_cnt)) sim_cmd += (" --log_suffix _%d" % i) if lsf_cmd == "": @@ -223,6 +234,8 @@ def setup_parser(): help="Number of CSV to process per run") parser.add_argument("-d", "--debug_mode", dest="debug_mode", action="store_true", help="Debug mode, randomize and sample the coverage directly") + parser.add_argument("--compliance_mode", action="store_true", + help="Run the coverage model in compliance test mode") parser.add_argument("-i", "--instr_cnt", dest="instr_cnt", type=int, default=0, help="Random instruction count for debug mode") parser.add_argument("-to", "--timeout", dest="timeout", type=int, default=1000, @@ -256,11 +269,21 @@ def setup_parser(): help="Path for the riscv_core_setting.sv") parser.add_argument("--stop_on_first_error", dest="stop_on_first_error", action="store_true", help="Stop on detecting first error") - parser.set_defaults(verbose=False) - parser.set_defaults(debug_mode=False) - parser.set_defaults(stop_on_first_error=False) + parser.add_argument("--dont_truncate_after_first_ecall", dest="dont_truncate_after_first_ecall", + action="store_true", help="Do not truncate log and csv file on first ecall") parser.add_argument("--noclean", action="store_true", help="Do not clean the output of the previous runs") + parser.add_argument("--vector_options", type=str, default="", + help="Enable Vectors and set options") + parser.add_argument("--coverage_options", type=str, default="", + help="Controlling coverage coverpoints") + parser.set_defaults(verbose=False) + parser.set_defaults(debug_mode=False) + parser.set_defaults(compliance_mode=False) + parser.set_defaults(stop_on_first_error=False) + parser.set_defaults(dont_truncate_after_first_ecall=False) + parser.set_defaults(vector_options="") + parser.set_defaults(coverage_options="") return parser def main(): @@ -273,9 +296,6 @@ def main(): if args.verbose: args.opts += "-v" - if not args.testlist: - args.testlist = cwd + "/yaml/cov_testlist.yaml" - if not args.simulator_yaml: args.simulator_yaml = cwd + "/yaml/simulator.yaml" @@ -301,14 +321,12 @@ def main(): args.testlist = cwd + "/yaml/cov_testlist.yaml" ## needed if need to force # Create output directory - if args.o is None: - output_dir = "cov_out_" + str(date.today()) - else: - output_dir = args.o + output_dir = create_output(args.o, "cov_out_") if args.noclean is False: os.system("rm -rf %s" % output_dir) + logging.info("Creating output directory: %s" % output_dir) subprocess.run(["mkdir", "-p", output_dir]) if args.debug_mode: @@ -320,7 +338,11 @@ def main(): collect_cov(args.dir, output_dir, args.core, args.iss, args.testlist, args.batch_size, args.lsf_cmd, args.steps, args.opts, args.timeout, args.simulator, args.simulator_yaml, args.custom_target, - args.isa, args.target, args.stop_on_first_error) + args.isa, args.target, args.stop_on_first_error, + args.dont_truncate_after_first_ecall, + args.vector_options, + args.coverage_options, + args.compliance_mode) logging.info("Coverage results are saved to %s" % output_dir) if __name__ == "__main__": diff --git a/vendor/google_riscv-dv/qrun_option.f b/vendor/google_riscv-dv/qrun_option.f new file mode 100644 index 00000000..bd1de096 --- /dev/null +++ b/vendor/google_riscv-dv/qrun_option.f @@ -0,0 +1,10 @@ +-64 +-uvmhome uvm-1.2 +-sv +-mfcu +-cuname design_cuname ++define+UVM_REGEX_NO_DPI +-debug ++designfile +-o design_opt +-optimize diff --git a/vendor/google_riscv-dv/requirements.txt b/vendor/google_riscv-dv/requirements.txt new file mode 100644 index 00000000..628ceec6 --- /dev/null +++ b/vendor/google_riscv-dv/requirements.txt @@ -0,0 +1,2 @@ +PyYAML +bitstring diff --git a/vendor/google_riscv-dv/run.py b/vendor/google_riscv-dv/run.py index a44c00ff..6ebaad40 100644 --- a/vendor/google_riscv-dv/run.py +++ b/vendor/google_riscv-dv/run.py @@ -23,7 +23,6 @@ import re import sys import logging -from datetime import date from scripts.lib import * from scripts.spike_log_to_trace_csv import * from scripts.ovpsim_log_to_trace_csv import * @@ -33,13 +32,14 @@ from scripts.instr_trace_compare import * LOGGER = logging.getLogger() -def get_generator_cmd(simulator, simulator_yaml, cov): +def get_generator_cmd(simulator, simulator_yaml, cov, exp): """ Setup the compile and simulation command for the generator Args: simulator : RTL simulator used to run instruction generator simulator_yaml : RTL simulator configuration file in YAML format cov : Enable functional coverage + exp : Use experimental version Returns: compile_cmd : RTL simulator command to compile the instruction generator @@ -58,6 +58,8 @@ def get_generator_cmd(simulator, simulator_yaml, cov): compile_cmd[i] = re.sub('', compile_spec['cov_opts'].rstrip(), compile_cmd[i]) else: compile_cmd[i] = re.sub('', '', compile_cmd[i]) + if exp: + compile_cmd[i] += " +define+EXPERIMENTAL " sim_cmd = entry['sim']['cmd'] if ('cov_opts' in entry['sim']) and cov: sim_cmd = re.sub('', entry['sim']['cov_opts'].rstrip(), sim_cmd) @@ -70,7 +72,7 @@ def get_generator_cmd(simulator, simulator_yaml, cov): sim_cmd = re.sub("<"+env_var+">", get_env_var(env_var), sim_cmd) return compile_cmd, sim_cmd logging.error("Cannot find RTL simulator %0s" % simulator) - sys.exit(1) + sys.exit(RET_FAIL) def parse_iss_yaml(iss, iss_yaml, isa, setting_dir): @@ -87,7 +89,6 @@ def parse_iss_yaml(iss, iss_yaml, isa, setting_dir): """ logging.info("Processing ISS setup file : %s" % iss_yaml) yaml_data = read_yaml(iss_yaml) - cwd = os.path.dirname(os.path.realpath(__file__)) # Search for matched ISS for entry in yaml_data: if entry['iss'] == iss: @@ -110,7 +111,7 @@ def parse_iss_yaml(iss, iss_yaml, isa, setting_dir): cmd = re.sub("\", isa, cmd) return cmd logging.error("Cannot find ISS %0s" % iss) - sys.exit(1) + sys.exit(RET_FAIL) def get_iss_cmd(base_cmd, elf, log): @@ -128,17 +129,142 @@ def get_iss_cmd(base_cmd, elf, log): cmd += (" &> %s" % log) return cmd +def do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir, cmp_opts, output_dir): + """Compile the instruction generator + + Args: + compile_cmd : Compile command for the generator + test_list : List of assembly programs to be compiled + core_setting_dir : Path for riscv_core_setting.sv + cwd : Filesystem path to RISCV-DV repo + ext_dir : User extension directory + cmd_opts : Compile options for the generator + output_dir : Output directory of the ELF files + """ + if (not((len(test_list) == 1) and (test_list[0]['test'] == 'riscv_csr_test'))): + logging.info("Building RISC-V instruction generator") + for cmd in compile_cmd: + cmd = re.sub("", os.path.abspath(output_dir), cmd) + cmd = re.sub("", core_setting_dir, cmd) + if ext_dir == "": + cmd = re.sub("", "/user_extension", cmd) + else: + cmd = re.sub("", ext_dir, cmd) + cmd = re.sub("", cwd, cmd) + cmd = re.sub("", cmp_opts, cmd) + + logging.debug("Compile command: %s" % cmd) + run_cmd(cmd) + +def run_csr_test(cmd_list, cwd, csr_file, isa, iterations, lsf_cmd, + end_signature_addr, timeout_s, output_dir): + """Run CSR test + It calls a separate python script to generate directed CSR test code, + located at scripts/gen_csr_test.py. + """ + cmd = "python3 " + cwd + "/scripts/gen_csr_test.py" + \ + (" --csr_file %s" % csr_file) + \ + (" --xlen %s" % re.search(r"(?P[0-9]+)", isa).group("xlen")) + \ + (" --iterations %i" % iterations) + \ + (" --out %s/asm_tests" % output_dir) + \ + (" --end_signature_addr %s" % end_signature_addr) + if lsf_cmd: + cmd_list.append(cmd) + else: + run_cmd(cmd, timeout_s) + +def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file, + isa, end_signature_addr, lsf_cmd, timeout_s, log_suffix, + batch_size, output_dir, verbose, check_return_code): + """Run the instruction generator + + Args: + sim_cmd : Simulate command for the generator + test_list : List of assembly programs to be compiled + cwd : Filesystem path to RISCV-DV repo + sim_opts : Simulation options for the generator + seed_yaml : Seed specification from a prior regression + seed : Seed to the instruction generator + csr_file : YAML file containing description of all CSRs + isa : Processor supported ISA subset + end_signature_addr : Address that tests will write pass/fail signature to at end of test + lsf_cmd : LSF command used to run the instruction generator + timeout_s : Timeout limit in seconds + log_suffix : Simulation log file name suffix + batch_size : Number of tests to generate per run + output_dir : Output directory of the ELF files + check_return_code : Check return code of the command + """ + cmd_list = [] + sim_cmd = re.sub("", os.path.abspath(output_dir), sim_cmd) + sim_cmd = re.sub("", cwd, sim_cmd) + sim_cmd = re.sub("", sim_opts, sim_cmd) + rerun_seed = {} + if seed_yaml: + rerun_seed = read_yaml(seed_yaml) + logging.info("Running RISC-V instruction generator") + sim_seed = {} + for test in test_list: + iterations = test['iterations'] + logging.info("Generating %d %s" % (iterations, test['test'])) + if iterations > 0: + # Running a CSR test + if test['test'] == 'riscv_csr_test': + run_csr_test(cmd_list, cwd, csr_file, isa, iterations, lsf_cmd, + end_signature_addr, timeout_s, output_dir) + else: + batch_cnt = 1 + if batch_size > 0: + batch_cnt = int((iterations + batch_size - 1) / batch_size); + logging.info("Running %s with %0d batches" % (test['test'], batch_cnt)) + for i in range(0, batch_cnt): + test_id = '%0s_%0d' % (test['test'], i) + if test_id in rerun_seed: + rand_seed = rerun_seed[test_id] + else: + rand_seed = get_seed(seed) + if i < batch_cnt - 1: + test_cnt = batch_size + else: + test_cnt = iterations - i * batch_size; + cmd = lsf_cmd + " " + sim_cmd.rstrip() + \ + (" +UVM_TESTNAME=%s " % test['gen_test']) + \ + (" +num_of_tests=%i " % test_cnt) + \ + (" +start_idx=%d " % (i*batch_size)) + \ + (" +asm_file_name=%s/asm_tests/%s " % (output_dir, test['test'])) + \ + (" -l %s/sim_%s_%d%s.log " % (output_dir, test['test'], i, log_suffix)) + if verbose: + cmd += "+UVM_VERBOSITY=UVM_HIGH " + cmd = re.sub("", str(rand_seed), cmd) + sim_seed[test_id] = str(rand_seed) + if "gen_opts" in test: + cmd += test['gen_opts'] + if not re.search("c", isa): + cmd += "+disable_compressed_instr=1 "; + if lsf_cmd: + cmd_list.append(cmd) + else: + logging.info("Running %s, batch %0d/%0d, test_cnt:%0d" % + (test['test'], i+1, batch_cnt, test_cnt)) + run_cmd(cmd, timeout_s, check_return_code = check_return_code) + 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) + if lsf_cmd: + run_parallel_cmd(cmd_list, timeout_s, check_return_code = check_return_code) + + def gen(test_list, csr_file, end_signature_addr, isa, simulator, simulator_yaml, output_dir, sim_only, compile_only, lsf_cmd, seed, cwd, cmp_opts, sim_opts, timeout_s, core_setting_dir, ext_dir, cov, - log_suffix, batch_size, seed_yaml, stop_on_first_error, verbose=False): + log_suffix, batch_size, seed_yaml, verbose, exp): """Run the instruction generator Args: test_list : List of assembly programs to be compiled csr_file : YAML file containing description of all CSRs - end_signature_addr : Address that tests will write pass/fail signature to at end of test + end_signature_addr : Address that tests will write pass/fail signature to isa : Processor supported ISA subset simulator : RTL simulator used to run instruction generator simulator_yaml : RTL simulator configuration file in YAML format @@ -157,105 +283,30 @@ def gen(test_list, csr_file, end_signature_addr, isa, simulator, log_suffix : Simulation log file name suffix batch_size : Number of tests to generate per run seed_yaml : Seed specification from a prior regression - stop_on_first_error : will end run on first error detected + exp : Enable experimental features """ + check_return_code = True + if simulator == "ius": + # Incisive return non-zero return code even test passes + check_return_code = False + logging.debug("Disable return_code checking for %s" % simulator) # Mutually exclusive options between compile_only and sim_only if compile_only and sim_only: logging.error("argument -co is not allowed with argument -so") + if ((compile_only == 0) and (len(test_list) == 0)): + return # Setup the compile and simulation command for the generator compile_cmd = [] sim_cmd = "" - compile_cmd, sim_cmd = get_generator_cmd(simulator, simulator_yaml, cov); - if ((compile_only == 0) and (len(test_list) == 0)): - return + compile_cmd, sim_cmd = get_generator_cmd(simulator, simulator_yaml, cov, exp); # Compile the instruction generator if not sim_only: - if (not((len(test_list) == 1) and (test_list[0]['test'] == 'riscv_csr_test'))): - logging.info("Building RISC-V instruction generator") - for cmd in compile_cmd: - cmd = re.sub("", os.path.abspath(output_dir), cmd) - cmd = re.sub("", core_setting_dir, cmd) - if ext_dir == "": - cmd = re.sub("", "/user_extension", cmd) - else: - cmd = re.sub("", ext_dir, cmd) - cmd = re.sub("", cwd, cmd) - cmd = re.sub("", cmp_opts, cmd) - - logging.debug("Compile command: %s" % cmd) - output = run_cmd(cmd) + do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir, cmp_opts, output_dir) # Run the instruction generator if not compile_only: - cmd_list = [] - sim_cmd = re.sub("", os.path.abspath(output_dir), sim_cmd) - sim_cmd = re.sub("", cwd, sim_cmd) - sim_cmd = re.sub("", sim_opts, sim_cmd) - if seed_yaml: - rerun_seed = read_yaml(seed_yaml) - else: - rerun_seed = {} - logging.info("Running RISC-V instruction generator") - sim_seed = {} - for test in test_list: - iterations = test['iterations'] - logging.info("Generating %d %s" % (iterations, test['test'])) - if iterations > 0: - """ - If we are running a CSR test, need to call a separate python script - to generate directed CSR test code, located at scripts/gen_csr_test.py. - """ - if test['test'] == 'riscv_csr_test': - cmd = "python3 " + cwd + "/scripts/gen_csr_test.py" + \ - (" --csr_file %s" % csr_file) + \ - (" --xlen %s" % re.search(r"(?P[0-9]+)", isa).group("xlen")) + \ - (" --iterations %i" % iterations) + \ - (" --out %s/asm_tests" % output_dir) + \ - (" --end_signature_addr %s" % end_signature_addr) - if lsf_cmd: - cmd_list.append(cmd) - else: - output = run_cmd(cmd, timeout_s) - else: - if batch_size > 0: - batch_cnt = int((iterations + batch_size - 1) / batch_size); - else: - batch_cnt = 1 - logging.info("Running %s with %0d batches" % (test['test'], batch_cnt)) - for i in range(0, batch_cnt): - test_id = '%0s_%0d' % (test['test'], i) - if test_id in rerun_seed: - rand_seed = rerun_seed[test_id] - else: - rand_seed = get_seed(seed) - if i < batch_cnt - 1: - test_cnt = batch_size - else: - test_cnt = iterations - i * batch_size; - cmd = lsf_cmd + " " + sim_cmd.rstrip() + \ - (" +UVM_TESTNAME=%s " % test['gen_test']) + \ - (" +num_of_tests=%i " % test_cnt) + \ - (" +start_idx=%d " % (i*batch_size)) + \ - (" +asm_file_name=%s/asm_tests/%s " % (output_dir, test['test'])) + \ - (" -l %s/sim_%s_%d%s.log " % (output_dir, test['test'], i, log_suffix)) - if verbose: - cmd += "+UVM_VERBOSITY=UVM_HIGH " - cmd = re.sub("", str(rand_seed), cmd) - sim_seed[test_id] = str(rand_seed) - if "gen_opts" in test: - cmd += test['gen_opts'] - if not re.search("c", isa): - cmd += "+disable_compressed_instr=1 "; - if lsf_cmd: - cmd_list.append(cmd) - else: - logging.info("Running %s, batch %0d/%0d, test_cnt:%0d" % - (test['test'], i+1, batch_cnt, test_cnt)) - output = run_cmd(cmd, timeout_s) - 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) - if lsf_cmd: - run_parallel_cmd(cmd_list, timeout_s) + do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file, + isa, end_signature_addr, lsf_cmd, timeout_s, log_suffix, + batch_size, output_dir, verbose, check_return_code) def gcc_compile(test_list, output_dir, isa, mabi, opts): @@ -377,14 +428,13 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, setting_dir, timeout logging.debug(cmd) -def iss_cmp(test_list, iss, output_dir, isa, stop_on_first_error): +def iss_cmp(test_list, iss, output_dir, stop_on_first_error): """Compare ISS simulation reult Args: test_list : List of assembly programs to be compiled iss : List of instruction set simulators output_dir : Output directory of the ELF files - isa : ISA stop_on_first_error : will end run on first error detected """ iss_list = iss.split(",") @@ -406,14 +456,14 @@ def iss_cmp(test_list, iss, output_dir, isa, stop_on_first_error): if iss == "spike": process_spike_sim_log(log, csv) elif iss == "ovpsim": - process_ovpsim_sim_log(log, csv, 1, stop_on_first_error) + process_ovpsim_sim_log(log, csv, 0, stop_on_first_error) elif iss == "sail": process_sail_sim_log(log, csv) elif iss == "whisper": process_whisper_sim_log(log, csv) else: logging.error("Unsupported ISS" % iss) - sys.exit(1) + sys.exit(RET_FAIL) compare_trace_csv(csv_list[0], csv_list[1], iss_list[0], iss_list[1], report) passed_cnt = run_cmd("grep PASSED %s | wc -l" % report).strip() failed_cnt = run_cmd("grep FAILED %s | wc -l" % report).strip() @@ -496,6 +546,8 @@ def setup_parser(): help="Directed assembly test") parser.add_argument("--log_suffix", type=str, default="", help="Simulation log name suffix") + parser.add_argument("--exp", action="store_true", + help="Run generator with experimental features") parser.add_argument("-bz", "--batch_size", type=int, default=0, help="Number of tests to generate per run. You can split a big" " job to small batches with this option") @@ -505,6 +557,7 @@ def setup_parser(): parser.set_defaults(so=False) parser.set_defaults(verbose=False) parser.set_defaults(cov=False) + parser.set_defaults(exp=False) parser.set_defaults(stop_on_first_error=False) return parser @@ -553,8 +606,11 @@ def main(): elif args.target == "ml": args.mabi = "lp64" args.isa = "rv64imc" + elif args.target == "exp": + args.mabi = "lp64" + args.isa = "rv64gc" else: - print ("Unsupported pre-defined target: %0s" % args.target) + sys.exit("Unsupported pre-defined target: %0s" % args.target) else: if re.match(".*gcc_compile.*", args.steps) or re.match(".*iss_sim.*", args.steps): if (not args.mabi) or (not args.isa): @@ -567,11 +623,8 @@ def main(): return # Create output directory - if args.o is None: - output_dir = "out_" + str(date.today()) - else: - output_dir = args.o - + output_dir = create_output(args.o) + logging.info("Creating output directory: %s" % output_dir) subprocess.run(["mkdir", "-p", output_dir]) subprocess.run(["mkdir", "-p", ("%s/asm_tests" % output_dir)]) @@ -590,7 +643,7 @@ def main(): args.co, args.lsf_cmd, args.seed, cwd, args.cmp_opts, args.sim_opts, args.gen_timeout, args.core_setting_dir, args.user_extension_dir, args.cov, args.log_suffix, args.batch_size, - args.seed_yaml, args.stop_on_first_error, args.verbose) + args.seed_yaml, args.verbose, args.exp) if not args.co: # Compile the assembly program to ELF, convert to plain binary @@ -604,7 +657,7 @@ def main(): # Compare ISS simulation result if args.steps == "all" or re.match(".*iss_cmp.*", args.steps): - iss_cmp(matched_list, args.iss, output_dir, args.isa, args.stop_on_first_error) + iss_cmp(matched_list, args.iss, output_dir, args.stop_on_first_error) if __name__ == "__main__": main() diff --git a/vendor/google_riscv-dv/scripts/gen_csr_test.py b/vendor/google_riscv-dv/scripts/gen_csr_test.py index 717a7b4a..bc1ca421 100644 --- a/vendor/google_riscv-dv/scripts/gen_csr_test.py +++ b/vendor/google_riscv-dv/scripts/gen_csr_test.py @@ -32,12 +32,13 @@ import yaml import argparse import random import copy +from lib import * try: from bitstring import BitArray as bitarray except ImportError as e: logging.error("Please install bitstring package: sudo apt-get install python3-bitstring") - sys.exit(1) + sys.exit(RET_FAIL) """ Defines the test's success/failure values, one of which will be written to @@ -176,25 +177,20 @@ def predict_csr_val(csr_op, rs1_val, csr_val, csr_write_mask, csr_read_mask): prediction = None # create a zero bitarray to zero extend immediates zero = bitarray(uint=0, length=csr_val.len - 5) + prediction = csr_read(csr_val, csr_read_mask) if csr_op == 'csrrw': - prediction = csr_read(csr_val, csr_read_mask) csr_write(rs1_val, csr_val, csr_write_mask) elif csr_op == 'csrrs': - prediction = csr_read(csr_val, csr_read_mask) csr_write(rs1_val | prediction, csr_val, csr_write_mask) elif csr_op == 'csrrc': - prediction = csr_read(csr_val, csr_read_mask) csr_write((~rs1_val) & prediction, csr_val, csr_write_mask) elif csr_op == 'csrrwi': - prediction = csr_read(csr_val, csr_read_mask) zero.append(rs1_val[-5:]) csr_write(zero, csr_val, csr_write_mask) elif csr_op == 'csrrsi': - prediction = csr_read(csr_val, csr_read_mask) zero.append(rs1_val[-5:]) csr_write(zero | prediction, csr_val, csr_write_mask) elif csr_op == 'csrrci': - prediction = csr_read(csr_val, csr_read_mask) zero.append(rs1_val[-5:]) csr_write((~zero) & prediction, csr_val, csr_write_mask) return f"0x{prediction.hex}" diff --git a/vendor/google_riscv-dv/scripts/lib.py b/vendor/google_riscv-dv/scripts/lib.py index 34fe797b..4ebe266c 100644 --- a/vendor/google_riscv-dv/scripts/lib.py +++ b/vendor/google_riscv-dv/scripts/lib.py @@ -25,6 +25,12 @@ import time import yaml import logging +from datetime import date + +RET_SUCCESS = 0 +RET_FAIL = 1 +RET_FATAL = -1 + def setup_logging(verbose): """Setup the root logger. @@ -55,7 +61,7 @@ def read_yaml(yaml_file): yaml_data = yaml.safe_load(f) except yaml.YAMLError as exc: logging.error(exc) - sys.exit(1) + sys.exit(RET_FAIL) return yaml_data @@ -72,7 +78,7 @@ def get_env_var(var): val = os.environ[var] except KeyError: logging.warning("Please set the environment variable %0s" % var) - sys.exit(1) + sys.exit(RET_FAIL) return val @@ -87,11 +93,10 @@ def get_seed(seed): """ if seed >= 0: return seed - else: - return random.getrandbits(32) + return random.getrandbits(32) -def run_cmd(cmd, timeout_s = 999, exit_on_error = 1): +def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True): """Run a command and return output Args: @@ -108,9 +113,9 @@ def run_cmd(cmd, timeout_s = 999, exit_on_error = 1): universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as exc: + except subprocess.CalledProcessError: logging.error(ps.communicate()[0]) - sys.exit(1) + sys.exit(RET_FAIL) try: output = ps.communicate(timeout = timeout_s)[0] except subprocess.TimeoutExpired: @@ -118,17 +123,16 @@ def run_cmd(cmd, timeout_s = 999, exit_on_error = 1): 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) + if rc and check_return_code and rc > 0: + logging.info(output) + logging.error("ERROR return code: %d/%d, cmd:%s" % (check_return_code, rc, cmd)) + if exit_on_error: + sys.exit(RET_FAIL) logging.debug(output) return output -def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0): +def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0, check_return_code = True): """Run a list of commands in parallel Args: @@ -155,12 +159,11 @@ def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0): 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) + if rc and check_return_code and rc > 0: + logging.info(output) + logging.error("ERROR return code: %d, cmd:%s" % (rc, cmd)) + if exit_on_error: + sys.exit(RET_FAIL) # Restore stty setting otherwise the terminal may go crazy os.system("stty sane") logging.debug(output) @@ -180,15 +183,30 @@ def process_regression_list(testlist, test, iterations, matched_list, riscv_dv_r """ logging.info("Processing regression test list : %s, test: %s" % (testlist, test)) yaml_data = read_yaml(testlist) + mult_test = test.split(',') for entry in yaml_data: 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 (entry['test'] in mult_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 create_output(output, prefix = "out_"): + """ Create output directory + + Args: + output : Name of specified output directory + + Returns: + Output directory + """ + # Create output directory + if output is None: + return prefix + str(date.today()) + return output 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 e9e49a91..477c4951 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 @@ -27,46 +27,54 @@ from lib import * from riscv_trace_csv import * try: - from ovpsim_log_to_trace_csv_vectors import * + from ovpsim_log_to_trace_csv_vectors import * except: - def assign_operand_vector(a,b,c,d): - """ stub version when no vector processing included """ - logging.info("No OVPsim vector instruction processing included") - if stop_on_first_error: - sys.exit(-1) + def assign_operand_vector(a,b,c,d): + """ stub version when no vector processing included """ + logging.info("No OVPsim vector instruction processing included") + if stop_on_first_error: + sys.exit(RET_FATAL) + def is_an_extension_instruction(instr): + if instr and 'v' in instr[0]: + return True + return False + stop_on_first_error = 0 def fatal (s): - """ ensure we end if a problem """ - logging.fatal("ERROR: "+s) - sys.exit(-1) + """ ensure we end if a problem """ + logging.fatal("ERROR: "+s) + sys.exit(RET_FATAL) def convert_mode(pri, line): - """ OVPsim uses text string, convert to numeric """ - if "Machine" in pri: return str(3) - if "Supervisor" in pri: return str(1) - if "User" in pri: return str(0) - logging.error("convert_mode = UNKNOWN PRIV MODE [%s]: %s" % (pri, line)) - if stop_on_first_error: - sys.exit(-1) + """ OVPsim uses text string, convert to numeric """ + if "Machine" in pri: return str(3) + if "Supervisor" in pri: return str(1) + if "User" in pri: return str(0) + logging.error("convert_mode = UNKNOWN PRIV MODE [%s]: %s" % (pri, line)) + if stop_on_first_error: + sys.exit(RET_FATAL) REGS = ["zero","ra","sp","gp","tp","t0","t1","t2","s0","s1", "a0","a1","a2","a3","a4","a5","a6","a7", "s2","s3","s4","s5","s6","s7","s8","s9","s10","s11", "t3","t4","t5","t6"] +FREGS = ["ft0","ft1","ft2","ft3","ft4","ft5","ft6","ft7","fs0","fs1","fa0", + "fa1","fa2","fa3","fa4","fa5","fa6","fa7","fs2","fs3","fs4","fs5", + "fs6","fs7","fs8","fs9","fs10","fs11","ft8","ft9","ft10","ft11"] def process_jal(trace, operands, gpr): - """ correctly process jal """ - # TODO need to merge with jalr - ## jal rd, imm - if len(operands) == 2: - trace.rd = operands[0] - trace.rd_val = gpr[trace.rd] - trace.imm = get_imm_hex_val("0x" + operands[1]) - else: - fatal("process_jal(%s) wrong num operands (%d)" % - (trace.instr, len(operands))) + """ correctly process jal """ + # TODO need to merge with jalr + ## jal rd, imm + if len(operands) == 2: + trace.rd = operands[0] + trace.rd_val = gpr[trace.rd] + trace.imm = get_imm_hex_val("0x" + operands[1]) + else: + fatal("process_jal(%s) wrong num operands (%d)" % + (trace.instr, len(operands))) def process_jalr(trace, operands, gpr): """ process jalr """ @@ -134,64 +142,69 @@ pseudos={ } def check_conversion(entry): - """ after conversion check that the entry was converted correctly """ - instr_str_0 =entry.instr_str.split(" ")[0] - instr =entry.instr.split(" ")[0] - if "c." in instr[0:2]: - instr = instr[2:] - if instr in instr_str_0: - return # same - #logging.debug("converted pseudo %10s -> %s" % (instr_str_0, instr)) - if instr_str_0 in pseudos: - p_instr = pseudos[instr_str_0] - if p_instr in instr: - return # is pseudo, converted ok - logging.error( - "converted %10s -> %s <<-- not correct pseudo (%s)" % - (instr_str_0, instr, p_instr)) - if stop_on_first_error: - sys.exit(-1) - logging.error("converted %10s -> %s <<-- not correct at all" % - (instr_str_0, instr)) + """ after conversion check that the entry was converted correctly """ + instr_str_0 =entry.instr_str.split(" ")[0] + instr =entry.instr.split(" ")[0] + if "c." in instr[0:2]: + instr = instr[2:] + if instr in instr_str_0: + return # same + #logging.debug("converted pseudo %10s -> %s" % (instr_str_0, instr)) + if instr_str_0 in pseudos: + p_instr = pseudos[instr_str_0] + if p_instr in instr: + return # is pseudo, converted ok + logging.error( + "converted %10s -> %s <<-- not correct pseudo (%s)" % + (instr_str_0, instr, p_instr)) if stop_on_first_error: - sys.exit(-1) + sys.exit(RET_FATAL) + logging.error("converted %10s -> %s <<-- not correct at all" % + (instr_str_0, instr)) + if stop_on_first_error: + sys.exit(RET_FATAL) + +operands_list = ["rd","rs1","rs2","vd","vs1","vs2","vs3","fd","fs1","fs2"] + +def update_operands_values(trace, gpr): + """ ensure operands have been updated """ + for op in operands_list: + exec("if trace.%0s in gpr: trace.%0s_val = gpr[trace.%0s]" % (op, op, op)) def show_line_instr(line, i): - """ show line """ - if i.instr_str[0] in ['v']: - logging.debug("%s" % (line.strip())) - logging.debug( - " -->> instr_str(%s) binary(%s) addr(%s) mode(%s) instr(%s)" - % ( i.instr_str, i.binary, i.addr, i.privileged_mode, - i.instr)) + """ show line """ + if is_an_extension_instruction(i.instr): + logging.debug("%s" % (line.strip())) + logging.debug( + " -->> instr_str(%s) binary(%s) addr(%s) mode(%s) instr(%s)" + % ( i.instr_str, i.binary, i.addr, i.privileged_mode,i.instr)) def check_num_operands(instr_str, num_operands, n): - """ ensure consistency """ - if n != num_operands: - fatal("%s: num operands wrong, expected (%d) got (%d)" % (instr_str, - n, num_operands)) + """ ensure consistency """ + if n != num_operands: + fatal("%s: num operands wrong, expected (%d) got (%d)" % (instr_str, + n, num_operands)) 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"]: - return True - else: - return False + """ see if r is a csr """ + # TODO add more as needed - could look in the enum privileged_reg_t or the cores settings: implemented_csr[] + if r in ["mtvec","pmpaddr0","pmpcfg0","mstatus","mepc","mscratch","mcause", + "mtval","vl","vtype"]: + return True + else: + return False def process_branch_offset (opn, operands, prev_trace): - """ convert from ovpsim logs branch offsets as absolute to relative """ - addr = operands[opn] - pc = prev_trace.addr - offset_dec = int(addr, 16) - int(pc, 16) - offset = hex(offset_dec) - operands[opn] = offset + """ convert from ovpsim logs branch offsets as absolute to relative """ + addr = operands[opn] + pc = prev_trace.addr + offset_dec = int(addr, 16) - int(pc, 16) + offset = hex(offset_dec) + operands[opn] = offset def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0, - dont_truncate_after_first_ecall = 0, - verbose2 = False): + dont_truncate_after_first_ecall = 0, + verbose2 = False): """Process OVPsim simulation log. Extract instruction and affected register information from ovpsim simulation @@ -200,10 +213,12 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0, stop_on_first_error = stop - logging.info("Processing ovpsim log [%s %s %s]: %s" % - ("full_trace" if full_trace else "", "stop_on_first_error" if stop else "", - "dont_truncate_after_first_ecall" if dont_truncate_after_first_ecall else - "", ovpsim_log)) + logging.info("Processing ovpsim log : %s" % ovpsim_log) + + logging.debug("Flags [%s %s %s]" % + ("full_trace" if full_trace else "", + "stop_on_first_error" if stop else "", + "dont_truncate_after_first_ecall" if dont_truncate_after_first_ecall else "")) # Remove the header part of ovpsim log cmd = ("sed -i '/Info 1:/,$!d' %s" % ovpsim_log) @@ -217,14 +232,16 @@ 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 + for g in REGS: # base isa gprs gpr[g] = 0 - for i in range(32): # add in v0-v31 gprs gpr["v"+str(i)] = 0 + for f in FREGS: # floating point gprs + gpr[f] = 0 csr["vl"] = 0 csr["vtype"] = 0 @@ -238,22 +255,22 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0, for line in f: # Extract instruction infromation m = re.search(r"riscvOVPsim.*, 0x(?P.*?)(?P
\(.*\): ?)" \ - "(?P[A-Za-z]*?)\s+(?P[a-f0-9]*?)\s+(?P.*?)$", - line) + "(?P[A-Za-z]*?)\s+(?P[a-f0-9]*?)\s+(?P.*?)$", line) if m: # its instruction disassembly line if prev_trace: # write out the previous one when find next one - check_conversion(prev_trace) - instr_cnt += 1 - trace_csv.write_trace_entry(prev_trace) - if verbose2: - logging.debug("prev_trace:: "+str(prev_trace.__dict__)) - logging.debug("csr :: "+str(csr)) - logging.debug("gpr :: "+str(gpr)) - if logit: - # fatal ("stop for now") - pass - prev_trace = 0 + check_conversion(prev_trace) + update_operands_values(prev_trace, gpr) + instr_cnt += 1 + trace_csv.write_trace_entry(prev_trace) + if verbose2: + logging.debug("prev_trace:: "+str(prev_trace.__dict__)) + logging.debug("csr :: "+str(csr)) + logging.debug("gpr :: "+str(gpr)) + if logit: + # fatal ("stop for now") + pass + prev_trace = 0 prev_trace = RiscvInstructionTraceEntry() prev_trace.instr_str = m.group("instr_str") prev_trace.instr = prev_trace.instr_str.split(" ")[0] @@ -263,127 +280,119 @@ def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 1, stop = 0, prev_trace.privileged_mode = convert_mode(m.group("mode"), line) prev_trace.updated_csr = [] prev_trace.updated_gpr = [] - #if prev_trace.instr in ["vsetvli"]: #if prev_trace.instr in ["vlh.v"]: #if prev_trace.instr in ["vmul.vx"]: - if prev_trace.instr in ["vmul.vx_XXX"]: - logit = 1 - verbose2 = True + if prev_trace.instr in ["vsetvl"]: + logit = 1 + verbose2 = True show_line_instr(line, prev_trace) if full_trace: - # TODO - when got full ins decode remove this - if "fsriw" in line or \ - "fsw" in line or \ - "fsd" in line or \ - "fnmsub.d" in line or \ - "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) - if o: - operand_str = o.group("operand").replace(" ", "") - operands = operand_str.split(",") - if (prev_trace.instr in ['jalr', 'c.jalr']): - process_jalr(prev_trace, operands, gpr) - elif (prev_trace.instr in ['jal','c.jal']): - 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) - elif 'f' in prev_trace.instr[0] or "c.f" in prev_trace.instr[0:3]: - pass # ignore floating point. TODO include them - else: - if prev_trace.instr in [ - 'beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu']: - process_branch_offset (2, operands, prev_trace) - elif prev_trace.instr in [ - 'c.beqz', 'c.bnez', 'beqz', 'bnez', 'bgez', - 'bltz', 'blez', 'bgtz']: - process_branch_offset (1, operands, prev_trace) - if prev_trace.instr in ['j', 'c.j']: - operands[0] = "0x" + operands[0] - assign_operand(prev_trace, operands, gpr, stop_on_first_error) + # TODO - when got full ins decode remove this + if "fsw" in line or \ + "fnmsub.d" in line or \ + "fsd" in line: + # "fsriw" in line or \ + # "flw" in line or \ + logging.debug ("Ignoring ins...(%s) " % (line)) + continue + process_if_compressed(prev_trace) + o = re.search (r"(?P[a-z]*?)\s(?P.*)", + prev_trace.instr_str) + if o: + operand_str = o.group("operand").replace(" ", "") + operands = operand_str.split(",") + if (prev_trace.instr in ['jalr', 'c.jalr']): + process_jalr(prev_trace, operands, gpr) + elif (prev_trace.instr in ['jal','c.jal']): + process_jal(prev_trace, operands, gpr) else: - # logging.debug("no operand for [%s] in [%s]" % (trace_instr, - # trace_instr_str)) - pass + if is_an_extension_instruction(prev_trace.instr): + 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: + if prev_trace.instr in ['beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu']: + process_branch_offset (2, operands, prev_trace) + elif prev_trace.instr in [ + 'c.beqz', 'c.bnez', 'beqz', 'bnez', 'bgez', 'bltz', 'blez', 'bgtz']: + process_branch_offset (1, operands, prev_trace) + if prev_trace.instr in ['j', 'c.j']: + operands[0] = "0x" + operands[0] # ovpsim has no '0x' so need to add it. + assign_operand(prev_trace, operands, gpr, stop_on_first_error) + else: + # logging.debug("no operand for [%s] in [%s]" % (trace_instr, + # trace_instr_str)) + pass else: # its a csr, gpr new value or report - if 0: logging.debug ("reg change... [%s]" % (line.strip())) + if verbose2: + logging.debug ("reg change... [%s]" % (line.strip())) # Extract register change value information c = re.search(r" (?P[a-z]*[0-9]{0,2}?) (?P
[a-f0-9]+?)" \
                        " -> (?P[a-f0-9]+?)$", line)
         if c and is_csr (c.group("r")):
-            csr[c.group("r")] = c.group("val")
-            if verbose2: logging.debug("c:csr %0s = %0s" %
-                (c.group("r"), c.group("val")))
-            csr[c.group("r")] = c.group("val")
-            # prev_trace.updated_csr.append(c.group("r"))
-            prev_trace.updated_csr.append([c.group("r"), c.group("val")])
-            continue
+          csr[c.group("r")] = c.group("val")
+          if verbose2:
+            logging.debug("c:csr %0s = %0s" % (c.group("r"), c.group("val")))
+          csr[c.group("r")] = c.group("val")
+          # prev_trace.updated_csr.append(c.group("r"))
+          prev_trace.updated_csr.append([c.group("r"), c.group("val")])
+          continue
         n = re.search(r" (?P[a-z]{1,3}[0-9]{0,2}?) (?P
[a-f0-9]+?)" \
                        " -> (?P[a-f0-9]+?)$", line)
         if n: # gpr
-          if verbose2: logging.debug(("n:gpr %0s = %0s" %
-                (n.group("r"), n.group("val"))))
+          if verbose2:
+            logging.debug(("n:gpr %0s = %0s" % (n.group("r"), n.group("val"))))
           if n.group("r") != "frm":
-            # prev_trace.updated_gpr.append(n.group("r"))
             prev_trace.updated_gpr.append([n.group("r"), n.group("val")])
-            if 'v' in prev_trace.instr[0]:
-                gpr[n.group("r")] = n.group("val")
+            if is_an_extension_instruction(prev_trace.instr):
+              gpr[n.group("r")] = n.group("val")
             else:
-                # backwards compatible
-                prev_trace.rd       = n.group("r")
-                prev_trace.rd_val   = n.group("val")
-                gpr[prev_trace.rd]  = prev_trace.rd_val
+              # backwards compatible
+              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)"
+              print("write entry [[%d]]: rd[%s] val[%s] instr(%s) bin(%s) addr(%s)"
                     % (instr_cnt, rv_instr_trace.rd, rv_instr_trace.rd_val,
-                        trace_instr_str, prev_trace.binary, prev_trace.addr))
+                       trace_instr_str, prev_trace.binary, prev_trace.addr))
               print (rv_instr_trace.__dict__)
-              sys.exit(-1)
+              sys.exit(RET_FATAL)
         else:
-            line = line.strip()
-            if verbose2: logging.debug("ignoring line: [%s] %s " %
-                (str(instr_cnt), line))
-            line = re.sub(' +', ' ', line)
-            split = line.split(" ")
-            if len(split) == 1: continue
-            item = split[1]
-            if "----" in item: continue
-            if "REPORT" in line or item in [ # TODO sort csrs
-                    "mtvec","pmpaddr0","pmpcfg0","mstatus","mepc","mscratch",
-                        "mcause","mtval","vl","vtype","sstatus"]:
-                logging.debug("Ignoring: [%d]  [[%s]]" % (instr_cnt, line))
-                pass
-            elif "Warning (RISCV_" in line:
-                logging.debug("Skipping: [%d] (%s) [[%s]]" %
-                    (instr_cnt, prev_trace.instr_str, line))
-                prev_trace.instr = "nop"
-                prev_trace.instr_str = "nop"
-            else:
-                logging.debug(" (%s) in line: [%s] %s " %
-                        (item, str(instr_cnt), line))
-                if stop_on_first_error:
-                    fatal ("")
+          line = line.strip()
+          if verbose2: logging.debug("ignoring line: [%s] %s " %
+              (str(instr_cnt), line))
+          line = re.sub(' +', ' ', line)
+          split = line.split(" ")
+          if len(split) == 1: continue
+          item = split[1]
+          if "----" in item: continue
+          if "REPORT" in line or item in [ # TODO sort csrs
+            "mtvec","pmpaddr0","pmpcfg0","mstatus","mepc","mscratch",
+            "mcause","mtval","vl","vtype","sstatus"]:
+            logging.debug("Ignoring: [%d]  [[%s]]" % (instr_cnt, line))
+            pass
+          elif "Warning (RISCV_" in line:
+            logging.debug("Skipping: [%d] (%s) [[%s]]" %
+                          (instr_cnt, prev_trace.instr_str, line))
+            prev_trace.instr = "nop"
+            prev_trace.instr_str = "nop"
+          else:
+            logging.debug(" (%s) in line: [%s] %s " %
+                          (item, str(instr_cnt), line))
+            if stop_on_first_error:
+                fatal ("")
   logging.info("Processed instruction count : %d " % instr_cnt)
   if instr_cnt == 0:
     logging.error ("No Instructions in logfile: %s" % ovpsim_log)
-    sys.exit(-1)
+    sys.exit(RET_FATAL)
   logging.info("CSV saved to : %s" % csv)
 
-
 def main():
   """ if used standalone set up for testing """
-  instr_trace = []
   # Parse input arguments
   parser = argparse.ArgumentParser()
   parser.add_argument("--log", type=str, help="Input ovpsim simulation log")
diff --git a/vendor/google_riscv-dv/scripts/riscv_trace_csv.py b/vendor/google_riscv-dv/scripts/riscv_trace_csv.py
index 27036baf..699fefd5 100644
--- a/vendor/google_riscv-dv/scripts/riscv_trace_csv.py
+++ b/vendor/google_riscv-dv/scripts/riscv_trace_csv.py
@@ -20,6 +20,7 @@ import csv
 import re
 import logging
 import sys
+from lib import *
 
 class RiscvInstructionTraceEntry(object):
   """RISC-V instruction trace entry"""
@@ -46,12 +47,20 @@ class RiscvInstructionTraceEntry(object):
     self.vs2_val = ""
     self.vs3 = ""
     self.vs3_val = ""
-    self.vtype_e = ""
-    self.vtype_m = ""
-    self.vtype_d = ""
+    self.rs3 = ""
+    self.rs3_val = ""
+    self.vtype_vsew = ""
+    self.vtype_vmul = ""
+    self.vtype_vediv = ""
     self.vm = ""
     self.updated_csr = ""
     self.updated_gpr = ""
+    self.fd = ""
+    self.fd_val = ""
+    self.fs1 = ""
+    self.fs1_val = ""
+    self.fs2 = ""
+    self.fs2_val = ""
 
   def get_trace_string(self):
     """Return a short string of the trace entry"""
@@ -73,9 +82,10 @@ class RiscvInstructionTraceCsv(object):
     """Create a CSV file handle for a new trace"""
     fields = [
         "instr", "rd", "rd_val", "rs1", "rs1_val", "rs2", "rs2_val",
-        "imm", "str", "addr", "binary", "csr", "mode",
+        "rs3", "rs3_val", "imm", "str", "addr", "binary", "csr", "mode",
         "vd", "vd_val", "vs1", "vs1_val","vs2", "vs2_val","vs3", "vs3_val",
-        "vtype_e", "vtype_m", "vtype_d", "vm", "updated_csr", "updated_gpr"]
+        "vtype_vsew", "vtype_vmul", "vtype_vediv", "vm", "updated_csr", "updated_gpr",
+        "fd", "fd_val", "fs1", "fs1_val","fs2", "fs2_val"]
     self.csv_writer = csv.DictWriter(self.csv_fd, fieldnames=fields)
     self.csv_writer.writeheader()
 
@@ -96,33 +106,41 @@ class RiscvInstructionTraceCsv(object):
   def write_trace_entry(self, entry):
     """Write a new trace entry to CSV"""
     self.gpr[entry.rd] = entry.rd_val
-    self.csv_writer.writerow({'str'        : entry.instr_str,
-                              'rd'         : entry.rd,
-                              'rd_val'     : entry.rd_val,
-                              'rs1'        : entry.rs1,
-                              'rs1_val'    : entry.rs1_val,
-                              'rs2'        : entry.rs2,
-                              'rs2_val'    : entry.rs2_val,
-                              'addr'       : entry.addr,
-                              'instr'      : entry.instr,
-                              'imm'        : entry.imm,
-                              'csr'        : entry.csr,
-                              'binary'     : entry.binary,
-                              'mode'       : entry.privileged_mode,
-                              'vd'         : entry.vd,
-                              'vd_val'     : entry.vd_val,
-                              'vs1'        : entry.vs1,
-                              'vs1_val'    : entry.vs1_val,
-                              'vs2'        : entry.vs2,
-                              'vs2_val'    : entry.vs2_val,
-                              'vs3'        : entry.vs3,
-                              'vs3_val'    : entry.vs3_val,
-                              'vtype_e'    : entry.vtype_e,
-                              'vtype_m'    : entry.vtype_m,
-                              'vtype_d'    : entry.vtype_d,
-                              'vm'         : entry.vm,
-                              'updated_csr': entry.updated_csr,
-                              'updated_gpr': entry.updated_gpr,
+    self.csv_writer.writerow({'str'           : entry.instr_str,
+                              'rd'            : entry.rd,
+                              'rd_val'        : entry.rd_val,
+                              'rs1'           : entry.rs1,
+                              'rs1_val'       : entry.rs1_val,
+                              'rs2'           : entry.rs2,
+                              'rs2_val'       : entry.rs2_val,
+                              'rs3'           : entry.rs3,
+                              'rs3_val'       : entry.rs3_val,
+                              'addr'          : entry.addr,
+                              'instr'         : entry.instr,
+                              'imm'           : entry.imm,
+                              'csr'           : entry.csr,
+                              'binary'        : entry.binary,
+                              'mode'          : entry.privileged_mode,
+                              'vd'            : entry.vd,
+                              'vd_val'        : entry.vd_val,
+                              'vs1'           : entry.vs1,
+                              'vs1_val'       : entry.vs1_val,
+                              'vs2'           : entry.vs2,
+                              'vs2_val'       : entry.vs2_val,
+                              'vs3'           : entry.vs3,
+                              'vs3_val'       : entry.vs3_val,
+                              'vtype_vsew'    : entry.vtype_vsew,
+                              'vtype_vmul'    : entry.vtype_vmul,
+                              'vtype_vediv'   : entry.vtype_vediv,
+                              'vm'            : entry.vm,
+                              'updated_csr'   : entry.updated_csr,
+                              'updated_gpr'   : entry.updated_gpr,
+                              'fd'            : entry.fd,
+                              'fd_val'        : entry.fd_val,
+                              'fs1'           : entry.fs1,
+                              'fs1_val'       : entry.fs1_val,
+                              'fs2'           : entry.fs2,
+                              'fs2_val'       : entry.fs2_val,
                 })
 
 
@@ -493,4 +511,4 @@ def assign_operand(trace, operands, gpr, stop_on_first_error = 0):
     logging.debug("Unsupported instr : %s (%s)" %
                   (trace.instr, trace.instr_str))
     if stop_on_first_error:
-        sys.exit(-1)
+        sys.exit(RET_FATAL)
diff --git a/vendor/google_riscv-dv/scripts/sail_log_to_trace_csv.py b/vendor/google_riscv-dv/scripts/sail_log_to_trace_csv.py
index 91c5e4d2..ba82c672 100644
--- a/vendor/google_riscv-dv/scripts/sail_log_to_trace_csv.py
+++ b/vendor/google_riscv-dv/scripts/sail_log_to_trace_csv.py
@@ -40,7 +40,6 @@ def process_sail_sim_log(sail_log, csv):
   """
   logging.info("Processing sail log : %s" % sail_log)
   instr_cnt = 0
-  sail_instr = ""
 
   with open(sail_log, "r") as f, open(csv, "w") as csv_fd:
     search_start = 0
@@ -84,7 +83,6 @@ def process_sail_sim_log(sail_log, csv):
 
 
 def main():
-  instr_trace = []
   # Parse input arguments
   parser = argparse.ArgumentParser()
   parser.add_argument("--log", type=str, help="Input sail simulation log")
diff --git a/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py b/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py
index 25c47a54..eb2d38db 100644
--- a/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py
+++ b/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py
@@ -112,7 +112,6 @@ def process_spike_sim_log(spike_log, csv, full_trace = 0):
 
 
 def main():
-  instr_trace = []
   # Parse input arguments
   parser = argparse.ArgumentParser()
   parser.add_argument("--log", type=str, help="Input spike simulation log")
diff --git a/vendor/google_riscv-dv/scripts/whisper_log_trace_csv.py b/vendor/google_riscv-dv/scripts/whisper_log_trace_csv.py
index ae366e43..811635c1 100644
--- a/vendor/google_riscv-dv/scripts/whisper_log_trace_csv.py
+++ b/vendor/google_riscv-dv/scripts/whisper_log_trace_csv.py
@@ -72,7 +72,6 @@ def process_whisper_sim_log(whisper_log, csv, full_trace = 0):
 
 
 def main():
-  instr_trace = []
   # Parse input arguments
   parser = argparse.ArgumentParser()
   parser.add_argument("--log", type=str, help="Input whisper simulation log")
diff --git a/vendor/google_riscv-dv/src/deprecated/riscv_amo_instr_lib.sv b/vendor/google_riscv-dv/src/deprecated/riscv_amo_instr_lib.sv
new file mode 100644
index 00000000..ba60035f
--- /dev/null
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_amo_instr_lib.sv
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2019 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.
+ */
+
+// Base class for AMO instruction stream
+class riscv_amo_base_instr_stream extends riscv_mem_access_stream;
+
+  rand int unsigned  num_amo;
+  rand int unsigned  num_mixed_instr;
+  rand int           base;
+  rand riscv_reg_t   rs1_reg;
+  rand int unsigned  data_page_id;
+  rand int           max_load_store_offset;
+
+  // User can specify a small group of available registers to generate various hazard condition
+  rand riscv_reg_t   avail_regs[];
+
+  `uvm_object_utils(riscv_amo_base_instr_stream)
+
+  constraint rs1_c {
+    !(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
+  }
+
+  constraint addr_range_c {
+    data_page_id < max_data_page_id;
+    base inside {[0 : max_load_store_offset-1]};
+  }
+
+  constraint aligned_amo_c {
+    if (XLEN == 32) {
+      base % 4 == 0;
+    } else {
+      base % 8 == 0;
+    }
+  }
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  function void post_randomize();
+    gen_amo_instr();
+    // rs1 cannot be modified by other instructions
+    if(!(rs1_reg inside {reserved_rd})) begin
+      reserved_rd = {reserved_rd, rs1_reg};
+    end
+    add_mixed_instr(num_mixed_instr);
+    add_rs1_init_la_instr(rs1_reg, data_page_id);
+    super.post_randomize();
+  endfunction
+
+  // AMO instruction generation
+  virtual function void gen_amo_instr();
+  endfunction
+
+endclass
+
+// A pair of LR/SC instruction
+class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
+
+  riscv_rand_instr lr_instr;
+  riscv_rand_instr sc_instr;
+
+  constraint legal_c {
+    num_amo == 1;
+    num_mixed_instr inside {[0:15]};
+  }
+
+  `uvm_object_utils(riscv_lr_sc_instr_stream)
+
+  function new(string name = "");
+    super.new(name);
+    lr_instr = riscv_rand_instr::type_id::create("lr_instr");
+    sc_instr = riscv_rand_instr::type_id::create("sc_instr");
+  endfunction
+
+  virtual function void gen_amo_instr();
+    lr_instr.cfg = cfg;
+    sc_instr.cfg = cfg;
+    lr_instr.disable_a_extension_c.constraint_mode(0);
+    sc_instr.disable_a_extension_c.constraint_mode(0);
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(lr_instr,
+                                   rs1 == rs1_reg;
+                                   rd != rs1_reg;
+                                   instr_name inside {LR_W, LR_D};)
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(sc_instr,
+                                   rs1 == rs1_reg;
+                                   rd != rs1_reg;
+                                   instr_name inside {SC_W, SC_D};)
+    instr_list.push_front(lr_instr);
+    instr_list.push_front(sc_instr);
+  endfunction
+
+endclass
+
+class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
+
+  riscv_rand_instr amo_instr[];
+
+  constraint reasonable_c {
+    solve num_amo before num_mixed_instr;
+    num_amo inside {[1:10]};
+    num_mixed_instr inside {[0:2*num_amo]};
+  }
+
+  `uvm_object_utils(riscv_amo_instr_stream)
+  `uvm_object_new
+
+  virtual function void gen_amo_instr();
+    amo_instr = new[num_amo];
+    foreach (amo_instr[i]) begin
+      amo_instr[i] = riscv_rand_instr::type_id::create($sformatf("amo_instr_%0d", i));
+      amo_instr[i].cfg = cfg;
+      amo_instr[i].disable_a_extension_c.constraint_mode(0);
+      `ifdef DSIM
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
+                                       rs1 == rs1_reg;
+                                       rd != rs1_reg;
+                                       instr_name inside {[AMOSWAP_W:AMOMAXU_D]};)
+      `else
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
+                                       rs1 == rs1_reg;
+                                       rd != rs1_reg;
+                                       category == AMO;)
+      `endif
+      instr_list.push_front(amo_instr[i]);
+    end
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/deprecated/riscv_directed_instr_lib.sv b/vendor/google_riscv-dv/src/deprecated/riscv_directed_instr_lib.sv
new file mode 100644
index 00000000..30a5343e
--- /dev/null
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_directed_instr_lib.sv
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2018 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.
+ */
+
+// Base class for directed instruction stream
+class riscv_directed_instr_stream extends riscv_rand_instr_stream;
+
+  `uvm_object_utils(riscv_directed_instr_stream)
+
+  string label;
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  function void post_randomize();
+    foreach(instr_list[i]) begin
+      instr_list[i].has_label = 1'b0;
+      instr_list[i].atomic = 1'b1;
+    end
+    instr_list[0].comment = $sformatf("Start %0s", get_name());
+    instr_list[$].comment = $sformatf("End %0s", get_name());
+    if(label!= "") begin
+      instr_list[0].label = label;
+      instr_list[0].has_label = 1'b1;
+    end
+  endfunction
+
+endclass
+
+// Base class for memory access stream
+class riscv_mem_access_stream extends riscv_directed_instr_stream;
+
+  int             max_data_page_id;
+  mem_region_t    data_page[$];
+
+  `uvm_object_utils(riscv_mem_access_stream)
+  `uvm_object_new
+
+  function void pre_randomize();
+    if(kernel_mode) begin
+      data_page = cfg.s_mem_region;
+    end else begin
+      data_page = cfg.mem_region;
+    end
+    max_data_page_id = data_page.size();
+  endfunction
+
+  // Use "la" instruction to initialize the base regiseter
+  virtual function void add_rs1_init_la_instr(riscv_reg_t gpr, int id, int base = 0);
+    riscv_pseudo_instr la_instr;
+    la_instr = riscv_pseudo_instr::type_id::create("la_instr");
+    la_instr.pseudo_instr_name = LA;
+    la_instr.rd = gpr;
+    if(kernel_mode) begin
+      la_instr.imm_str = $sformatf("%s+%0d", cfg.s_mem_region[id].name, base);
+    end else begin
+      la_instr.imm_str = $sformatf("%s+%0d", cfg.mem_region[id].name, base);
+    end
+    instr_list.push_front(la_instr);
+  endfunction
+
+  // Insert some other instructions to mix with mem_access instruction
+  virtual function void add_mixed_instr(int instr_cnt);
+    riscv_instr_base instr;
+    setup_allowed_instr(1, 1);
+    for(int i = 0; i < instr_cnt; i ++) begin
+      instr = riscv_instr_base::type_id::create("instr");
+      randomize_instr(instr);
+      insert_instr(instr);
+    end
+  endfunction
+
+endclass
+
+// Jump instruction (JAL, JALR)
+// la rd0, jump_tagert_label
+// addi rd1, offset, rd0
+// jalr rd, offset, rd1
+// For JAL, restore the stack before doing the jump
+class riscv_jump_instr extends riscv_directed_instr_stream;
+
+  riscv_instr_base     jump;
+  riscv_instr_base     addi;
+  riscv_pseudo_instr   la;
+  riscv_instr_base     branch;
+  rand riscv_reg_t     gpr;
+  rand int             imm;
+  rand bit             enable_branch;
+  rand int             mixed_instr_cnt;
+  riscv_instr_base     stack_exit_instr[];
+  string               target_program_label;
+  int                  idx;
+  bit                  use_jalr;
+
+  constraint instr_c {
+    !(gpr inside {cfg.reserved_regs, ZERO});
+    imm inside {[-1023:1023]};
+    mixed_instr_cnt inside {[5:10]};
+  }
+
+  `uvm_object_utils(riscv_jump_instr)
+
+  function new(string name = "");
+    super.new(name);
+    jump = riscv_instr_base::type_id::create("jump");
+    la = riscv_pseudo_instr::type_id::create("la");
+    addi = riscv_instr_base::type_id::create("addi");
+    branch = riscv_instr_base::type_id::create("branch");
+  endfunction
+
+  function void post_randomize();
+    riscv_instr_base instr[];
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump,
+      (use_jalr) -> (instr_name == JALR);
+      instr_name dist {JAL := 2, JALR := 6, C_JALR := 2};
+      if (cfg.disable_compressed_instr || (cfg.ra != RA)) {
+        instr_name != C_JALR;
+      }
+      rd == cfg.ra;
+      rs1 == gpr;
+    )
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(addi,
+      rs1 == gpr;
+      instr_name == ADDI;
+      rd  == gpr;
+    )
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(branch,
+      instr_name inside {BEQ, BNE, BLT, BGE, BLTU, BGEU};)
+    la.pseudo_instr_name = LA;
+    la.imm_str = target_program_label;
+    la.rd = gpr;
+    // Generate some random instructions to mix with jump instructions
+    reserved_rd = {gpr};
+    initialize_instr_list(mixed_instr_cnt);
+    gen_instr(1'b1);
+    addi.imm_str = $sformatf("%0d", imm);
+    jump.imm_str = $sformatf("%0d", -imm);
+    // The branch instruction is always inserted right before the jump instruction to avoid
+    // skipping other required instructions like restore stack, load jump base etc.
+    // The purse of adding the branch instruction here is to cover branch -> jump scenario.
+    if(enable_branch) instr = {branch};
+    // Restore stack before unconditional jump
+    if(jump.rd == ZERO) begin
+      instr= {stack_exit_instr, instr};
+    end
+    if(jump.instr_name == JAL) begin
+      jump.imm_str = target_program_label;
+    end else if (jump.instr_name == C_JALR) begin
+      instr = {la, instr};
+    end else begin
+      instr = {la, addi, instr};
+    end
+    mix_instr_stream(instr);
+    instr_list = {instr_list, jump};
+    foreach(instr_list[i]) begin
+      instr_list[i].has_label = 1'b0;
+      instr_list[i].atomic = 1'b1;
+    end
+    jump.has_label = 1'b1;
+    jump.label = $sformatf("j_%0s_%0s_%0d", label, target_program_label, idx);
+    branch.imm_str = jump.label;
+    branch.comment = "branch to jump instr";
+    branch.branch_assigned = 1'b1;
+  endfunction
+endclass
+
+// Stress back to back jump instruction
+class riscv_jal_instr extends riscv_rand_instr_stream;
+
+  riscv_instr_base     jump[];
+  riscv_instr_base     jump_start;
+  riscv_instr_base     jump_end;
+  rand int unsigned    num_of_jump_instr;
+  riscv_instr_name_t   jal[$];
+
+  constraint instr_c {
+    num_of_jump_instr inside {[10:30]};
+  }
+
+  `uvm_object_utils(riscv_jal_instr)
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  function void post_randomize();
+    int order[];
+    order = new[num_of_jump_instr];
+    jump = new[num_of_jump_instr];
+    foreach (order[i]) begin
+      order[i] = i;
+    end
+    order.shuffle();
+    setup_allowed_instr(1, 1);
+    jal = {JAL};
+    if (!cfg.disable_compressed_instr) begin
+      jal.push_back(C_J);
+      if (XLEN == 32) begin
+        jal.push_back(C_JAL);
+      end
+    end
+    // First instruction
+    jump_start = riscv_instr_base::type_id::create("jump_start");
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump_start,
+      instr_name == JAL;
+      rd == cfg.ra;
+    )
+    jump_start.imm_str = $sformatf("%0df", order[0]);
+    jump_start.label = label;
+    // Last instruction
+    jump_end = riscv_instr_base::type_id::create("jump_end");
+    randomize_instr(jump_end);
+    jump_end.label = $sformatf("%0d", num_of_jump_instr);
+    foreach (jump[i]) begin
+      jump[i] = riscv_instr_base::type_id::create($sformatf("jump_%0d", i));
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(jump[i],
+        instr_name inside {jal};
+        rd dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
+        !(rd inside {cfg.reserved_regs});
+      )
+      jump[i].label = $sformatf("%0d", i);
+    end
+    foreach (order[i]) begin
+      if (i == num_of_jump_instr - 1) begin
+        jump[order[i]].imm_str = $sformatf("%0df", num_of_jump_instr);
+      end else begin
+        if (order[i+1] > order[i]) begin
+          jump[order[i]].imm_str = $sformatf("%0df", order[i+1]);
+        end else begin
+          jump[order[i]].imm_str = $sformatf("%0db", order[i+1]);
+        end
+      end
+    end
+    instr_list = {jump_start, jump, jump_end};
+    foreach (instr_list[i]) begin
+      instr_list[i].has_label = 1'b1;
+      instr_list[i].atomic = 1'b1;
+    end
+  endfunction
+endclass
+
+// Push stack instruction stream
+class riscv_push_stack_instr extends riscv_rand_instr_stream;
+
+  int                      stack_len;
+  int                      num_of_reg_to_save;
+  int                      num_of_redudant_instr;
+  riscv_instr_base         push_stack_instr[];
+  riscv_reg_t              saved_regs[];
+  rand riscv_rand_instr    branch_instr;
+  rand bit                 enable_branch;
+  string                   push_start_label;
+
+  `uvm_object_utils(riscv_push_stack_instr)
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  function void init();
+    // Save RA, T0
+    reserved_rd = {cfg.ra};
+    saved_regs = {cfg.ra};
+    num_of_reg_to_save = saved_regs.size();
+    if(num_of_reg_to_save * (XLEN/8) > stack_len) begin
+      `uvm_fatal(get_full_name(), $sformatf("stack len [%0d] is not enough to store %d regs",
+                 stack_len, num_of_reg_to_save))
+    end
+    num_of_redudant_instr = $urandom_range(3,10);
+    initialize_instr_list(num_of_redudant_instr);
+  endfunction
+
+  virtual function void gen_push_stack_instr(int stack_len, bit allow_branch = 1);
+    this.stack_len = stack_len;
+    init();
+    gen_instr(1'b1);
+    push_stack_instr = new[num_of_reg_to_save+1];
+    foreach(push_stack_instr[i]) begin
+      push_stack_instr[i] = riscv_instr_base::type_id::
+                             create($sformatf("push_stack_instr_%0d", i));
+    end
+    // addi sp,sp,-imm
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[0],
+                                   instr_name == ADDI; rd == cfg.sp; rs1 == cfg.sp;
+                                   imm == (~stack_len + 1);)
+    push_stack_instr[0].imm_str = $sformatf("-%0d", stack_len);
+    foreach(saved_regs[i]) begin
+      if(XLEN == 32) begin
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[i+1],
+          instr_name == SW; rs2 == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
+      end else begin
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[i+1],
+          instr_name == SD; rs2 == saved_regs[i]; rs1 == cfg.sp; imm == 8 * (i+1);)
+      end
+      push_stack_instr[i+1].process_load_store = 0;
+    end
+    if (allow_branch) begin
+      `DV_CHECK_STD_RANDOMIZE_FATAL(enable_branch)
+    end else begin
+      enable_branch = 0;
+    end
+    if(enable_branch) begin
+      // Cover jal -> branch scenario, the branch is added before push stack operation
+      branch_instr = riscv_rand_instr::type_id::create("branch_instr");
+      branch_instr.cfg = cfg;
+      `ifdef DSIM
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(branch_instr,
+                                       instr_name inside {[BEQ:BGEU], C_BEQZ, C_BNEZ};)
+      `else
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(branch_instr, category == BRANCH;)
+      `endif
+      branch_instr.imm_str = push_start_label;
+      branch_instr.branch_assigned = 1'b1;
+      push_stack_instr[0].label = push_start_label;
+      push_stack_instr[0].has_label = 1'b1;
+      push_stack_instr = {branch_instr, push_stack_instr};
+    end
+    mix_instr_stream(push_stack_instr);
+    foreach(instr_list[i]) begin
+      instr_list[i].atomic = 1'b1;
+      if(instr_list[i].label == "")
+        instr_list[i].has_label = 1'b0;
+    end
+  endfunction
+
+endclass
+
+// Pop stack instruction stream
+class riscv_pop_stack_instr extends riscv_rand_instr_stream;
+
+  int                      stack_len;
+  int                      num_of_reg_to_save;
+  int                      num_of_redudant_instr;
+  riscv_instr_base         pop_stack_instr[];
+  riscv_reg_t              saved_regs[];
+
+  `uvm_object_utils(riscv_pop_stack_instr)
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  function void init();
+    reserved_rd = {cfg.ra};
+    num_of_reg_to_save = saved_regs.size();
+    if(num_of_reg_to_save * 4 > stack_len) begin
+      `uvm_fatal(get_full_name(), $sformatf("stack len [%0d] is not enough to store %d regs",
+                 stack_len, num_of_reg_to_save))
+    end
+    num_of_redudant_instr = $urandom_range(3,10);
+    initialize_instr_list(num_of_redudant_instr);
+  endfunction
+
+  virtual function void gen_pop_stack_instr(int stack_len, riscv_reg_t saved_regs[]);
+    this.stack_len = stack_len;
+    this.saved_regs = saved_regs;
+    init();
+    gen_instr(1'b1);
+    pop_stack_instr = new[num_of_reg_to_save+1];
+    foreach(pop_stack_instr[i]) begin
+      pop_stack_instr[i] = riscv_instr_base::type_id::
+                             create($sformatf("pop_stack_instr_%0d", i));
+    end
+    foreach(saved_regs[i]) begin
+      if(XLEN == 32) begin
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[i],
+          instr_name == LW; rd == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
+      end else begin
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[i],
+          instr_name == LD; rd == saved_regs[i]; rs1 == cfg.sp; imm == 8 * (i+1);)
+      end
+      pop_stack_instr[i].process_load_store = 0;
+    end
+    // addi sp,sp,imm
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[num_of_reg_to_save],
+      instr_name == ADDI; rd == cfg.sp; rs1 == cfg.sp; imm == stack_len;)
+    pop_stack_instr[num_of_reg_to_save].imm_str = $sformatf("%0d", stack_len);
+    mix_instr_stream(pop_stack_instr);
+    foreach(instr_list[i]) begin
+      instr_list[i].atomic = 1'b1;
+      instr_list[i].has_label = 1'b0;
+    end
+  endfunction
+
+endclass
+
+// Cover the long fprward and backward jump
+class riscv_long_branch_instr extends riscv_rand_instr_stream;
+
+  int branch_instr_stream_len = 100;
+  int branch_instr_offset = 999;
+  riscv_rand_instr_stream forward_branch_instr_stream;
+  riscv_rand_instr_stream backward_branch_instr_stream;
+  riscv_instr_base        jump_instr;
+
+  `uvm_object_utils(riscv_long_branch_instr)
+
+  function new(string name = "");
+    super.new(name);
+    forward_branch_instr_stream = riscv_rand_instr_stream::type_id::
+                                  create("forward_branch_instr_stream");
+    backward_branch_instr_stream = riscv_rand_instr_stream::type_id::
+                                  create("backward_branch_instr_stream");
+    jump_instr = riscv_instr_base::type_id::create("jump_instr");
+  endfunction
+
+  function void init(int instr_len);
+    branch_instr_stream_len = instr_len;
+    initialize_instr_list(branch_instr_offset-branch_instr_stream_len);
+    forward_branch_instr_stream.cfg = cfg;
+    backward_branch_instr_stream.cfg = cfg;
+    forward_branch_instr_stream.initialize_instr_list(branch_instr_stream_len);
+    backward_branch_instr_stream.initialize_instr_list(branch_instr_stream_len);
+  endfunction
+
+  virtual function void gen_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1,
+                                  bit is_debug_program = 1'b0);
+    int branch_offset;
+    super.gen_instr(1'b1);
+    forward_branch_instr_stream.gen_instr();
+    backward_branch_instr_stream.gen_instr();
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump_instr, instr_name == JAL;)
+    jump_instr.imm_str = "test_done";
+    instr_list = {forward_branch_instr_stream.instr_list, instr_list,
+                  jump_instr, backward_branch_instr_stream.instr_list};
+    foreach(instr_list[i]) begin
+      instr_list[i].atomic = 1'b1;
+      if(!instr_list[i].is_branch_target) begin
+        instr_list[i].has_label = 1'b0;
+      end
+      if(instr_list[i].category == BRANCH) begin
+        if(i < branch_instr_stream_len)
+          branch_offset = branch_instr_offset;
+        else
+          branch_offset = -branch_instr_offset;
+        instr_list[i].imm_str = $sformatf("target_%0d", i);
+        instr_list[i].branch_assigned = 1'b1;
+        // Avoid dead loop
+        if(((instr_list[i+branch_offset].category == BRANCH) ||
+             instr_list[i+branch_offset].is_branch_target) && (branch_offset < 0))
+          branch_offset = branch_offset + 1;
+        `uvm_info(get_full_name(), $sformatf("Branch [%0d] %0s -> [%0d] %0s", i,
+                  instr_list[i].convert2asm(), i+branch_offset,
+                  instr_list[i+branch_offset].convert2asm()), UVM_LOW)
+        if(i < -branch_offset)
+          `uvm_fatal(get_name(), $sformatf("Unexpected branch instr at %0d", i))
+        instr_list[i+branch_offset].label = $sformatf("target_%0d", i);
+        instr_list[i+branch_offset].has_label = 1'b1;
+        instr_list[i+branch_offset].is_branch_target = 1;
+      end
+    end
+  endfunction
+
+endclass
+
+class riscv_sw_interrupt_instr extends riscv_directed_instr_stream;
+
+  rand bit usip;
+  rand bit ssip;
+  rand bit msip;
+  rand privileged_reg_t ip_reg;
+  rand riscv_pseudo_instr li_instr;
+  rand riscv_instr_base csr_instr;
+  riscv_privil_reg ip;
+  rand riscv_reg_t rs1_reg;
+
+  constraint ip_reg_c {
+    if(cfg.init_privileged_mode == MACHINE_MODE) {
+      ip_reg == MIP;
+    } else {
+      ip_reg == SIP;
+    }
+    (ip_reg == MIP) -> (usip || ssip || msip);
+    (ip_reg == SIP) -> (usip || ssip);
+  }
+
+  constraint instr_c {
+    !(rs1_reg inside {cfg.reserved_regs});
+    rs1_reg != ZERO;
+    li_instr.pseudo_instr_name == LI;
+    li_instr.rd == rs1_reg;
+    csr_instr.instr_name == CSRRW;
+    csr_instr.rs1 == rs1_reg;
+    // TODO: Support non-zero rd for SIP, MIP
+    // csr_instr.rd inside {cfg.avail_regs};
+    csr_instr.rd == ZERO;
+    csr_instr.csr == ip_reg;
+  }
+
+  `uvm_object_utils(riscv_sw_interrupt_instr)
+
+  function new(string name = "");
+    super.new(name);
+    li_instr = riscv_pseudo_instr::type_id::create("li_instr");
+    csr_instr = riscv_instr_base::type_id::create("csr_instr");
+    ip = riscv_privil_reg::type_id::create("ip");
+  endfunction
+
+  function void post_randomize();
+    // TODO: Support UIP
+    if(cfg.init_privileged_mode == USER_MODE) return;
+    ip.init_reg(ip_reg);
+    if(ip_reg == SIP) begin
+      ip.set_field("USIP", usip);
+      ip.set_field("SSIP", ssip);
+    end else begin
+      ip.set_field("USIP", usip);
+      ip.set_field("SSIP", ssip);
+      ip.set_field("MSIP", msip);
+    end
+    li_instr.imm_str = $sformatf("0x%0x", ip.get_val());
+    csr_instr.comment = ip_reg.name();
+    instr_list = {li_instr, csr_instr};
+    super.post_randomize();
+  endfunction
+
+endclass
+
diff --git a/vendor/google_riscv-dv/src/riscv_instr_base.sv b/vendor/google_riscv-dv/src/deprecated/riscv_instr_base.sv
similarity index 97%
rename from vendor/google_riscv-dv/src/riscv_instr_base.sv
rename to vendor/google_riscv-dv/src/deprecated/riscv_instr_base.sv
index de58abea..548758e6 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_base.sv
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_instr_base.sv
@@ -32,9 +32,9 @@ class riscv_instr_base extends uvm_object;
   rand bit [31:0]               imm;
   rand imm_t                    imm_type;
   rand bit [4:0]                imm_len;
-  rand bit                      is_pseudo_instr;
   rand bit                      aq;
   rand bit                      rl;
+  bit                           is_pseudo_instr;
   bit                           is_branch_target;
   bit                           has_label = 1'b1;
   bit                           atomic = 0;
@@ -58,11 +58,11 @@ class riscv_instr_base extends uvm_object;
   string                        label;
   bit                           is_local_numeric_label;
   int                           idx = -1;
+  `VECTOR_INCLUDE("riscv_instr_base_inc_riscv_instr_base_declares.sv")
 
   `uvm_object_utils(riscv_instr_base)
 
   constraint default_c {
-    soft is_pseudo_instr == 0;
     instr_name != INVALID_INSTR;
   }
 
@@ -369,6 +369,7 @@ class riscv_instr_base extends uvm_object;
   `add_instr(C_ADDI4SPN, CIW_FORMAT, ARITHMETIC, RV32C, NZUIMM)
   `add_instr(C_ADDI,     CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
   `add_instr(C_ADDI16SP, CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
+
   `add_instr(C_LI,       CI_FORMAT, ARITHMETIC, RV32C)
   `add_instr(C_LUI,      CI_FORMAT, ARITHMETIC, RV32C, NZUIMM)
   `add_instr(C_SUB,      CA_FORMAT, ARITHMETIC, RV32C)
@@ -449,6 +450,8 @@ class riscv_instr_base extends uvm_object;
   // Supervisor Instructions
   `add_instr(SFENCE_VMA, R_FORMAT,SYNCH,RV32I)
 
+  `VECTOR_INCLUDE("riscv_instr_base_inc_add_instr.sv")
+
   function void post_randomize();
     if (group inside {RV32C, RV64C, RV128C, RV32DC, RV32FC}) begin
       is_compressed = 1'b1;
@@ -519,6 +522,9 @@ class riscv_instr_base extends uvm_object;
         has_rs1 = 1'b1;
       end
     end
+
+    `VECTOR_INCLUDE("riscv_instr_base_inc_post_randomize.sv")
+
   endfunction
 
   function void mask_imm();
@@ -758,6 +764,7 @@ class riscv_instr_base extends uvm_object;
       end else begin
         asm_str = $sformatf("%0s %0s, %0s, (%0s)", asm_str, rd.name(), rs2.name(), rs1.name());
       end
+    `VECTOR_INCLUDE("riscv_instr_base_inc_convert2asm.sv")
     end else begin
       // For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
       // This is needed to resume execution from epc+4 after ebreak handling
@@ -1202,42 +1209,7 @@ class riscv_instr_base extends uvm_object;
     this.has_fs3           = obj.has_fs3;
     this.has_fd            = obj.has_fd;
     this.is_floating_point = obj.is_floating_point;
-  endfunction
-
-endclass
-
-// Psuedo instructions are used to simplify assembly program writing
-class riscv_pseudo_instr extends riscv_instr_base;
-
-  rand riscv_pseudo_instr_name_t  pseudo_instr_name;
-
-  constraint default_c {
-    is_pseudo_instr == 1'b1;
-  }
-
-  `add_pseudo_instr(LI,    I_FORMAT, LOAD, RV32I)
-  `add_pseudo_instr(LA,    I_FORMAT, LOAD, RV32I)
-
-  `uvm_object_utils(riscv_pseudo_instr)
-
-  function new(string name = "");
-    super.new(name);
-    process_load_store = 0;
-  endfunction
-
-  // Convert the instruction to assembly code
-  virtual function string convert2asm(string prefix = "");
-    string asm_str;
-    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
-    // instr rd,imm
-    asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
-    if(comment != "")
-      asm_str = {asm_str, " #",comment};
-    return asm_str.tolower();
-  endfunction
-
-  virtual function string get_instr_name();
-    return pseudo_instr_name.name();
-  endfunction
+    `VECTOR_INCLUDE("riscv_instr_base_inc_copy_base_instr.sv")
+   endfunction
 
 endclass
diff --git a/vendor/google_riscv-dv/src/deprecated/riscv_instr_gen_config.sv b/vendor/google_riscv-dv/src/deprecated/riscv_instr_gen_config.sv
new file mode 100644
index 00000000..d6ccb46e
--- /dev/null
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_instr_gen_config.sv
@@ -0,0 +1,700 @@
+/*
+ * Copyright 2018 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.
+ */
+
+//-----------------------------------------------------------------------------
+// RISC-V assembly program generator configuration class
+//-----------------------------------------------------------------------------
+
+class riscv_instr_gen_config extends uvm_object;
+
+  //-----------------------------------------------------------------------------
+  // Random instruction generation settings
+  //-----------------------------------------------------------------------------
+
+  // Instruction count of the main program
+  rand int               main_program_instr_cnt;
+
+  // Instruction count of each sub-program
+  rand int               sub_program_instr_cnt[];
+
+  // Instruction count of the debug rom
+  rand int               debug_program_instr_cnt;
+
+  // Instruction count of debug sub-programs
+  rand int               debug_sub_program_instr_cnt[];
+
+  // Pattern of data section: RAND_DATA, ALL_ZERO, INCR_VAL
+  rand data_pattern_t    data_page_pattern;
+
+  // Associate array for delegation configuration for each exception and interrupt
+  // When the bit is 1, the corresponding delegation is enabled.
+  rand bit               m_mode_exception_delegation[exception_cause_t];
+  rand bit               s_mode_exception_delegation[exception_cause_t];
+  rand bit               m_mode_interrupt_delegation[interrupt_cause_t];
+  rand bit               s_mode_interrupt_delegation[interrupt_cause_t];
+
+  // Priviledged mode after boot
+  rand privileged_mode_t init_privileged_mode;
+
+  rand bit[XLEN-1:0]     mstatus, mie,
+                         sstatus, sie,
+                         ustatus, uie;
+
+  // Key fields in xSTATUS
+  // Memory protection bits
+  rand bit               mstatus_mprv;
+  rand bit               mstatus_mxr;
+  rand bit               mstatus_sum;
+  rand bit               mstatus_tvm;
+  rand bit [1:0]         mstatus_fs;
+  rand mtvec_mode_t      mtvec_mode;
+
+  // Floating point rounding mode
+  rand f_rounding_mode_t fcsr_rm;
+
+  // Enable sfence.vma instruction
+  rand bit               enable_sfence;
+
+  // Reserved register
+  // Reserved for various hardcoded routines
+  rand riscv_reg_t       gpr[4];
+  // Used by any DCSR operations inside of the debug rom
+  rand riscv_reg_t       scratch_reg;
+  // Use a random register for stack pointer/thread pointer
+  rand riscv_reg_t       sp;
+  rand riscv_reg_t       tp;
+  rand riscv_reg_t       ra;
+
+  // Options for privileged mode CSR checking
+  // Below checking can be made optional as the ISS implementation could be different with the
+  // processor.
+  bit                    check_misa_init_val = 1'b0;
+  bit                    check_xstatus = 1'b1;
+
+  // Virtual address translation is on for this test
+  rand bit               virtual_addr_translation_on;
+
+  //-----------------------------------------------------------------------------
+  //  User space memory region and stack setting
+  //-----------------------------------------------------------------------------
+
+  mem_region_t mem_region[$] = '{
+    '{name:"region_0", size_in_bytes: 4096,      xwr: 3'b111},
+    '{name:"region_1", size_in_bytes: 4096 * 4,  xwr: 3'b111},
+    '{name:"region_2", size_in_bytes: 4096 * 2,  xwr: 3'b111},
+    '{name:"region_3", size_in_bytes: 512,       xwr: 3'b111},
+    '{name:"region_4", size_in_bytes: 4096,      xwr: 3'b111}
+  };
+
+  // Stack section word length
+  int stack_len = 5000;
+
+  //-----------------------------------------------------------------------------
+  // Kernel section setting, used by supervisor mode programs
+  //-----------------------------------------------------------------------------
+
+  mem_region_t s_mem_region[$] = '{
+    '{name:"s_region_0", size_in_bytes: 4096, xwr: 3'b111},
+    '{name:"s_region_1", size_in_bytes: 4096, xwr: 3'b111}};
+
+  // Kernel Stack section word length
+  int kernel_stack_len = 4000;
+
+  // Number of instructions for each kernel program
+  int kernel_program_instr_cnt = 400;
+
+  //-----------------------------------------------------------------------------
+  // Instruction list based on the config, generate by build_instruction_template
+  //-----------------------------------------------------------------------------
+  riscv_instr_base       instr_template[riscv_instr_name_t];
+  riscv_instr_name_t     basic_instr[$];
+  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
+  //-----------------------------------------------------------------------------
+  // Main options for RISC-V assembly program generation
+  // Number of sub-programs per test
+  int                    num_of_sub_program = 5;
+  int                    instr_cnt = 200;
+  int                    num_of_tests = 1;
+  // For tests doesn't involve load/store, the data section generation could be skipped
+  bit                    no_data_page;
+  // Options to turn off some specific types of instructions
+  bit                    no_branch_jump;     // No branch/jump instruction
+  bit                    no_load_store;      // No load/store instruction
+  bit                    no_csr_instr;       // No csr instruction
+  bit                    no_ebreak = 1;      // No ebreak instruction
+  bit                    no_dret = 1;        // No dret instruction
+  bit                    no_fence;           // No fence instruction
+  bit                    no_wfi = 1;         // No WFI instruction
+  bit                    enable_unaligned_load_store;
+  int                    illegal_instr_ratio;
+  int                    hint_instr_ratio;
+  // Directed boot privileged mode, u, m, s
+  string                 boot_mode_opts;
+  int                    enable_page_table_exception;
+  bit                    no_directed_instr;
+  // A name suffix for the generated assembly program
+  string                 asm_test_suffix;
+  // Enable interrupt bit in MSTATUS (MIE, SIE, UIE)
+  bit                    enable_interrupt;
+  // We need a separate control knob for enabling timer interrupts, as Spike
+  // throws an exception if xIE.xTIE is enabled
+  bit                    enable_timer_irq;
+  // Generate a bare program without any init/exit/error handling/page table routines
+  // The generated program can be integrated with a larger program.
+  // Note that the bare mode program is not expected to run in standalone mode
+  bit                    bare_program_mode;
+  // Enable accessing illegal CSR instruction
+  // - 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;
+  // Interrupt/Exception Delegation
+  bit                    no_delegation = 1;
+  bit                    force_m_delegation = 0;
+  bit                    force_s_delegation = 0;
+  bit                    support_supervisor_mode;
+  bit                    disable_compressed_instr;
+  // "Memory mapped" address that when written to will indicate some event to
+  // the testbench - testbench will take action based on the value written
+  int                    signature_addr = 32'hdead_beef;
+  bit                    require_signature_addr = 1'b0;
+  // Enable a full or empty debug_rom section.
+  // Full debug_rom will contain random instruction streams.
+  // Empty debug_rom will contain just dret instruction and will return immediately.
+  // Will be empty by default.
+  bit                    gen_debug_section = 1'b0;
+  // Enable generation of a directed sequence of instructions containing
+  // ebreak inside the debug_rom.
+  // Disabled by default.
+  bit                    enable_ebreak_in_debug_rom = 1'b0;
+  // Enable setting dcsr.ebreak(m/s/u)
+  bit                    set_dcsr_ebreak = 1'b0;
+  // Number of sub programs in the debug rom
+  int                    num_debug_sub_program = 0;
+  // Enable debug single stepping
+  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);
+  int                    max_stack_len_per_program = 16 * (XLEN/8);
+  // Maximum branch distance, avoid skipping large portion of the code
+  int                    max_branch_step = 20;
+  // Maximum directed instruction stream sequence count
+  int                    max_directed_instr_stream_seq = 20;
+  // Reserved registers
+  riscv_reg_t            reserved_regs[];
+  // Floating point support
+  bit                    enable_floating_point;
+
+  //-----------------------------------------------------------------------------
+  // Command line options for instruction distribution control
+  //-----------------------------------------------------------------------------
+  int                    dist_control_mode;
+  int unsigned           category_dist[riscv_instr_category_t];
+
+  uvm_cmdline_processor  inst;
+
+  constraint default_c {
+    sub_program_instr_cnt.size() == num_of_sub_program;
+    debug_sub_program_instr_cnt.size() == num_debug_sub_program;
+    main_program_instr_cnt inside {[10 : instr_cnt]};
+    foreach(sub_program_instr_cnt[i]) {
+      sub_program_instr_cnt[i] inside {[10 : instr_cnt]};
+    }
+    // Disable sfence if the program is not boot to supervisor mode
+    // If sfence exception is allowed, we can enable sfence instruction in any priviledged mode.
+    // When MSTATUS.TVM is set, executing sfence.vma will be treate as illegal instruction
+    if(allow_sfence_exception) {
+      enable_sfence == 1'b1;
+      (init_privileged_mode != SUPERVISOR_MODE) || (mstatus_tvm == 1'b1);
+    } else {
+      (init_privileged_mode != SUPERVISOR_MODE || !riscv_instr_pkg::support_sfence || mstatus_tvm || no_fence)
+                                                     -> (enable_sfence == 1'b0);
+    }
+  }
+
+  constraint debug_mode_c {
+      if (riscv_instr_pkg::support_debug_mode) {
+        debug_program_instr_cnt inside {[100 : 300]};
+        foreach(debug_sub_program_instr_cnt[i]) {
+          debug_sub_program_instr_cnt[i] inside {[100 : 300]};
+        }
+      }
+    `ifndef DSIM
+       main_program_instr_cnt + sub_program_instr_cnt.sum() == instr_cnt;
+    `else
+       // dsim has some issue supporting sum(), use some approximate constraint to generate
+       // instruction cnt
+       if (num_of_sub_program > 0) {
+         main_program_instr_cnt inside {[10:instr_cnt/2]};
+         foreach (sub_program_instr_cnt[i]) {
+           sub_program_instr_cnt[i] inside {[10:instr_cnt/num_of_sub_program]};
+         }
+       } else {
+         main_program_instr_cnt == instr_cnt;
+       }
+    `endif
+  }
+
+  // Keep the number of single step iterations relatively small
+  constraint debug_single_step_c {
+    if (enable_debug_single_step) {
+      single_step_iterations inside {[10 : 50]};
+    }
+  }
+
+  // Boot privileged mode distribution
+  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] := 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] := 3};
+    } else {
+      init_privileged_mode == riscv_instr_pkg::supported_privileged_mode[0];
+    }
+  }
+
+  constraint mtvec_c {
+    mtvec_mode inside {supported_interrupt_mode};
+  }
+
+  constraint mstatus_c {
+    // This is default disabled at setup phase. It can be enabled in the exception and interrupt
+    // handling routine
+    mstatus_mprv == 1'b0;
+  }
+
+  // Exception delegation setting
+  constraint exception_delegation_c {
+    // Do not delegate instructino page fault to supervisor/user mode because this may introduce
+    // dead loop. All the subsequent instruction fetches may fail and program cannot recover.
+    m_mode_exception_delegation[INSTRUCTION_PAGE_FAULT] == 1'b0;
+    if(force_m_delegation) {
+      foreach(m_mode_exception_delegation[i]) {
+        soft m_mode_exception_delegation[i] == 1'b1;
+      }
+      foreach(m_mode_interrupt_delegation[i]) {
+        soft m_mode_interrupt_delegation[i] == 1'b1;
+      }
+    }
+    if(force_s_delegation) {
+      foreach(s_mode_exception_delegation[i]) {
+        soft s_mode_exception_delegation[i] == 1'b1;
+      }
+      foreach(s_mode_interrupt_delegation[i]) {
+        soft s_mode_interrupt_delegation[i] == 1'b1;
+      }
+    }
+  }
+
+  // Spike only supports a subset of exception and interrupt delegation
+  // You can modify this constraint if your ISS support different set of delegations
+  constraint delegation_c {
+    foreach(m_mode_exception_delegation[i]) {
+      if(!support_supervisor_mode || no_delegation) {
+        m_mode_exception_delegation[i] == 0;
+      }
+      if(!(i inside {INSTRUCTION_ADDRESS_MISALIGNED, BREAKPOINT, ECALL_UMODE,
+                     INSTRUCTION_PAGE_FAULT, LOAD_PAGE_FAULT, STORE_AMO_PAGE_FAULT})) {
+        m_mode_exception_delegation[i] == 0;
+      }
+    }
+    foreach(m_mode_interrupt_delegation[i]) {
+      if(!support_supervisor_mode || no_delegation) {
+        m_mode_interrupt_delegation[i] == 0;
+      }
+      if(!(i inside {S_SOFTWARE_INTR, S_TIMER_INTR, S_EXTERNAL_INTR})) {
+        m_mode_interrupt_delegation[i] == 0;
+      }
+    }
+  }
+
+  constraint ra_c {
+    ra dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
+    ra != sp;
+    ra != tp;
+    ra != ZERO;
+  }
+
+  constraint sp_tp_c {
+    sp != tp;
+    sp dist {SP := 6, RA := 1, [GP:T6] :/ 3};
+    !(sp inside {GP, RA, ZERO});
+    !(tp inside {GP, RA, ZERO});
+  }
+
+  constraint reserve_scratch_reg_c {
+    scratch_reg != ZERO;
+    scratch_reg != sp;
+    scratch_reg != tp;
+  }
+
+  constraint gpr_c {
+    foreach (gpr[i]) {
+      !(gpr[i] inside {sp, tp, scratch_reg, ZERO, RA, GP});
+    }
+    unique {gpr};
+  }
+
+  constraint addr_translaction_c {
+    solve init_privileged_mode before virtual_addr_translation_on;
+    if ((init_privileged_mode != MACHINE_MODE) && (SATP_MODE != BARE)) {
+      virtual_addr_translation_on == 1'b1;
+    } else {
+      virtual_addr_translation_on == 1'b0;
+    }
+  }
+
+  constraint floating_point_c {
+    if (enable_floating_point) {
+      mstatus_fs == 2'b01;
+    } else {
+      mstatus_fs == 2'b00;
+    }
+  }
+
+  `uvm_object_utils_begin(riscv_instr_gen_config)
+    `uvm_field_int(main_program_instr_cnt, UVM_DEFAULT)
+    `uvm_field_sarray_int(sub_program_instr_cnt, UVM_DEFAULT)
+    `uvm_field_int(debug_program_instr_cnt, UVM_DEFAULT)
+    `uvm_field_enum(data_pattern_t, data_page_pattern, UVM_DEFAULT)
+    `uvm_field_enum(privileged_mode_t, init_privileged_mode, UVM_DEFAULT)
+    `uvm_field_array_enum(riscv_reg_t, reserved_regs, UVM_DEFAULT)
+  `uvm_object_utils_end
+
+  function new (string name = "");
+    string s;
+    super.new(name);
+    init_delegation();
+    inst = uvm_cmdline_processor::get_inst();
+    get_int_arg_value("+num_of_tests=", num_of_tests);
+    get_int_arg_value("+enable_page_table_exception=", enable_page_table_exception);
+    get_bool_arg_value("+enable_interrupt=", enable_interrupt);
+    get_bool_arg_value("+enable_timer_irq=", enable_timer_irq);
+    get_int_arg_value("+num_of_sub_program=", num_of_sub_program);
+    get_int_arg_value("+instr_cnt=", instr_cnt);
+    get_bool_arg_value("+no_ebreak=", no_ebreak);
+    get_bool_arg_value("+no_dret=", no_dret);
+    get_bool_arg_value("+no_wfi=", no_wfi);
+    get_bool_arg_value("+no_branch_jump=", no_branch_jump);
+    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);
+    get_bool_arg_value("+no_fence=", no_fence);
+    get_bool_arg_value("+no_delegation=", no_delegation);
+    get_int_arg_value("+illegal_instr_ratio=", illegal_instr_ratio);
+    get_int_arg_value("+hint_instr_ratio=", hint_instr_ratio);
+    get_bool_arg_value("+enable_unaligned_load_store=", enable_unaligned_load_store);
+    get_bool_arg_value("+force_m_delegation=", force_m_delegation);
+    get_bool_arg_value("+force_s_delegation=", force_s_delegation);
+    get_bool_arg_value("+require_signature_addr=", require_signature_addr);
+    get_bool_arg_value("+disable_compressed_instr=", disable_compressed_instr);
+    get_bool_arg_value("+randomize_csr=", randomize_csr);
+    if (this.require_signature_addr) begin
+      get_hex_arg_value("+signature_addr=", signature_addr);
+    end
+    get_bool_arg_value("+gen_debug_section=", gen_debug_section);
+    get_bool_arg_value("+bare_program_mode=", bare_program_mode);
+    get_int_arg_value("+num_debug_sub_program=", num_debug_sub_program);
+    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(
+                "Got boot mode option - %0s", boot_mode_opts), UVM_LOW)
+      case(boot_mode_opts)
+        "m" : init_privileged_mode = MACHINE_MODE;
+        "s" : init_privileged_mode = SUPERVISOR_MODE;
+        "u" : init_privileged_mode = USER_MODE;
+        default: `uvm_fatal(get_full_name(),
+                  $sformatf("Illegal boot mode option - %0s", boot_mode_opts))
+      endcase
+      init_privileged_mode.rand_mode(0);
+    end
+    `uvm_info(`gfn, $sformatf("riscv_instr_pkg::supported_privileged_mode = %0d",
+                   riscv_instr_pkg::supported_privileged_mode.size()), UVM_LOW)
+    void'(inst.get_arg_value("+asm_test_suffix=", asm_test_suffix));
+    // Directed march list from the runtime options, ex. RV32I, RV32M etc.
+    void'(inst.get_arg_value("+march=", s));
+    if(s != "") begin
+      string cmdline_march_list[$];
+      riscv_instr_group_t march;
+      uvm_split_string(s, ",", cmdline_march_list);
+      riscv_instr_pkg::supported_isa.delete();
+      foreach(cmdline_march_list[i]) begin
+        if(uvm_enum_wrapper#(riscv_instr_group_t)::from_name(
+           cmdline_march_list[i].toupper(), march)) begin
+          riscv_instr_pkg::supported_isa.push_back(march);
+        end else begin
+          `uvm_fatal(get_full_name(), $sformatf(
+                     "Invalid march %0s specified in command line", cmdline_march_list[i]))
+        end
+      end
+    end
+    if (!(RV32C inside {supported_isa})) begin
+      disable_compressed_instr = 1;
+    end
+    setup_instr_distribution();
+    get_invalid_priv_lvl_csr();
+  endfunction
+
+  function void setup_instr_distribution();
+    string opts;
+    int val;
+    get_int_arg_value("+dist_control_mode=", dist_control_mode);
+    if (dist_control_mode == 1) begin
+      riscv_instr_category_t category;
+      category = category.first;
+      do begin
+        opts = {$sformatf("dist_%0s=", category.name()), "%d"};
+        opts = opts.tolower();
+        if ($value$plusargs(opts, val)) begin
+          category_dist[category] = val;
+        end else begin
+          category_dist[category] = 10; // Default ratio
+        end
+        `uvm_info(`gfn, $sformatf("Set dist[%0s] = %0d",
+                        category.name(), category_dist[category]), UVM_LOW)
+        category = category.next;
+      end
+      while(category != category.first);
+    end
+  endfunction
+
+  // Initialize the exception/interrupt delegation associate array, set all delegation default to 0
+  virtual function void init_delegation();
+    exception_cause_t cause;
+    interrupt_cause_t intr_cause;
+    cause = cause.first;
+    // Init exception delegation array
+    do begin
+      m_mode_exception_delegation[cause] = 1'b0;
+      s_mode_exception_delegation[cause] = 1'b0;
+      cause = cause.next;
+    end
+    while(cause != cause.first);
+    // Init interrupt delegation array
+    intr_cause = intr_cause.first;
+    do begin
+      m_mode_interrupt_delegation[intr_cause] = 1'b0;
+      s_mode_interrupt_delegation[intr_cause] = 1'b0;
+      intr_cause = intr_cause.next;
+    end
+    while(intr_cause != intr_cause.first);
+  endfunction
+
+  function void pre_randomize();
+    foreach (riscv_instr_pkg::supported_privileged_mode[i]) begin
+      if(riscv_instr_pkg::supported_privileged_mode[i] == SUPERVISOR_MODE)
+        support_supervisor_mode = 1;
+    end
+  endfunction
+
+  function void get_non_reserved_gpr();
+  endfunction
+
+  function void post_randomize();
+    // Setup the list all reserved registers
+    reserved_regs = {tp, sp, scratch_reg};
+    // Need to save all loop registers, and RA/T0
+    min_stack_len_per_program = 2 * (XLEN/8);
+    // Check if the setting is legal
+    check_setting();
+    // WFI is not supported in umode
+    if (init_privileged_mode == USER_MODE) begin
+      no_wfi = 1'b1;
+    end
+  endfunction
+
+  function void check_setting();
+    bit support_64b;
+    bit support_128b;
+    foreach (riscv_instr_pkg::supported_isa[i]) begin
+      if (riscv_instr_pkg::supported_isa[i] inside {RV64I, RV64M, RV64A, RV64F, RV64D, RV64C}) begin
+        support_64b = 1'b1;
+      end else if (riscv_instr_pkg::supported_isa[i] inside {RV128I, RV128C}) begin
+        support_128b = 1'b1;
+      end
+    end
+    if (support_128b && XLEN != 128) begin
+      `uvm_fatal(`gfn, "XLEN should be set to 128 based on riscv_instr_pkg::supported_isa setting")
+    end
+    if (!support_128b && support_64b && XLEN != 64) begin
+      `uvm_fatal(`gfn, "XLEN should be set to 64 based on riscv_instr_pkg::supported_isa setting")
+    end
+    if (!(support_128b || support_64b) && XLEN != 32) begin
+      `uvm_fatal(`gfn, "XLEN should be set to 32 based on riscv_instr_pkg::supported_isa setting")
+    end
+    if (!(support_128b || support_64b) && !(SATP_MODE inside {SV32, BARE})) begin
+      `uvm_fatal(`gfn, $sformatf("SATP mode %0s is not supported for RV32G ISA", SATP_MODE.name()))
+    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_name;
+    privileged_reg_t 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
+      privileged_reg_t csr = implemented_csr[i];
+      csr_name = csr.name();
+      if (csr_name[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;
+    if(inst.get_arg_value(cmdline_str, s)) begin
+      val = s.atoi();
+    end
+  endfunction
+
+  // Get a bool argument from comand line
+  function void get_bool_arg_value(string cmdline_str, ref bit val);
+    string s;
+    if(inst.get_arg_value(cmdline_str, s)) begin
+      val = s.atobin();
+    end
+  endfunction
+
+  // Get a hex argument from command line
+  function void get_hex_arg_value(string cmdline_str, ref int val);
+    string s;
+    if(inst.get_arg_value(cmdline_str, s)) begin
+      val = s.atohex();
+    end
+  endfunction
+
+  // Build instruction template
+  virtual function void build_instruction_template(bit skip_instr_exclusion = 0);
+    riscv_instr_name_t instr_name;
+    riscv_instr_name_t excluded_instr[$];
+    excluded_instr = {INVALID_INSTR};
+    if (!skip_instr_exclusion) begin
+      get_excluded_instr(excluded_instr);
+    end
+    instr_name = instr_name.first;
+    do begin
+      riscv_instr_base instr;
+      if (!(instr_name inside {unsupported_instr, excluded_instr})) begin
+        instr = riscv_instr_base::type_id::create("instr");
+        `DV_CHECK_RANDOMIZE_WITH_FATAL(instr, instr_name == local::instr_name;)
+        if ((instr.group inside {supported_isa}) &&
+            !(disable_compressed_instr && instr.is_compressed) &&
+            !(!enable_floating_point && (instr.group inside {RV32F, RV64F, RV32D, RV64D}))) begin
+          `uvm_info(`gfn, $sformatf("Adding [%s] %s to the list",
+                          instr.group.name(), instr.instr_name.name()), UVM_HIGH)
+          instr_group[instr.group].push_back(instr_name);
+          instr_category[instr.category].push_back(instr_name);
+          instr_template[instr_name] = instr;
+        end
+      end
+      instr_name = instr_name.next;
+    end
+    while (instr_name != instr_name.first);
+  endfunction
+
+  virtual function void build_instruction_list();
+    basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
+                   instr_category[LOGICAL], instr_category[COMPARE]};
+    basic_instr = {basic_instr, EBREAK};
+    foreach(riscv_instr_pkg::supported_isa[i]) begin
+      if (riscv_instr_pkg::supported_isa[i] inside {RV32C, RV64C, RV128C, RV32DC, RV32FC}) begin
+        basic_instr = {basic_instr, C_EBREAK};
+        break;
+      end
+    end
+    if (no_dret == 0) begin
+      basic_instr = {basic_instr, DRET};
+    end
+    if (no_fence == 0) begin
+      basic_instr = {basic_instr, instr_category[SYNCH]};
+    end
+    // TODO: Support CSR instruction in other mode
+    if ((no_csr_instr == 0) && (init_privileged_mode == MACHINE_MODE)) begin
+      `uvm_info(`gfn, $sformatf("Adding CSR instr, mode: %0s", init_privileged_mode.name()), UVM_LOW)
+      basic_instr = {basic_instr, instr_category[CSR]};
+    end
+    if (no_wfi == 0) begin
+      basic_instr = {basic_instr, WFI};
+    end
+  endfunction
+
+  virtual function void get_excluded_instr(ref riscv_instr_name_t excluded[$]);
+    // Below instrutions will modify stack pointer, not allowed in normal instruction stream.
+    // It can be used in stack operation instruction stream.
+    excluded = {excluded, C_SWSP, C_SDSP, C_ADDI16SP};
+    if (!enable_sfence) begin
+      excluded = {excluded, SFENCE_VMA};
+    end
+    if (no_fence) begin
+      excluded = {excluded, FENCE, FENCE_I, SFENCE_VMA};
+    end
+    // TODO: Support C_ADDI4SPN
+    excluded = {excluded, C_ADDI4SPN};
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/deprecated/riscv_instr_stream.sv b/vendor/google_riscv-dv/src/deprecated/riscv_instr_stream.sv
new file mode 100644
index 00000000..b4defc86
--- /dev/null
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_instr_stream.sv
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2018 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.
+ */
+
+// Base class for RISC-V instruction stream
+// A instruction stream here is a  queue of RISC-V basic instructions.
+// This class also provides some functions to manipulate the instruction stream, like insert a new
+// instruction, mix two instruction streams etc.
+class riscv_instr_stream extends uvm_object;
+
+  `INSTR                instr_list[$];
+  int unsigned          instr_cnt;
+  string                label = "";
+  // User can specify a small group of available registers to generate various hazard condition
+  rand riscv_reg_t      avail_regs[];
+  // Some additional reserved registers that should not be used as rd register
+  // by this instruction stream
+  riscv_reg_t           reserved_rd[];
+
+  `uvm_object_utils(riscv_instr_stream)
+  `uvm_object_new
+
+  // Initialize the instruction stream, create each instruction instance
+  function void initialize_instr_list(int unsigned instr_cnt);
+    instr_list = {};
+    this.instr_cnt = instr_cnt;
+    create_instr_instance();
+  endfunction
+
+  virtual function void create_instr_instance();
+    `INSTR instr;
+    for(int i = 0; i < instr_cnt; i++) begin
+      instr = `INSTR::type_id::create($sformatf("instr_%0d", i));
+      instr_list.push_back(instr);
+    end
+  endfunction
+
+  // Insert an instruction to the existing instruction stream at the given index
+  // When index is -1, the instruction is injected at a random location
+  function void insert_instr(`INSTR instr, int idx = -1);
+    int current_instr_cnt = instr_list.size();
+    if(idx == -1) begin
+      idx = $urandom_range(0, current_instr_cnt-1);
+      while(instr_list[idx].atomic) begin
+       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",
+                       instr.convert2asm(), idx))
+    end
+    instr_list.insert(idx, instr);
+  endfunction
+
+  // Insert an instruction to the existing instruction stream at the given index
+  // When index is -1, the instruction is injected at a random location
+  // When replace is 1, the original instruction at the inserted position will be replaced
+  function void insert_instr_stream(`INSTR new_instr[], int idx = -1, bit replace = 1'b0);
+    int current_instr_cnt = instr_list.size();
+    int new_instr_cnt = new_instr.size();
+    if(current_instr_cnt == 0) begin
+      instr_list = new_instr;
+      return;
+    end
+    if(idx == -1) begin
+      idx = $urandom_range(0, current_instr_cnt-1);
+      repeat(10) begin
+       if (instr_list[idx].atomic) break;
+       idx = $urandom_range(0, current_instr_cnt-1);
+      end
+      if (instr_list[idx].atomic) begin
+        foreach (instr_list[i]) begin
+          if (!instr_list[i].atomic) begin
+            idx = i;
+            break;
+          end
+        end
+        if (instr_list[idx].atomic) begin
+          `uvm_fatal(`gfn, $sformatf("Cannot inject the instruction"))
+        end
+      end
+    end else if((idx > current_instr_cnt) || (idx < 0)) begin
+      `uvm_error(`gfn, $sformatf("Cannot insert instr stream at idx %0d", idx))
+    end
+    // When replace is 1, the original instruction at this index will be removed. The label of the
+    // original instruction will be copied to the head of inserted instruction stream.
+    if(replace) begin
+      new_instr[0].label = instr_list[idx].label;
+      new_instr[0].has_label = instr_list[idx].has_label;
+      if (idx == 0) begin
+        instr_list = {new_instr, instr_list[idx+1:current_instr_cnt-1]};
+      end else begin
+        instr_list = {instr_list[0:idx-1], new_instr, instr_list[idx+1:current_instr_cnt-1]};
+      end
+    end else begin
+      if (idx == 0) begin
+        instr_list = {new_instr, instr_list[idx:current_instr_cnt-1]};
+      end else begin
+        instr_list = {instr_list[0:idx-1], new_instr, instr_list[idx:current_instr_cnt-1]};
+      end
+    end
+  endfunction
+
+  // Mix the input instruction stream with the original instruction, the instruction order is
+  // preserved. When 'contained' is set, the original instruction stream will be inside the
+  // new instruction stream with the first and last instruction from the input instruction stream.
+  function void mix_instr_stream(`INSTR new_instr[], bit contained = 1'b0);
+    int current_instr_cnt = instr_list.size();
+    int insert_instr_position[];
+    int new_instr_cnt = new_instr.size();
+    insert_instr_position = new[new_instr_cnt];
+    `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(insert_instr_position,
+      foreach(insert_instr_position[i]) {
+        insert_instr_position[i] inside {[0:current_instr_cnt-1]};
+      })
+    if (insert_instr_position.size() > 0) begin
+      insert_instr_position.sort();
+    end
+    if(contained) begin
+      insert_instr_position[0] = 0;
+      if(new_instr_cnt > 1)
+        insert_instr_position[new_instr_cnt-1] = current_instr_cnt-1;
+    end
+    foreach(new_instr[i]) begin
+      insert_instr(new_instr[i], insert_instr_position[i] + i);
+    end
+  endfunction
+
+  function string convert2string();
+    string str;
+    foreach(instr_list[i])
+      str = {str, instr_list[i].convert2asm(), "\n"};
+    return str;
+  endfunction
+
+endclass
+
+// Generate a random instruction stream based on the configuration
+// There are two ways to use this class to generate instruction stream
+// 1. For short instruction stream, you can call randomize() directly.
+// 2. For long instruction stream (>1K), randomize() all instructions together might take a long
+// time for the constraint solver. In this case, you can call gen_instr to generate instructions
+// one by one. The time only grows linearly with the instruction count
+class riscv_rand_instr_stream extends riscv_instr_stream;
+
+  riscv_instr_gen_config  cfg;
+  bit                     kernel_mode;
+  riscv_instr_name_t      allowed_instr[$];
+  int unsigned            category_dist[riscv_instr_category_t];
+
+  `uvm_object_utils(riscv_rand_instr_stream)
+  `uvm_object_new
+
+  virtual function void create_instr_instance();
+    `INSTR instr;
+    for (int i = 0; i < instr_cnt; i++) begin
+      instr = `INSTR::type_id::create($sformatf("instr_%0d", i));
+      instr_list.push_back(instr);
+    end
+  endfunction
+
+  virtual function void setup_allowed_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1);
+    allowed_instr = cfg.basic_instr;
+    if (no_branch == 0) begin
+      allowed_instr = {allowed_instr, cfg.instr_category[BRANCH]};
+    end
+    if (no_load_store == 0) begin
+      allowed_instr = {allowed_instr, cfg.instr_category[LOAD], cfg.instr_category[STORE]};
+    end
+    setup_instruction_dist(no_branch, no_load_store);
+  endfunction
+
+  function void setup_instruction_dist(bit no_branch = 1'b0, bit no_load_store = 1'b1);
+    if (cfg.dist_control_mode) begin
+      category_dist = cfg.category_dist;
+      if (no_branch) begin
+        category_dist[BRANCH] = 0;
+      end
+      if (no_load_store) begin
+        category_dist[LOAD] = 0;
+        category_dist[STORE] = 0;
+      end
+      `uvm_info(`gfn, $sformatf("setup_instruction_dist: %0d", category_dist.size()), UVM_LOW)
+    end
+  endfunction
+
+  virtual function void gen_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1,
+                                  bit is_debug_program = 1'b0);
+    setup_allowed_instr(no_branch, no_load_store);
+    foreach(instr_list[i]) begin
+      randomize_instr(instr_list[i], is_debug_program);
+    end
+    // Do not allow branch instruction as the last instruction because there's no
+    // forward branch target
+    while (instr_list[$].category == BRANCH) begin
+      void'(instr_list.pop_back());
+      if (instr_list.size() == 0) break;
+    end
+  endfunction
+
+  function void randomize_instr(riscv_instr_base instr,
+                                bit is_in_debug = 1'b0,
+                                bit skip_rs1 = 1'b0,
+                                bit skip_rs2 = 1'b0,
+                                bit skip_rd  = 1'b0,
+                                bit skip_imm = 1'b0,
+                                bit skip_csr = 1'b0,
+                                bit disable_dist = 1'b0);
+    riscv_instr_name_t instr_name;
+    if ((cfg.dist_control_mode == 1) && !disable_dist) begin
+      riscv_instr_category_t category;
+      int unsigned idx;
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(category,
+        category dist {LOAD       := category_dist[LOAD],
+                       STORE      := category_dist[STORE],
+                       SHIFT      := category_dist[SHIFT],
+                       ARITHMETIC := category_dist[ARITHMETIC],
+                       LOGICAL    := category_dist[LOGICAL],
+                       COMPARE    := category_dist[COMPARE],
+                       BRANCH     := category_dist[BRANCH],
+                       SYNCH      := category_dist[SYNCH],
+                       CSR        := category_dist[CSR]};)
+      idx = $urandom_range(0, cfg.instr_category[category].size() - 1);
+      instr_name = cfg.instr_category[category][idx];
+    // if set_dcsr_ebreak is set, we do not want to generate any ebreak
+    // instructions inside the debug_rom
+    end else if ((cfg.no_ebreak && !is_in_debug) ||
+                 (!cfg.enable_ebreak_in_debug_rom && is_in_debug)) begin
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(instr_name,
+                                        instr_name inside {allowed_instr};
+                                        !(instr_name inside {EBREAK, C_EBREAK});)
+    end else begin
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(instr_name,
+                                         instr_name inside {allowed_instr};)
+    end
+    instr.copy_base_instr(cfg.instr_template[instr_name]);
+    `uvm_info(`gfn, $sformatf("%s: rs1:%0d, rs2:%0d, rd:%0d, imm:%0d",
+                              instr.instr_name.name(),
+                              instr.has_rs1,
+                              instr.has_rs2,
+                              instr.has_rd,
+                              instr.has_imm), UVM_FULL)
+    if (instr.has_imm && !skip_imm) begin
+      instr.gen_rand_imm();
+    end
+    if (instr.has_rs1 && !skip_rs1) begin
+      if (instr.is_compressed) begin
+        // Compressed instruction could use the same register for rs1 and rd
+        instr.rs1 = instr.gen_rand_gpr(
+                         .included_reg(avail_regs),
+                         .excluded_reg({reserved_rd, cfg.reserved_regs}));
+      end else begin
+        instr.rs1 = instr.gen_rand_gpr(.included_reg(avail_regs));
+      end
+    end
+    if (instr.has_rs2 && !skip_rs2) begin
+      instr.rs2 = instr.gen_rand_gpr(.included_reg(avail_regs));
+    end
+    if (instr.has_rd && !skip_rd) begin
+      if (instr_name == C_LUI) begin
+        instr.rd = instr.gen_rand_gpr(
+                        .included_reg(avail_regs),
+                        .excluded_reg({reserved_rd, cfg.reserved_regs, SP}));
+      end else begin
+        instr.rd = instr.gen_rand_gpr(
+                        .included_reg(avail_regs),
+                        .excluded_reg({reserved_rd, cfg.reserved_regs}));
+      end
+    end
+    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),
+                         .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();
+    end
+    if (instr.has_fs2) begin
+      instr.fs2 = instr.gen_rand_fpr();
+    end
+    if (instr.has_fs3) begin
+      instr.fs3 = instr.gen_rand_fpr();
+    end
+    if (instr.has_fd) begin
+      instr.fd = instr.gen_rand_fpr();
+    end
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/deprecated/riscv_load_store_instr_lib.sv b/vendor/google_riscv-dv/src/deprecated/riscv_load_store_instr_lib.sv
new file mode 100644
index 00000000..92b05706
--- /dev/null
+++ b/vendor/google_riscv-dv/src/deprecated/riscv_load_store_instr_lib.sv
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2018 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.
+ */
+
+// Base class for all load/store instruction stream
+
+class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
+
+  typedef enum bit [1:0] {
+    NARROW,
+    HIGH,
+    MEDIUM,
+    SPARSE
+  } locality_e;
+
+  rand int unsigned  num_load_store;
+  rand int unsigned  num_mixed_instr;
+  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;
+  rand int           max_load_store_offset;
+
+  `uvm_object_utils(riscv_load_store_base_instr_stream)
+
+  constraint rs1_c {
+    !(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
+  }
+
+  constraint addr_c {
+    solve data_page_id before max_load_store_offset;
+    solve max_load_store_offset before base;
+    data_page_id < max_data_page_id;
+    foreach (data_page[i]) {
+      if (i == data_page_id) {
+        max_load_store_offset == data_page[i].size_in_bytes;
+      }
+    }
+    base inside {[0 : max_load_store_offset-1]};
+  }
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  virtual function void randomize_offset();
+    int offset_, addr_;
+    offset = new[num_load_store];
+    addr = new[num_load_store];
+    for (int i=0; i 0) begin
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
+                                         unique{avail_regs};
+                                         avail_regs[0] inside {[S0 : A5]};
+                                         foreach(avail_regs[i]) {
+                                           !(avail_regs[i] inside {cfg.reserved_regs, reserved_rd});
+                                         },
+                                         "Cannot randomize avail_regs")
+    end
+    if ((rs1_reg inside {[S0 : A5]}) && !cfg.disable_compressed_instr) begin
+      enable_compressed_load_store = 1;
+    end
+    foreach(addr[i]) begin
+      instr = riscv_instr_base::type_id::create("instr");
+      // Assign the allowed load/store instructions based on address alignment
+      // This is done separately rather than a constraint to improve the randomization performance
+      allowed_instr = {LB, LBU, SB};
+      if (!cfg.enable_unaligned_load_store) begin
+        if (addr[i][0] == 1'b0) begin
+          allowed_instr = {LH, LHU, SH, allowed_instr};
+        end
+        if (addr[i] % 4 == 0) begin
+          allowed_instr = {LW, SW, allowed_instr};
+          if (cfg.enable_floating_point) begin
+            allowed_instr = {FLW, FSW, allowed_instr};
+          end
+          if((offset[i] inside {[0:127]}) && (offset[i] % 4 == 0) &&
+             (RV32C inside {riscv_instr_pkg::supported_isa}) &&
+             enable_compressed_load_store) begin
+            allowed_instr = {C_LW, C_SW, allowed_instr};
+            if (cfg.enable_floating_point && (RV32FC inside {supported_isa})) begin
+              allowed_instr = {C_FLW, C_FSW, allowed_instr};
+            end
+          end
+        end
+        if ((XLEN >= 64) && (addr[i] % 8 == 0)) begin
+          allowed_instr = {LWU, LD, SD, allowed_instr};
+          if (cfg.enable_floating_point && (RV32D inside {supported_isa})) begin
+            allowed_instr = {FLD, FSD, allowed_instr};
+          end
+          if((offset[i] inside {[0:255]}) && (offset[i] % 8 == 0) &&
+             (RV64C inside {riscv_instr_pkg::supported_isa} &&
+             enable_compressed_load_store)) begin
+            allowed_instr = {C_LD, C_SD, allowed_instr};
+            if (cfg.enable_floating_point && (RV32DC inside {supported_isa})) begin
+              allowed_instr = {C_FLD, C_FSD, allowed_instr};
+            end
+          end
+        end
+      end else begin
+        allowed_instr = {LW, SW, LH, LHU, SH, allowed_instr};
+        if ((offset[i] inside {[0:127]}) && (offset[i] % 4 == 0) &&
+            (RV32C inside {riscv_instr_pkg::supported_isa}) &&
+            enable_compressed_load_store) begin
+          allowed_instr = {C_LW, C_SW, allowed_instr};
+        end
+        if (XLEN >= 64) begin
+          allowed_instr = {LWU, LD, SD, allowed_instr};
+          if ((offset[i] inside {[0:255]}) && (offset[i] % 8 == 0) &&
+              (RV64C inside {riscv_instr_pkg::supported_isa}) &&
+              enable_compressed_load_store) begin
+              allowed_instr = {C_LD, C_SD, allowed_instr};
+           end
+        end
+      end
+      randomize_instr(instr, .skip_rs1(1'b1), .skip_imm(1'b1), .disable_dist(1'b1));
+      instr.rs1 = rs1_reg;
+      instr.set_imm(offset[i]);
+      instr.process_load_store = 0;
+      instr_list.push_back(instr);
+      load_store_instr.push_back(instr);
+    end
+  endfunction
+
+endclass
+
+// A single load/store instruction
+class riscv_single_load_store_instr_stream extends riscv_load_store_base_instr_stream;
+
+  constraint legal_c {
+    num_load_store == 1;
+    num_mixed_instr < 5;
+  }
+
+  `uvm_object_utils(riscv_single_load_store_instr_stream)
+  `uvm_object_new
+
+endclass
+
+// Back to back load/store instructions
+class riscv_load_store_stress_instr_stream extends riscv_load_store_base_instr_stream;
+
+  int unsigned max_instr_cnt = 30;
+  int unsigned min_instr_cnt = 10;
+
+  constraint legal_c {
+    num_load_store inside {[min_instr_cnt:max_instr_cnt]};
+    num_mixed_instr == 0;
+  }
+
+  `uvm_object_utils(riscv_load_store_stress_instr_stream)
+  `uvm_object_new
+
+endclass
+
+// Random load/store sequence
+// A random mix of load/store instructions and other instructions
+class riscv_load_store_rand_instr_stream extends riscv_load_store_base_instr_stream;
+
+  constraint legal_c {
+    num_load_store inside {[10:30]};
+    num_mixed_instr inside {[10:30]};
+  }
+
+  `uvm_object_utils(riscv_load_store_rand_instr_stream)
+  `uvm_object_new
+
+endclass
+
+// Use a small set of GPR to create various WAW, RAW, WAR hazard scenario
+class riscv_hazard_instr_stream extends riscv_load_store_base_instr_stream;
+
+  int unsigned num_of_avail_regs = 6;
+
+  constraint legal_c {
+    num_load_store inside {[10:30]};
+    num_mixed_instr inside {[10:30]};
+  }
+
+  `uvm_object_utils(riscv_hazard_instr_stream)
+  `uvm_object_new
+
+  function void pre_randomize();
+    avail_regs = new[num_of_avail_regs];
+    super.pre_randomize();
+  endfunction
+
+endclass
+
+// Use a small set of address to create various load/store hazard sequence
+// This instruction stream focus more on hazard handling of load store unit.
+class riscv_load_store_hazard_instr_stream extends riscv_load_store_base_instr_stream;
+
+  rand int avail_addr[];
+
+  constraint legal_c {
+    num_load_store inside {[10:30]};
+    num_mixed_instr inside {[10:30]};
+  }
+
+  constraint avail_addr_c {
+    avail_addr.size() inside {[1:3]};
+    foreach(avail_addr[i]) {
+      avail_addr[i] inside {[0 : max_load_store_offset - 1]};
+    }
+  }
+
+  `uvm_object_utils(riscv_load_store_hazard_instr_stream)
+  `uvm_object_new
+
+  // Randomize each address in the post_randomize to reduce the complexity of solving everything
+  // in one shot.
+  function void post_randomize();
+    int temp_addr;
+    foreach(addr[i]) begin
+      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(temp_addr,
+                                         temp_addr inside {avail_addr};,
+                                         "Cannot randomize address")
+      addr[i] = temp_addr;
+    end
+  endfunction
+endclass
+
+// Back to back access to multiple data pages
+// This is useful to test data TLB switch and replacement
+class riscv_multi_page_load_store_instr_stream extends riscv_mem_access_stream;
+
+  riscv_load_store_stress_instr_stream load_store_instr_stream[];
+  rand int unsigned num_of_instr_stream;
+  rand int unsigned data_page_id[];
+  rand riscv_reg_t  rs1_reg[];
+
+  constraint default_c {
+    foreach(data_page_id[i]) {
+      data_page_id[i] < max_data_page_id;
+    }
+    data_page_id.size() == num_of_instr_stream;
+    rs1_reg.size() == num_of_instr_stream;
+    unique {rs1_reg};
+    foreach(rs1_reg[i]) {
+      !(rs1_reg[i] inside {cfg.reserved_regs, ZERO});
+    }
+  }
+
+  constraint page_c {
+    solve num_of_instr_stream before data_page_id;
+    num_of_instr_stream inside {[1 : max_data_page_id]};
+    unique {data_page_id};
+  }
+
+  // Avoid accessing a large number of pages because we may run out of registers for rs1
+  // Each page access needs a reserved register as the base address of load/store instruction
+  constraint reasonable_c {
+    num_of_instr_stream inside {[2:8]};
+  }
+
+  `uvm_object_utils(riscv_multi_page_load_store_instr_stream)
+  `uvm_object_new
+
+  // Generate each load/store seq, and mix them together
+  function void post_randomize();
+    load_store_instr_stream = new[num_of_instr_stream];
+    foreach(load_store_instr_stream[i]) begin
+      load_store_instr_stream[i] = riscv_load_store_stress_instr_stream::type_id::
+                                   create($sformatf("load_store_instr_stream_%0d", i));
+      load_store_instr_stream[i].min_instr_cnt = 5;
+      load_store_instr_stream[i].max_instr_cnt = 10;
+      load_store_instr_stream[i].cfg = cfg;
+      // Make sure each load/store sequence doesn't override the rs1 of other sequences.
+      foreach(rs1_reg[j]) begin
+        if(i != j) begin
+          load_store_instr_stream[i].reserved_rd =
+            {load_store_instr_stream[i].reserved_rd, rs1_reg[j]};
+        end
+      end
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(load_store_instr_stream[i],
+                                     rs1_reg == local::rs1_reg[i];
+                                     data_page_id == local::data_page_id[i];,
+                                     "Cannot randomize load/store instruction")
+      // Mix the instruction stream of different page access, this could trigger the scenario of
+      // frequent data TLB switch
+      if(i == 0) begin
+        instr_list = load_store_instr_stream[i].instr_list;
+      end else begin
+        mix_instr_stream(load_store_instr_stream[i].instr_list);
+      end
+    end
+  endfunction
+
+endclass
+
+// Access the different locations of the same memory regions
+class riscv_mem_region_stress_test extends riscv_multi_page_load_store_instr_stream;
+
+  `uvm_object_utils(riscv_mem_region_stress_test)
+  `uvm_object_new
+
+  constraint page_c {
+    num_of_instr_stream inside {[2:5]};
+    foreach (data_page_id[i]) {
+      if (i > 0) {
+        data_page_id[i] == data_page_id[i-1];
+      }
+    }
+  }
+
+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 0;
+        // Avoid count to negative
+        loop_step_val[i] + loop_limit_val[i] > 0;
+      } else if (branch_type[i] == BLT) {
+        loop_step_val[i] > 0;
+      } else if (branch_type[i] == BLTU) {
+        loop_step_val[i] > 0;
+        loop_limit_val[i] > 0;
+      }
+      loop_init_val[i]  inside {[-10:10]};
+      loop_step_val[i]  inside {[-10:10]};
+      if(loop_init_val[i] < loop_limit_val[i]) {
+        loop_step_val[i] > 0;
+      } else {
+        loop_step_val[i] < 0;
+      }
+    }
+  }
+
+  `uvm_object_utils(riscv_loop_instr)
+  `uvm_object_new
+
+  function void post_randomize();
+    reserved_rd = {loop_cnt_reg, loop_limit_reg};
+    // Generate instructions that mixed with the loop instructions
+    initialize_instr_list(num_of_instr_in_loop);
+    gen_instr(1'b1);
+    // Randomize the key loop instructions
+    loop_init_instr   = new[num_of_nested_loop*2];
+    loop_update_instr = new[num_of_nested_loop];
+    loop_branch_instr = new[num_of_nested_loop];
+    loop_branch_target_instr = new[num_of_nested_loop];
+    for(int i = 0; i < num_of_nested_loop; i++) begin
+      // Instruction to init the loop counter
+      loop_init_instr[2*i] = riscv_instr_base::type_id::create("loop_init_instr");
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_init_instr[2*i],
+                                     instr_name == ADDI;
+                                     rd == loop_cnt_reg[i];
+                                     rs1 == ZERO;
+                                     imm == loop_init_val[i];,
+                                     "Cannot randomize loop init insturction")
+      loop_init_instr[2*i].comment = $sformatf("init loop %0d counter", i);
+
+      // Instruction to init loop limit
+      loop_init_instr[2*i+1] = riscv_instr_base::type_id::create("loop_init_instr");
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_init_instr[2*i+1],
+                                     instr_name == ADDI;
+                                     rd == loop_limit_reg[i];
+                                     rs1 == ZERO;
+                                     imm == loop_limit_val[i];,
+                                     "Cannot randomize init loop instruction")
+      loop_init_instr[2*i+1].comment = $sformatf("init loop %0d limit", i);
+
+      // Branch target instruction, can be anything
+      loop_branch_target_instr[i] = riscv_rand_instr::type_id::create("loop_branch_target_instr");
+      loop_branch_target_instr[i].cfg = cfg;
+      loop_branch_target_instr[i].reserved_rd = reserved_rd;
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_target_instr[i],
+                                     !(category inside {LOAD, STORE, BRANCH, JUMP});
+                                     // TODO: allow CSR instructions in all modes
+                                     if (cfg.init_privileged_mode == MACHINE_MODE) {
+                                       if (category == CSR) {
+                                         csr == MSCRATCH;
+                                       }
+                                     } else {
+                                       !(category == CSR);
+                                     },
+                                     "Cannot randomize branch target instruction")
+      loop_branch_target_instr[i].label = $sformatf("%0s_%0d_t", label, i);
+
+      // Instruction to update loop counter
+      loop_update_instr[i] = riscv_instr_base::type_id::create("loop_update_instr");
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_update_instr[i],
+                                     instr_name == ADDI;
+                                     rd == loop_cnt_reg[i];
+                                     rs1== loop_cnt_reg[i];
+                                     imm == loop_step_val[i];,
+                                     "Cannot randomize loop update instruction")
+      loop_update_instr[i].comment = $sformatf("update loop %0d counter", i);
+
+      // Backward branch instruction
+      loop_branch_instr[i] = riscv_instr_base::type_id::create("loop_branch_instr");
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_instr[i],
+                                     instr_name == branch_type[i];
+                                     rs1 == loop_cnt_reg[i];
+                                     if (!(branch_type[i] inside {C_BEQZ, C_BNEZ})) {
+                                       rs2 == loop_limit_reg[i];
+                                     },
+                                     "Cannot randomize backward branch instruction")
+      loop_branch_instr[i].comment = $sformatf("branch for loop %0d", i);
+      loop_branch_instr[i].imm_str = loop_branch_target_instr[i].label;
+      loop_branch_instr[i].branch_assigned = 1'b1;
+    end
+    // Randomly distribute the loop instruction in the existing instruction stream
+    build_loop_instr_stream();
+    mix_instr_stream(loop_instr, 1'b1);
+    foreach(instr_list[i]) begin
+      if(instr_list[i].label != "")
+        instr_list[i].has_label = 1'b1;
+      else
+        instr_list[i].has_label = 1'b0;
+      instr_list[i].atomic = 1'b1;
+    end
+  endfunction
+
+  // Build the whole loop structure from innermost loop to the outermost loop
+  function void build_loop_instr_stream();
+    loop_instr.delete;
+    for(int i = 0; i < num_of_nested_loop; i++) begin
+      loop_instr = {loop_init_instr[2*i],
+                    loop_init_instr[2*i+1],
+                    loop_branch_target_instr[i],
+                    loop_update_instr[i],
+                    loop_instr,
+                    loop_branch_instr[i]};
+    end
+    `uvm_info(get_full_name(), $sformatf("Totally %0d instructions have been added",
+                               loop_instr.size()), UVM_HIGH)
+  endfunction
+endclass
diff --git a/vendor/google_riscv-dv/src/riscv_rand_instr.sv b/vendor/google_riscv-dv/src/deprecated/riscv_rand_instr.sv
similarity index 100%
rename from vendor/google_riscv-dv/src/riscv_rand_instr.sv
rename to vendor/google_riscv-dv/src/deprecated/riscv_rand_instr.sv
diff --git a/vendor/google_riscv-dv/src/dv_defines.svh b/vendor/google_riscv-dv/src/dv_defines.svh
index 1ebdf507..205f5d35 100644
--- a/vendor/google_riscv-dv/src/dv_defines.svh
+++ b/vendor/google_riscv-dv/src/dv_defines.svh
@@ -67,3 +67,11 @@
   `define DV_CHECK_STD_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_,MSG_="Randomization failed!",ID_=`gfn) \
     `DV_CHECK_FATAL(std::randomize(VAR_), MSG_, ID_, with { WITH_C_ })
 `endif
+
+// for vector processing
+`ifndef VECTOR_INCLUDE
+  `define VECTOR_INCLUDE(VCE_INC) \
+    `ifdef ENABLE_VECTORS \
+      `include VCE_INC \
+    `endif
+`endif
diff --git a/vendor/google_riscv-dv/src/isa/riscv_amo_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_amo_instr.sv
new file mode 100644
index 00000000..29458fa6
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/riscv_amo_instr.sv
@@ -0,0 +1,60 @@
+class riscv_amo_instr extends riscv_instr;
+
+  rand bit aq;
+  rand bit rl;
+
+  constraint aq_rl_c {
+    aq && rl == 0;
+  }
+
+  `uvm_object_utils(riscv_amo_instr)
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  virtual function string get_instr_name();
+    get_instr_name = instr_name.name();
+    if (group == RV32A) begin
+      get_instr_name = {get_instr_name.substr(0, get_instr_name.len() - 3), ".w"};
+      get_instr_name = aq ? {get_instr_name, ".aq"} :
+                       rl ? {get_instr_name, ".rl"} : get_instr_name;
+    end else if (group == RV64A) begin
+      get_instr_name = {get_instr_name.substr(0, get_instr_name.len() - 3), ".d"};
+      get_instr_name = aq ? {get_instr_name, ".aq"} :
+                       rl ? {get_instr_name, ".rl"} : get_instr_name;
+    end else begin
+      `uvm_fatal(`gfn, $sformatf("Unexpected amo instr group: %0s / %0s",
+                                 group.name(), instr_name.name()))
+    end
+    return get_instr_name;
+  endfunction : get_instr_name
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    if (group inside {RV32A, RV64A}) begin
+      if (instr_name inside {LR_W, LR_D}) begin
+        asm_str = $sformatf("%0s %0s, (%0s)", asm_str, rd.name(), rs1.name());
+      end else begin
+        asm_str = $sformatf("%0s %0s, %0s, (%0s)", asm_str, rd.name(), rs2.name(), rs1.name());
+      end
+    end else begin
+      `uvm_fatal(`gfn, $sformatf("Unexpected amo instr group: %0s / %0s",
+                                 group.name(), instr_name.name()))
+    end
+    if(comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction : convert2asm
+
+  virtual function void do_copy(uvm_object rhs);
+    riscv_amo_instr rhs_;
+    super.copy(rhs);
+    assert($cast(rhs_, rhs));
+    this.aq = rhs_.aq;
+    this.rl = rhs_.rl;
+  endfunction : do_copy
+
+endclass
diff --git a/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv
new file mode 100644
index 00000000..57902648
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv
@@ -0,0 +1,384 @@
+class riscv_compressed_instr extends riscv_instr;
+
+  int imm_align;
+
+  constraint rvc_csr_c {
+    //  Registers specified by the three-bit rs1’, rs2’, and rd’
+    if (format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT, CA_FORMAT}) {
+      if (has_rs1) {
+        rs1 inside {[S0:A5]};
+      }
+      if (has_rs2) {
+        rs2 inside {[S0:A5]};
+      }
+      if (has_rd) {
+        rd inside {[S0:A5]};
+      }
+    }
+    // C_ADDI16SP is only valid when rd == SP
+    if (instr_name == C_ADDI16SP) {
+      rd  == SP;
+    }
+    if (instr_name inside {C_JR, C_JALR}) {
+      rs2 == ZERO;
+      rs1 != ZERO;
+    }
+  }
+
+  constraint imm_val_c {
+    if(imm_type inside {NZIMM, NZUIMM}) {
+      imm[5:0] != 0;
+      if (instr_name == C_LUI) {
+        // TODO(taliu) Check why bit 6 cannot be zero
+        imm[31:5] == 0;
+      }
+      if (instr_name inside {C_SRAI, C_SRLI, C_SLLI}) {
+        imm[31:5] == 0;
+      }
+    }
+  }
+
+  // C_JAL is RV32C only instruction
+  constraint jal_c {
+    if (XLEN != 32) {
+      instr_name != C_JAL;
+    }
+  }
+
+  // Avoid generating HINT or illegal instruction by default as it's not supported by the compiler
+  constraint no_hint_illegal_instr_c {
+    if (instr_name inside {C_ADDI, C_ADDIW, C_LI, C_LUI, C_SLLI, C_SLLI64,
+                           C_LQSP, C_LDSP, C_MV, C_ADD, C_LWSP}) {
+      rd != ZERO;
+    }
+    if (instr_name == C_JR) {
+      rs1 != ZERO;
+    }
+    if (instr_name inside {C_ADD, C_MV}) {
+      rs2 != ZERO;
+    }
+    (instr_name == C_LUI) -> (rd != SP);
+  }
+
+  `uvm_object_utils(riscv_compressed_instr)
+
+  function new(string name = "");
+    super.new(name);
+    rs1 = S0;
+    rs2 = S0;
+    rd  = S0;
+    is_compressed = 1'b1;
+  endfunction : new
+
+  virtual function void set_imm_len();
+    if (format inside {CI_FORMAT, CSS_FORMAT}) begin
+      imm_len = 6;
+    end else if (format inside {CL_FORMAT, CS_FORMAT}) begin
+      imm_len = 5;
+    end else if (format inside {CJ_FORMAT}) begin
+      imm_len = 11;
+    end else if (format inside {CB_FORMAT}) begin
+      if (instr_name == C_ANDI) begin
+        imm_len = 6;
+      end else begin
+        imm_len = 7;
+      end
+    end else if (format inside {CB_FORMAT, CIW_FORMAT}) begin
+      imm_len = 8;
+    end
+    if (instr_name inside {C_SQ, C_LQ, C_LQSP, C_SQSP, C_ADDI16SP}) begin
+      imm_align = 4;
+    end else if (instr_name inside {C_SD, C_LD, C_LDSP, C_SDSP}) begin
+      imm_align = 3;
+    end else if (instr_name inside {C_SW, C_LW, C_LWSP, C_SWSP, C_ADDI4SPN}) begin
+      imm_align = 2;
+    end else if (instr_name inside {C_LUI}) begin
+      imm_align = 12;
+    end else if (instr_name inside {C_J, C_JAL, C_BNEZ, C_BEQZ}) begin
+      imm_align = 1;
+    end
+  endfunction : set_imm_len
+
+  virtual function void do_copy(uvm_object rhs);
+    riscv_compressed_instr rhs_;
+    super.copy(rhs);
+    assert($cast(rhs_, rhs));
+    this.imm_align = rhs_.imm_align;
+  endfunction : do_copy
+
+  virtual function void extend_imm();
+    if (instr_name != C_LUI) begin
+      super.extend_imm();
+      imm = imm << imm_align;
+    end
+  endfunction : extend_imm
+
+  virtual function void set_rand_mode();
+    case (format) inside
+      CR_FORMAT : begin
+        if (category == JUMP) begin
+          has_rd = 1'b0;
+        end else begin
+          has_rs1 = 1'b0;
+        end
+        has_imm = 1'b0;
+      end
+      CI_FORMAT : begin
+        has_rs2 = 1'b0;
+        has_rs1 = 1'b0;
+      end
+      CSS_FORMAT : begin
+        has_rs1 = 1'b0;
+        has_rd  = 1'b0;
+      end
+      CL_FORMAT: begin
+        has_rs2 = 1'b0;
+      end
+      CS_FORMAT : begin
+        has_rd = 1'b0;
+      end
+      CA_FORMAT: begin
+        has_rs1 = 1'b0;
+        has_imm = 1'b0;
+      end
+      CIW_FORMAT: begin
+        has_rs1 = 1'b0;
+        has_rs2 = 1'b0;
+      end
+      CJ_FORMAT: begin
+        has_rs1 = 1'b0;
+        has_rs2 = 1'b0;
+        has_rd  = 1'b0;
+      end
+      CB_FORMAT: begin
+        if (instr_name != C_ANDI) has_rd = 1'b0;
+        has_rs2 = 1'b0;
+      end
+    endcase
+  endfunction
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    if (category != SYSTEM) begin
+      case(format)
+        CI_FORMAT, CIW_FORMAT:
+          if (instr_name == C_NOP)
+            asm_str = "c.nop";
+          else if (instr_name == C_ADDI16SP)
+            asm_str = $sformatf("%0ssp, %0s", asm_str, get_imm());
+          else if (instr_name inside {C_LDSP, C_LWSP, C_LQSP})
+            asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, rd.name(), get_imm());
+          else
+            asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
+        CL_FORMAT:
+          asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rd.name(), get_imm(), rs1.name());
+        CS_FORMAT:
+          if (category == STORE)
+            asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rs2.name(), get_imm(), rs1.name());
+          else
+            asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), rs2.name());
+        CA_FORMAT:
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name());
+        CB_FORMAT:
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), get_imm());
+        CSS_FORMAT:
+          if (category == STORE)
+            asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, rs2.name(), get_imm());
+          else
+            asm_str = $sformatf("%0s%0s, %0s", asm_str, rs2.name(), get_imm());
+        CR_FORMAT:
+          if (instr_name inside {C_JR, C_JALR}) begin
+            asm_str = $sformatf("%0s%0s", asm_str, rs1.name());
+          end else begin
+            asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name());
+          end
+        CJ_FORMAT:
+          asm_str = $sformatf("%0s%0s", asm_str, get_imm());
+      endcase
+    end else begin
+      // For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
+      // This is needed to resume execution from epc+4 after ebreak handling
+      if (instr_name == C_EBREAK) begin
+        asm_str = "c.ebreak;c.nop;";
+      end
+    end
+    if (comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction : convert2asm
+
+  // Convert the instruction to assembly code
+  virtual function string convert2bin(string prefix = "");
+    string binary;
+    case (instr_name) inside
+      C_ADDI4SPN:
+        binary = $sformatf("%4h", {get_func3(), imm[5:4], imm[9:6],
+                                   imm[2], imm[3], get_c_gpr(rd), get_c_opcode()});
+      C_LQ:
+        binary = $sformatf("%4h", {get_func3(), imm[5:4], imm[8],
+                                   get_c_gpr(rs1), imm[7:6], get_c_gpr(rd), get_c_opcode()});
+      C_FLD, C_LD:
+        binary = $sformatf("%4h", {get_func3(), imm[5:3], get_c_gpr(rs1),
+                                   imm[7:6], get_c_gpr(rd), get_c_opcode()});
+      C_LW, C_FLW:
+        binary = $sformatf("%4h", {get_func3(), imm[5:3], get_c_gpr(rs1),
+                                   imm[2], imm[6], get_c_gpr(rd), get_c_opcode()});
+      C_SQ:
+        binary = $sformatf("%4h", {get_func3(), imm[5:4], imm[8],
+                                   get_c_gpr(rs1), imm[7:6], get_c_gpr(rs2), get_c_opcode()});
+      C_FSD, C_SD:
+        binary = $sformatf("%4h", {get_func3(), imm[5:3], get_c_gpr(rs1),
+                                   imm[7:6], get_c_gpr(rs2), get_c_opcode()});
+      C_SW, C_FSW:
+        binary = $sformatf("%4h", {get_func3(), imm[5:3], get_c_gpr(rs1),
+                                   imm[2], imm[6], get_c_gpr(rs2), get_c_opcode()});
+      C_NOP, C_ADDI, C_LI, C_ADDIW:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:0], get_c_opcode()});
+      C_JAL, C_J:
+        binary = $sformatf("%4h", {get_func3(), imm[11], imm[4], imm[9:8],
+                                   imm[10], imm[6], imm[7], imm[3:1], imm[5], get_c_opcode()});
+      C_ADDI16SP:
+        binary = $sformatf("%4h", {get_func3(), imm[9], 5'b10,
+                                   imm[4], imm[6], imm[8:7], imm[5], get_c_opcode()});
+      C_LUI:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:0], get_c_opcode()});
+      C_SRLI:
+        binary = $sformatf("%4h", {get_func3(), imm[5],
+                                   2'b0, get_c_gpr(rd), imm[4:0], get_c_opcode()});
+      C_SRLI64:
+        binary = $sformatf("%4h", {get_func3(), 3'b0, get_c_gpr(rd), 5'b0, get_c_opcode()});
+      C_SRAI:
+        binary = $sformatf("%4h", {get_func3(), imm[5],
+                                   2'b01, get_c_gpr(rd), imm[4:0], get_c_opcode()});
+      C_SRAI64:
+        binary = $sformatf("%4h", {get_func3(), 3'b001,
+                                   get_c_gpr(rd), 5'b0, get_c_opcode()});
+      C_ANDI:
+        binary = $sformatf("%4h", {get_func3(), imm[5],
+                                   2'b10, get_c_gpr(rd), imm[4:0], get_c_opcode()});
+      C_SUB:
+        binary = $sformatf("%4h", {get_func3(), 3'b011, get_c_gpr(rd),
+                                   2'b00, get_c_gpr(rs2), get_c_opcode()});
+      C_XOR:
+        binary = $sformatf("%4h", {get_func3(), 3'b011, get_c_gpr(rd),
+                                   2'b01, get_c_gpr(rs2), get_c_opcode()});
+      C_OR:
+        binary = $sformatf("%4h", {get_func3(), 3'b011, get_c_gpr(rd),
+                                   2'b10, get_c_gpr(rs2), get_c_opcode()});
+      C_AND:
+        binary = $sformatf("%4h", {get_func3(), 3'b011, get_c_gpr(rd),
+                                   2'b11, get_c_gpr(rs2), get_c_opcode()});
+      C_SUBW:
+        binary = $sformatf("%4h", {get_func3(), 3'b111, get_c_gpr(rd),
+                                   2'b00, get_c_gpr(rs2), get_c_opcode()});
+      C_ADDW:
+        binary = $sformatf("%4h", {get_func3(), 3'b111, get_c_gpr(rd),
+                                   2'b01, get_c_gpr(rs2), get_c_opcode()});
+      C_BEQZ, C_BNEZ:
+        binary = $sformatf("%4h", {get_func3(), imm[8], imm[4:3],
+                                   get_c_gpr(rs1), imm[7:6], imm[2:1], imm[5], get_c_opcode()});
+      C_SLLI:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:0], get_c_opcode()});
+      C_SLLI64:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, rd, 5'b0, get_c_opcode()});
+      C_FLDSP, C_LDSP:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:3], imm[8:6], get_c_opcode()});
+      C_LQSP:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4], imm[9:6], get_c_opcode()});
+      C_LWSP, C_FLWSP:
+        binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:2], imm[7:6], get_c_opcode()});
+      C_JR:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, rs1, 5'b0, get_c_opcode()});
+      C_MV:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, rd, rs2, get_c_opcode()});
+      C_EBREAK:
+        binary = $sformatf("%4h", {get_func3(), 1'b1, 10'b0, get_c_opcode()});
+      C_JALR:
+        binary = $sformatf("%4h", {get_func3(), 1'b1, 10'b0, get_c_opcode()});
+      C_ADD:
+        binary = $sformatf("%4h", {get_func3(), 1'b1, rd, rs2, get_c_opcode()});
+      C_FSDSP, C_SDSP:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, imm[5:3], imm[8:6], rs2, get_c_opcode()});
+      C_SQSP:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, imm[5:4], imm[9:6], rs2, get_c_opcode()});
+      C_SWSP, C_FSWSP:
+        binary = $sformatf("%4h", {get_func3(), 1'b0, imm[5:2], imm[7:6], rs2, get_c_opcode()});
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+    return {prefix, binary};
+  endfunction : convert2bin
+
+  // Get opcode for compressed instruction
+  virtual function bit [1:0] get_c_opcode();
+    case (instr_name) inside
+      C_ADDI4SPN, C_FLD, C_FLD, C_LQ, C_LW, C_FLW,
+      C_LD, C_FSD, C_SQ, C_SW, C_FSW, C_SD            : get_c_opcode = 2'b00;
+      C_NOP, C_ADDI, C_JAL, C_ADDIW, C_LI, C_ADDI16SP,
+      C_LUI, C_SRLI, C_SRLI64, C_SRAI, C_SRAI64,
+      C_ANDI, C_SUB, C_XOR, C_OR, C_AND, C_SUBW,
+      C_ADDW, C_J, C_BEQZ, C_BNEZ                     : get_c_opcode = 2'b01;
+      C_SLLI, C_SLLI64, C_FLDSP, C_LQSP, C_LWSP,
+      C_FLWSP, C_LDSP, C_JR, C_MV, C_EBREAK, C_JALR,
+      C_ADD, C_FSDSP, C_SQSP, C_SWSP, C_FSWSP, C_SDSP : get_c_opcode = 2'b10;
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+  endfunction : get_c_opcode
+
+  virtual function bit [2:0] get_func3();
+    case (instr_name) inside
+      C_ADDI4SPN : get_func3 = 3'b000;
+      C_FLD      : get_func3 = 3'b001;
+      C_LQ       : get_func3 = 3'b001;
+      C_LW       : get_func3 = 3'b010;
+      C_FLW      : get_func3 = 3'b011;
+      C_LD       : get_func3 = 3'b011;
+      C_FSD      : get_func3 = 3'b101;
+      C_SQ       : get_func3 = 3'b101;
+      C_SW       : get_func3 = 3'b110;
+      C_FSW      : get_func3 = 3'b111;
+      C_SD       : get_func3 = 3'b111;
+      C_NOP      : get_func3 = 3'b000;
+      C_ADDI     : get_func3 = 3'b000;
+      C_JAL      : get_func3 = 3'b001;
+      C_ADDIW    : get_func3 = 3'b001;
+      C_LI       : get_func3 = 3'b010;
+      C_ADDI16SP : get_func3 = 3'b011;
+      C_LUI      : get_func3 = 3'b011;
+      C_SRLI     : get_func3 = 3'b100;
+      C_SRLI64   : get_func3 = 3'b100;
+      C_SRAI     : get_func3 = 3'b100;
+      C_SRAI64   : get_func3 = 3'b100;
+      C_ANDI     : get_func3 = 3'b100;
+      C_SUB      : get_func3 = 3'b100;
+      C_XOR      : get_func3 = 3'b100;
+      C_OR       : get_func3 = 3'b100;
+      C_AND      : get_func3 = 3'b100;
+      C_SUBW     : get_func3 = 3'b100;
+      C_ADDW     : get_func3 = 3'b100;
+      C_J        : get_func3 = 3'b101;
+      C_BEQZ     : get_func3 = 3'b110;
+      C_BNEZ     : get_func3 = 3'b111;
+      C_SLLI     : get_func3 = 3'b000;
+      C_SLLI64   : get_func3 = 3'b000;
+      C_FLDSP    : get_func3 = 3'b001;
+      C_LQSP     : get_func3 = 3'b001;
+      C_LWSP     : get_func3 = 3'b010;
+      C_FLWSP    : get_func3 = 3'b011;
+      C_LDSP     : get_func3 = 3'b011;
+      C_JR       : get_func3 = 3'b100;
+      C_MV       : get_func3 = 3'b100;
+      C_EBREAK   : get_func3 = 3'b100;
+      C_JALR     : get_func3 = 3'b100;
+      C_ADD      : get_func3 = 3'b100;
+      C_FSDSP    : get_func3 = 3'b101;
+      C_SQSP     : get_func3 = 3'b101;
+      C_SWSP     : get_func3 = 3'b110;
+      C_FSWSP    : get_func3 = 3'b111;
+      C_SDSP     : get_func3 = 3'b111;
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+  endfunction : get_func3
+
+endclass : riscv_compressed_instr
diff --git a/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv
new file mode 100644
index 00000000..850c1787
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv
@@ -0,0 +1,70 @@
+class riscv_floating_point_instr extends riscv_instr;
+
+  rand riscv_fpr_t fs1;
+  rand riscv_fpr_t fs2;
+  rand riscv_fpr_t fs3;
+  rand riscv_fpr_t fd;
+
+  `uvm_object_utils(riscv_floating_point_instr)
+
+  function new(string name = "");
+    super.new(name);
+    rs2.rand_mode(0);
+  endfunction
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    case (format)
+      I_FORMAT:
+        if (category == LOAD) begin
+          asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name());
+        end else if (instr_name inside {FMV_X_W, FMV_X_D, FCVT_W_S, FCVT_WU_S,
+                                        FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D, FCVT_LU_S,
+                                        FCVT_W_D, FCVT_WU_D}) begin
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
+        end else if (instr_name inside {FMV_W_X, FMV_D_X, FCVT_S_W, FCVT_S_WU,
+                                        FCVT_S_L, FCVT_D_L, FCVT_S_LU, FCVT_D_W,
+                                        FCVT_D_LU, FCVT_D_WU}) begin
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, fd.name(), rs1.name());
+        end else begin
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, fd.name(), fs1.name());
+        end
+      S_FORMAT:
+        asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fs2.name(), get_imm(), rs1.name());
+      R_FORMAT:
+        if (category == COMPARE) begin
+          asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), fs1.name(), fs2.name());
+        end else if (instr_name inside {FCLASS_S, FCLASS_D}) begin
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
+        end else begin
+          asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, fd.name(), fs1.name(), fs2.name());
+        end
+      R4_FORMAT:
+        asm_str = $sformatf("%0s%0s, %0s, %0s, %0s", asm_str, fd.name(), fs1.name(),
+                                                     fs2.name(), fs3.name());
+      CL_FORMAT:
+        asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name());
+      CS_FORMAT:
+        asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fs2.name(), get_imm(), rs1.name());
+      default:
+        `uvm_fatal(`gfn, $sformatf("Unsupported floating point format: %0s", format.name()))
+    endcase
+    if(comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction
+
+
+  virtual function void do_copy(uvm_object rhs);
+    riscv_floating_point_instr rhs_;
+    super.copy(rhs);
+    assert($cast(rhs_, rhs));
+    this.fs3            = rhs_.fs3;
+    this.fs2            = rhs_.fs2;
+    this.fs1            = rhs_.fs1;
+    this.fd             = rhs_.fd;
+  endfunction : do_copy
+
+endclass
diff --git a/vendor/google_riscv-dv/src/isa/riscv_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_instr.sv
new file mode 100644
index 00000000..2e66f140
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/riscv_instr.sv
@@ -0,0 +1,622 @@
+/*
+ * Copyright 2019 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.
+ */
+
+class riscv_instr extends uvm_object;
+
+  // All derived instructions
+  static bit                 instr_registry[riscv_instr_name_t];
+
+  // Instruction list
+  static riscv_instr_name_t  instr_names[$];
+
+  // Categorized instruction list
+  static riscv_instr_name_t  instr_group[riscv_instr_group_t][$];
+  static riscv_instr_name_t  instr_category[riscv_instr_category_t][$];
+  static riscv_instr_name_t  basic_instr[$];
+  static riscv_instr         instr_template[riscv_instr_name_t];
+
+  // Privileged CSR filter
+  static privileged_reg_t    exclude_reg[];
+  static privileged_reg_t    include_reg[];
+
+  // Instruction attributes
+  riscv_instr_group_t        group;
+  riscv_instr_format_t       format;
+  riscv_instr_category_t     category;
+  riscv_instr_name_t         instr_name;
+  imm_t                      imm_type;
+  bit [4:0]                  imm_len;
+
+  // Operands
+  rand bit [11:0]            csr;
+  rand riscv_reg_t           rs2;
+  rand riscv_reg_t           rs1;
+  rand riscv_reg_t           rd;
+  rand bit [31:0]            imm;
+
+  // Helper fields
+  bit [31:0]                 imm_mask = 32'hFFFF_FFFF;
+  bit                        is_branch_target;
+  bit                        has_label = 1'b1;
+  bit                        atomic = 0;
+  bit                        branch_assigned;
+  bit                        process_load_store = 1'b1;
+  bit                        is_compressed;
+  bit                        is_illegal_instr;
+  bit                        is_hint_instr;
+  bit                        is_floating_point;
+  string                     imm_str;
+  string                     comment;
+  string                     label;
+  bit                        is_local_numeric_label;
+  int                        idx = -1;
+  bit                        has_rs1 = 1'b1;
+  bit                        has_rs2 = 1'b1;
+  bit                        has_rd = 1'b1;
+  bit                        has_imm = 1'b1;
+
+  constraint imm_c {
+    if (instr_name inside {SLLI, SRLI, SRAI, SLLIW, SRLIW, SRAIW}) {
+      imm[11:5] == 0;
+    }
+  }
+
+  constraint csr_c {
+    if (category == CSR) {
+      if (include_reg.size() > 0) {
+        csr inside {include_reg};
+      }
+      if (exclude_reg.size() > 0) {
+        !(csr inside {exclude_reg});
+      }
+    }
+  }
+
+  `uvm_object_utils(riscv_instr)
+  `uvm_object_new
+
+  static function bit register(riscv_instr_name_t instr_name);
+    `uvm_info("riscv_instr", $sformatf("Registering %0s", instr_name.name()), UVM_LOW)
+    instr_registry[instr_name] = 1;
+    return 1;
+  endfunction : register
+
+  // Create the list of instructions based on the supported ISA extensions and configuration of the
+  // generator.
+  static function void create_instr_list(riscv_instr_gen_config cfg);
+    instr_names.delete();
+    instr_group.delete();
+    instr_category.delete();
+    foreach (instr_registry[instr_name]) begin
+      riscv_instr instr_inst;
+      instr_inst = create_instr(instr_name);
+      instr_template[instr_name] = instr_inst;
+      // C_JAL is RV32C only instruction
+      if ((XLEN != 32) && (instr_name == C_JAL)) continue;
+      if ((SP inside {cfg.reserved_regs}) && (instr_name inside {C_ADDI16SP})) begin
+        continue;
+      end
+      if (!cfg.enable_sfence && instr_name == SFENCE_VMA) continue;
+      if (cfg.no_fence && (instr_name inside {FENCE, FENCE_I, SFENCE_VMA})) continue;
+      // TODO: gcc compile issue, support c.addi4spn later
+      if (instr_name == C_ADDI4SPN) continue;
+      if ((instr_inst.group inside {supported_isa}) &&
+          !(cfg.disable_compressed_instr &&
+            (instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
+          !(!cfg.enable_floating_point &&
+            (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D}))) begin
+        instr_category[instr_inst.category].push_back(instr_name);
+        instr_group[instr_inst.group].push_back(instr_name);
+        instr_names.push_back(instr_name);
+      end
+    end
+    build_basic_instruction_list(cfg);
+    create_csr_filter(cfg);
+  endfunction : create_instr_list
+
+  static function void create_csr_filter(riscv_instr_gen_config cfg);
+    include_reg.delete();
+    exclude_reg.delete();
+    if (cfg.enable_illegal_csr_instruction) begin
+      exclude_reg = implemented_csr;
+    end else if (cfg.enable_access_invalid_csr_level) begin
+      include_reg = cfg.invalid_priv_mode_csrs;
+    end else begin
+      // Use scratch register to avoid the side effect of modifying other privileged mode CSR.
+      if (cfg.init_privileged_mode == MACHINE_MODE) begin
+        include_reg = {MSCRATCH};
+      end else if (cfg.init_privileged_mode == SUPERVISOR_MODE) begin
+        include_reg = {SSCRATCH};
+      end else begin
+        include_reg = {USCRATCH};
+      end
+    end
+  endfunction : create_csr_filter
+
+  static function riscv_instr create_instr(riscv_instr_name_t instr_name);
+    uvm_object obj;
+    riscv_instr inst;
+    string instr_class_name;
+    uvm_coreservice_t coreservice = uvm_coreservice_t::get();
+    uvm_factory factory = coreservice.get_factory();
+    instr_class_name = {"riscv_", instr_name.name(), "_instr"};
+    obj = factory.create_object_by_name(instr_class_name, "riscv_instr", instr_class_name);
+    if (obj == null) begin
+      `uvm_fatal("riscv_instr", $sformatf("Failed to create instr: %0s", instr_class_name))
+    end
+    if (!$cast(inst, obj)) begin
+      `uvm_fatal("riscv_instr", $sformatf("Failed to cast instr: %0s", instr_class_name))
+    end
+    return inst;
+  endfunction : create_instr
+
+  static function void build_basic_instruction_list(riscv_instr_gen_config cfg);
+    basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
+                   instr_category[LOGICAL], instr_category[COMPARE]};
+    if (!cfg.no_ebreak) begin
+      basic_instr = {basic_instr, EBREAK};
+      foreach (riscv_instr_pkg::supported_isa[i]) begin
+        if (RV32C inside {riscv_instr_pkg::supported_isa[i]}) begin
+          basic_instr = {basic_instr, C_EBREAK};
+          break;
+        end
+      end
+    end
+    if (cfg.no_dret == 0) begin
+      basic_instr = {basic_instr, DRET};
+    end
+    if (cfg.no_fence == 0) begin
+      basic_instr = {basic_instr, instr_category[SYNCH]};
+    end
+    if ((cfg.no_csr_instr == 0) && (cfg.init_privileged_mode == MACHINE_MODE)) begin
+      basic_instr = {basic_instr, instr_category[CSR]};
+    end
+    if (cfg.no_wfi == 0) begin
+      basic_instr = {basic_instr, WFI};
+    end
+  endfunction : build_basic_instruction_list
+
+  static function riscv_instr get_rand_instr(riscv_instr instr_h = null,
+                                             riscv_instr_name_t include_instr[] = {},
+                                             riscv_instr_name_t exclude_instr[] = {},
+                                             riscv_instr_category_t include_category[] = {},
+                                             riscv_instr_category_t exclude_category[] = {},
+                                             riscv_instr_group_t include_group[] = {},
+                                             riscv_instr_group_t exclude_group[] = {});
+     int unsigned idx;
+     riscv_instr_name_t name;
+     riscv_instr_name_t allowed_instr[];
+     riscv_instr_name_t disallowed_instr[];
+     riscv_instr_category_t allowed_categories[];
+     foreach (include_category[i]) begin
+       allowed_instr = {allowed_instr, instr_category[include_category[i]]};
+     end
+     foreach (exclude_category[i]) begin
+       disallowed_instr = {disallowed_instr, instr_category[exclude_category[i]]};
+     end
+     foreach (include_group[i]) begin
+       allowed_instr = {allowed_instr, instr_group[include_group[i]]};
+     end
+     foreach (exclude_group[i]) begin
+       disallowed_instr = {disallowed_instr, instr_group[exclude_group[i]]};
+     end
+     disallowed_instr = {disallowed_instr, exclude_instr};
+     if (disallowed_instr.size() == 0) begin
+       if (include_instr.size() > 0) begin
+         idx = $urandom_range(0, include_instr.size()-1);
+         name = include_instr[idx];
+       end else if (allowed_instr.size() > 0) begin
+         idx = $urandom_range(0, allowed_instr.size()-1);
+         name = allowed_instr[idx];
+       end else begin
+         idx = $urandom_range(0, instr_names.size()-1);
+         name = instr_names[idx];
+       end
+     end else begin
+       if (!std::randomize(name) with {
+          name inside {instr_names};
+          if (include_instr.size() > 0) {
+            name inside {include_instr};
+          }
+          if (allowed_instr.size() > 0) {
+            name inside {allowed_instr};
+          }
+          if (disallowed_instr.size() > 0) {
+            !(name inside {disallowed_instr});
+          }
+       }) begin
+         `uvm_fatal("riscv_instr", "Cannot generate random instruction")
+       end
+     end
+     // Shallow copy for all relevant fields, avoid using create() to improve performance
+     instr_h = new instr_template[name];
+     return instr_h;
+  endfunction : get_rand_instr
+
+  static function riscv_instr get_load_store_instr(riscv_instr_name_t load_store_instr[] = {});
+     riscv_instr instr_h;
+     int unsigned idx;
+     riscv_instr_name_t name;
+     if (load_store_instr.size() == 0) begin
+       load_store_instr = {instr_category[LOAD], instr_category[STORE]};
+     end
+     idx = $urandom_range(0, load_store_instr.size()-1);
+     name = load_store_instr[idx];
+     // Shallow copy for all relevant fields, avoid using create() to improve performance
+     instr_h = new instr_template[name];
+     return instr_h;
+  endfunction : get_load_store_instr
+
+  // Disable the rand mode for unused operands to randomization performance
+  virtual function void set_rand_mode();
+    case (format) inside
+      R_FORMAT : has_imm = 1'b0;
+      I_FORMAT : has_rs2 = 1'b0;
+      S_FORMAT, B_FORMAT : has_rd = 1'b0;
+      U_FORMAT, J_FORMAT : begin
+        has_rs1 = 1'b0;
+        has_rs2 = 1'b0;
+      end
+    endcase
+    if (category == CSR) begin
+      has_rs2 = 1'b0;
+      if (format == I_FORMAT) begin
+        has_rs1 = 1'b0;
+      end
+    end
+  endfunction
+
+  function void pre_randomize();
+    rs1.rand_mode(has_rs1);
+    rs2.rand_mode(has_rs2);
+    rd.rand_mode(has_rd);
+    imm.rand_mode(has_imm);
+    if (category != CSR) begin
+      csr.rand_mode(0);
+    end
+  endfunction
+
+  virtual function void set_imm_len();
+    if(format inside {U_FORMAT, J_FORMAT}) begin
+      imm_len = 20;
+    end else if(format inside {I_FORMAT, S_FORMAT, B_FORMAT}) begin
+      if(imm_type == UIMM) begin
+        imm_len = 5;
+      end else begin
+        imm_len = 11;
+      end
+    end
+    imm_mask = imm_mask << imm_len;
+  endfunction
+
+  virtual function void extend_imm();
+    bit sign;
+    imm = imm << (32 - imm_len);
+    sign = imm[31];
+    imm = imm >> (32 - imm_len);
+    // Signed extension
+    if (sign && !((format == U_FORMAT) || (imm_type inside {UIMM, NZUIMM}))) begin
+      imm = imm_mask | imm;
+    end
+  endfunction : extend_imm
+
+  function void post_randomize();
+    extend_imm();
+    update_imm_str();
+  endfunction : post_randomize
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    if(category != SYSTEM) begin
+      case(format)
+        J_FORMAT, U_FORMAT : // instr rd,imm
+          asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
+        I_FORMAT: // instr rd,rs1,imm
+          if(instr_name == NOP)
+            asm_str = "nop";
+          else if(instr_name == WFI)
+            asm_str = "wfi";
+          else if(instr_name == FENCE)
+            asm_str = $sformatf("fence"); // TODO: Support all fence combinations
+          else if(instr_name == FENCE_I)
+            asm_str = "fence.i";
+          else if(category == LOAD) // Use psuedo instruction format
+            asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rd.name(), get_imm(), rs1.name());
+          else if(category == CSR)
+            asm_str = $sformatf("%0s%0s, 0x%0x, %0s", asm_str, rd.name(), csr, get_imm());
+          else
+            asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), rs1.name(), get_imm());
+        S_FORMAT, B_FORMAT: // instr rs1,rs2,imm
+          if(category == STORE) // Use psuedo instruction format
+            asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rs2.name(), get_imm(), rs1.name());
+          else
+            asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rs1.name(), rs2.name(), get_imm());
+        R_FORMAT: // instr rd,rs1,rs2
+          if(category == CSR) begin
+            asm_str = $sformatf("%0s%0s, 0x%0x, %0s", asm_str, rd.name(), csr, rs1.name());
+          end else if(instr_name == SFENCE_VMA) begin
+            asm_str = "sfence.vma x0, x0"; // TODO: Support all possible sfence
+          end else begin
+            asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
+          end
+      endcase
+    end else begin
+      // For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
+      // This is needed to resume execution from epc+4 after ebreak handling
+      if(instr_name == EBREAK) begin
+        asm_str = ".4byte 0x00100073 # ebreak";
+      end
+    end
+    if(comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction
+
+  function bit [6:0] get_opcode();
+    case (instr_name) inside
+      LUI                                                          : get_opcode = 7'b0110111;
+      AUIPC                                                        : get_opcode = 7'b0010111;
+      JAL                                                          : get_opcode = 7'b1101111;
+      JALR                                                         : get_opcode = 7'b1100111;
+      BEQ, BNE, BLT, BGE, BLTU, BGEU                               : get_opcode = 7'b1100011;
+      LB, LH, LW, LBU, LHU, LWU, LD                                : get_opcode = 7'b0000011;
+      SB, SH, SW, SD                                               : get_opcode = 7'b0100011;
+      ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI, NOP    : get_opcode = 7'b0010011;
+      ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND, MUL,
+      MULH, MULHSU, MULHU, DIV, DIVU, REM, REMU                    : get_opcode = 7'b0110011;
+      ADDIW, SLLIW, SRLIW, SRAIW                                   : get_opcode = 7'b0011011;
+      MULH, MULHSU, MULHU, DIV, DIVU, REM, REMU                    : get_opcode = 7'b0110011;
+      FENCE, FENCE_I                                               : get_opcode = 7'b0001111;
+      ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI   : get_opcode = 7'b1110011;
+      ADDW, SUBW, SLLW, SRLW, SRAW, MULW, DIVW, DIVUW, REMW, REMUW : get_opcode = 7'b0111011;
+      ECALL, EBREAK, URET, SRET, MRET, DRET, WFI, SFENCE_VMA       : get_opcode = 7'b1110011;
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+  endfunction
+
+  virtual function bit [2:0] get_func3();
+    case (instr_name) inside
+      JALR       : get_func3 = 3'b000;
+      BEQ        : get_func3 = 3'b000;
+      BNE        : get_func3 = 3'b001;
+      BLT        : get_func3 = 3'b100;
+      BGE        : get_func3 = 3'b101;
+      BLTU       : get_func3 = 3'b110;
+      BGEU       : get_func3 = 3'b111;
+      LB         : get_func3 = 3'b000;
+      LH         : get_func3 = 3'b001;
+      LW         : get_func3 = 3'b010;
+      LBU        : get_func3 = 3'b100;
+      LHU        : get_func3 = 3'b101;
+      SB         : get_func3 = 3'b000;
+      SH         : get_func3 = 3'b001;
+      SW         : get_func3 = 3'b010;
+      ADDI       : get_func3 = 3'b000;
+      NOP        : get_func3 = 3'b000;
+      SLTI       : get_func3 = 3'b010;
+      SLTIU      : get_func3 = 3'b011;
+      XORI       : get_func3 = 3'b100;
+      ORI        : get_func3 = 3'b110;
+      ANDI       : get_func3 = 3'b111;
+      SLLI       : get_func3 = 3'b001;
+      SRLI       : get_func3 = 3'b101;
+      SRAI       : get_func3 = 3'b101;
+      ADD        : get_func3 = 3'b000;
+      SUB        : get_func3 = 3'b000;
+      SLL        : get_func3 = 3'b001;
+      SLT        : get_func3 = 3'b010;
+      SLTU       : get_func3 = 3'b011;
+      XOR        : get_func3 = 3'b100;
+      SRL        : get_func3 = 3'b101;
+      SRA        : get_func3 = 3'b101;
+      OR         : get_func3 = 3'b110;
+      AND        : get_func3 = 3'b111;
+      FENCE      : get_func3 = 3'b000;
+      FENCE_I    : get_func3 = 3'b001;
+      ECALL      : get_func3 = 3'b000;
+      EBREAK     : get_func3 = 3'b000;
+      CSRRW      : get_func3 = 3'b001;
+      CSRRS      : get_func3 = 3'b010;
+      CSRRC      : get_func3 = 3'b011;
+      CSRRWI     : get_func3 = 3'b101;
+      CSRRSI     : get_func3 = 3'b110;
+      CSRRCI     : get_func3 = 3'b111;
+      LWU        : get_func3 = 3'b110;
+      LD         : get_func3 = 3'b011;
+      SD         : get_func3 = 3'b011;
+      ADDIW      : get_func3 = 3'b000;
+      SLLIW      : get_func3 = 3'b001;
+      SRLIW      : get_func3 = 3'b101;
+      SRAIW      : get_func3 = 3'b101;
+      ADDW       : get_func3 = 3'b000;
+      SUBW       : get_func3 = 3'b000;
+      SLLW       : get_func3 = 3'b001;
+      SRLW       : get_func3 = 3'b101;
+      SRAW       : get_func3 = 3'b101;
+      MUL        : get_func3 = 3'b000;
+      MULH       : get_func3 = 3'b001;
+      MULHSU     : get_func3 = 3'b010;
+      MULHU      : get_func3 = 3'b011;
+      DIV        : get_func3 = 3'b100;
+      DIVU       : get_func3 = 3'b101;
+      REM        : get_func3 = 3'b110;
+      REMU       : get_func3 = 3'b111;
+      MULW       : get_func3 = 3'b000;
+      DIVW       : get_func3 = 3'b100;
+      DIVUW      : get_func3 = 3'b101;
+      REMW       : get_func3 = 3'b110;
+      REMUW      : get_func3 = 3'b111;
+      ECALL, EBREAK, URET, SRET, MRET, DRET, WFI, SFENCE_VMA : get_func3 = 3'b000;
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+  endfunction
+
+  function bit [6:0] get_func7();
+    case (instr_name)
+      SLLI   : get_func7 = 7'b0000000;
+      SRLI   : get_func7 = 7'b0000000;
+      SRAI   : get_func7 = 7'b0100000;
+      ADD    : get_func7 = 7'b0000000;
+      SUB    : get_func7 = 7'b0100000;
+      SLL    : get_func7 = 7'b0000000;
+      SLT    : get_func7 = 7'b0000000;
+      SLTU   : get_func7 = 7'b0000000;
+      XOR    : get_func7 = 7'b0000000;
+      SRL    : get_func7 = 7'b0000000;
+      SRA    : get_func7 = 7'b0100000;
+      OR     : get_func7 = 7'b0000000;
+      AND    : get_func7 = 7'b0000000;
+      FENCE  : get_func7 = 7'b0000000;
+      FENCE_I : get_func7 = 7'b0000000;
+      SLLIW  : get_func7 = 7'b0000000;
+      SRLIW  : get_func7 = 7'b0000000;
+      SRAIW  : get_func7 = 7'b0100000;
+      ADDW   : get_func7 = 7'b0000000;
+      SUBW   : get_func7 = 7'b0100000;
+      SLLW   : get_func7 = 7'b0000000;
+      SRLW   : get_func7 = 7'b0000000;
+      SRAW   : get_func7 = 7'b0100000;
+      MUL    : get_func7 = 7'b0000001;
+      MULH   : get_func7 = 7'b0000001;
+      MULHSU : get_func7 = 7'b0000001;
+      MULHU  : get_func7 = 7'b0000001;
+      DIV    : get_func7 = 7'b0000001;
+      DIVU   : get_func7 = 7'b0000001;
+      REM    : get_func7 = 7'b0000001;
+      REMU   : get_func7 = 7'b0000001;
+      MULW   : get_func7 = 7'b0000001;
+      DIVW   : get_func7 = 7'b0000001;
+      DIVUW  : get_func7 = 7'b0000001;
+      REMW   : get_func7 = 7'b0000001;
+      REMUW  : get_func7 = 7'b0000001;
+      ECALL  : get_func7 = 7'b0000000;
+      EBREAK : get_func7 = 7'b0000000;
+      URET   : get_func7 = 7'b0000000;
+      SRET   : get_func7 = 7'b0001000;
+      MRET   : get_func7 = 7'b0011000;
+      DRET   : get_func7 = 7'b0111101;
+      WFI    : get_func7 = 7'b0001000;
+      SFENCE_VMA: get_func7 = 7'b0001001;
+      default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
+    endcase
+  endfunction
+
+  // Convert the instruction to assembly code
+  virtual function string convert2bin(string prefix = "");
+    string binary;
+    case(format)
+      J_FORMAT: begin
+          binary = $sformatf("%8h", {imm[20], imm[10:1], imm[11], imm[19:12], rd,  get_opcode()});
+      end
+      U_FORMAT: begin
+          binary = $sformatf("%8h", {imm[31:12], rd,  get_opcode()});
+      end
+      I_FORMAT: begin
+        if(instr_name inside {FENCE, FENCE_I})
+          binary = $sformatf("%8h", {17'b0, get_func3(), 5'b0, get_opcode()});
+        else if(category == CSR)
+          binary = $sformatf("%8h", {csr[10:0], imm[4:0], get_func3(), rd, get_opcode()});
+        else if(instr_name == ECALL)
+          binary = $sformatf("%8h", {get_func7(), 18'b0, get_opcode()});
+        else if(instr_name inside {URET, SRET, MRET})
+          binary = $sformatf("%8h", {get_func7(), 5'b10, 13'b0, get_opcode()});
+        else if(instr_name inside {DRET})
+          binary = $sformatf("%8h", {get_func7(), 5'b10010, 13'b0, get_opcode()});
+        else if(instr_name == EBREAK)
+          binary = $sformatf("%8h", {get_func7(), 5'b01, 13'b0, get_opcode()});
+        else if(instr_name == WFI)
+          binary = $sformatf("%8h", {get_func7(), 5'b101, 13'b0, get_opcode()});
+        else
+          binary = $sformatf("%8h", {imm[11:0], rs1, get_func3(), rd, get_opcode()});
+      end
+      S_FORMAT: begin
+          binary = $sformatf("%8h", {imm[11:5], rs2, rs1, get_func3(), imm[4:0], get_opcode()});
+      end
+      B_FORMAT: begin
+          binary = $sformatf("%8h",
+                             {imm[12], imm[10:5], rs2, rs1, get_func3(),
+                              imm[4:1], imm[11], get_opcode()});
+      end
+      R_FORMAT: begin
+        if(category == CSR)
+          binary = $sformatf("%8h", {csr[10:0], rs1, get_func3(), rd, get_opcode()});
+        else if(instr_name == SFENCE_VMA)
+          binary = $sformatf("%8h", {get_func7(), 18'b0, get_opcode()});
+        else
+          binary = $sformatf("%8h", {get_func7(), rs2, rs1, get_func3(), rd, get_opcode()});
+      end
+    endcase
+    return {prefix, binary};
+  endfunction
+
+  virtual function string get_instr_name();
+    get_instr_name = instr_name.name();
+    foreach(get_instr_name[i]) begin
+      if (get_instr_name[i] == "_") begin
+        get_instr_name[i] = ".";
+      end
+    end
+    return get_instr_name;
+  endfunction
+
+  // Get RVC register name for CIW, CL, CS, CB format
+  function bit [2:0] get_c_gpr(riscv_reg_t gpr);
+    return gpr[2:0];
+  endfunction
+
+  // Default return imm value directly, can be overriden to use labels and symbols
+  // Example: %hi(symbol), %pc_rel(label) ...
+  virtual function string get_imm();
+    return imm_str;
+  endfunction
+
+  virtual function void clear_unused_label();
+    if(has_label && !is_branch_target && is_local_numeric_label) begin
+      has_label = 1'b0;
+    end
+  endfunction
+
+  virtual function void do_copy(uvm_object rhs);
+    riscv_instr rhs_;
+    super.copy(rhs);
+    assert($cast(rhs_, rhs));
+    this.group          = rhs_.group;
+    this.format         = rhs_.format;
+    this.category       = rhs_.category;
+    this.instr_name     = rhs_.instr_name;
+    this.rs2            = rhs_.rs2;
+    this.rs1            = rhs_.rs1;
+    this.rd             = rhs_.rd;
+    this.imm            = rhs_.imm;
+    this.imm_type       = rhs_.imm_type;
+    this.imm_len        = rhs_.imm_len;
+    this.imm_mask       = rhs_.imm_mask;
+    this.imm_str        = rhs_.imm_str;
+    this.imm_mask       = rhs_.imm_mask;
+    this.is_compressed  = rhs_.is_compressed;
+    this.has_rs2        = rhs_.has_rs2;
+    this.has_rs1        = rhs_.has_rs1;
+    this.has_rd         = rhs_.has_rd;
+    this.has_imm        = rhs_.has_imm;
+  endfunction : do_copy
+
+  virtual function void update_imm_str();
+    imm_str = $sformatf("%0d", $signed(imm));
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
new file mode 100644
index 00000000..fba526fe
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
@@ -0,0 +1,25 @@
+class riscv_vector_instr extends riscv_instr;
+
+  // TODO : Add vector instruction operands here
+
+  `uvm_object_utils(riscv_vector_instr)
+
+  function new(string name = "");
+    super.new(name);
+  endfunction
+
+  virtual function string get_instr_name();
+    // TODO : Implement this function for vector instructions
+  endfunction
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    // TODO : Implement this function for vector instructions
+    if(comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/isa/rv128c_instr.sv b/vendor/google_riscv-dv/src/isa/rv128c_instr.sv
new file mode 100644
index 00000000..30af2ea5
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv128c_instr.sv
@@ -0,0 +1,7 @@
+`DEFINE_C_INSTR(C_SRLI64, CB_FORMAT, SHIFT, RV128C, NZUIMM)
+`DEFINE_C_INSTR(C_SRAI64, CB_FORMAT, SHIFT, RV128C, NZUIMM)
+`DEFINE_C_INSTR(C_SLLI64, CI_FORMAT, SHIFT, RV128C, NZUIMM)
+`DEFINE_C_INSTR(C_LQ,     CL_FORMAT, LOAD, RV32DC, UIMM)
+`DEFINE_C_INSTR(C_SQ,     CS_FORMAT, STORE, RV32DC, UIMM)
+`DEFINE_C_INSTR(C_LQSP,   CI_FORMAT, LOAD, RV32DC, UIMM)
+`DEFINE_C_INSTR(C_SQSP,   CSS_FORMAT, STORE, RV32DC, UIMM)
diff --git a/vendor/google_riscv-dv/src/isa/rv32a_instr.sv b/vendor/google_riscv-dv/src/isa/rv32a_instr.sv
new file mode 100644
index 00000000..c5374100
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32a_instr.sv
@@ -0,0 +1,11 @@
+`DEFINE_AMO_INSTR(LR_W,      R_FORMAT, LOAD, RV32A)
+`DEFINE_AMO_INSTR(SC_W,      R_FORMAT, STORE, RV32A)
+`DEFINE_AMO_INSTR(AMOSWAP_W, R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOADD_W,  R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOAND_W,  R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOOR_W,   R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOXOR_W,  R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOMIN_W,  R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOMAX_W,  R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOMINU_W, R_FORMAT, AMO, RV32A)
+`DEFINE_AMO_INSTR(AMOMAXU_W, R_FORMAT, AMO, RV32A)
diff --git a/vendor/google_riscv-dv/src/isa/rv32c_instr.sv b/vendor/google_riscv-dv/src/isa/rv32c_instr.sv
new file mode 100644
index 00000000..c2df949a
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32c_instr.sv
@@ -0,0 +1,27 @@
+`DEFINE_C_INSTR(C_LW,       CL_FORMAT, LOAD, RV32C, UIMM)
+`DEFINE_C_INSTR(C_SW,       CS_FORMAT, STORE, RV32C, UIMM)
+`DEFINE_C_INSTR(C_LWSP,     CI_FORMAT, LOAD, RV32C, UIMM)
+`DEFINE_C_INSTR(C_SWSP,     CSS_FORMAT, STORE, RV32C, UIMM)
+`DEFINE_C_INSTR(C_ADDI4SPN, CIW_FORMAT, ARITHMETIC, RV32C, NZUIMM)
+`DEFINE_C_INSTR(C_ADDI,     CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
+`DEFINE_C_INSTR(C_ADDI16SP, CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
+`DEFINE_C_INSTR(C_LI,       CI_FORMAT, ARITHMETIC, RV32C)
+`DEFINE_C_INSTR(C_LUI,      CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
+`DEFINE_C_INSTR(C_SUB,      CA_FORMAT, ARITHMETIC, RV32C)
+`DEFINE_C_INSTR(C_ADD,      CR_FORMAT, ARITHMETIC, RV32C)
+`DEFINE_C_INSTR(C_NOP,      CI_FORMAT, ARITHMETIC, RV32C)
+`DEFINE_C_INSTR(C_MV,       CR_FORMAT, ARITHMETIC, RV32C)
+`DEFINE_C_INSTR(C_ANDI,     CB_FORMAT, LOGICAL, RV32C)
+`DEFINE_C_INSTR(C_XOR,      CA_FORMAT, LOGICAL, RV32C)
+`DEFINE_C_INSTR(C_OR,       CA_FORMAT, LOGICAL, RV32C)
+`DEFINE_C_INSTR(C_AND,      CA_FORMAT, LOGICAL, RV32C)
+`DEFINE_C_INSTR(C_BEQZ,     CB_FORMAT, BRANCH, RV32C)
+`DEFINE_C_INSTR(C_BNEZ,     CB_FORMAT, BRANCH, RV32C)
+`DEFINE_C_INSTR(C_SRLI,     CB_FORMAT, SHIFT, RV32C, NZUIMM)
+`DEFINE_C_INSTR(C_SRAI,     CB_FORMAT, SHIFT, RV32C, NZUIMM)
+`DEFINE_C_INSTR(C_SLLI,     CI_FORMAT, SHIFT, RV32C, NZUIMM)
+`DEFINE_C_INSTR(C_J,        CJ_FORMAT, JUMP, RV32C)
+`DEFINE_C_INSTR(C_JAL,      CJ_FORMAT, JUMP, RV32C)
+`DEFINE_C_INSTR(C_JR,       CR_FORMAT, JUMP, RV32C)
+`DEFINE_C_INSTR(C_JALR,     CR_FORMAT, JUMP, RV32C)
+`DEFINE_C_INSTR(C_EBREAK,   CI_FORMAT, SYSTEM, RV32C)
diff --git a/vendor/google_riscv-dv/src/isa/rv32d_instr.sv b/vendor/google_riscv-dv/src/isa/rv32d_instr.sv
new file mode 100644
index 00000000..dc53a262
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32d_instr.sv
@@ -0,0 +1,26 @@
+`DEFINE_FP_INSTR(FLD,       I_FORMAT, LOAD, RV32D)
+`DEFINE_FP_INSTR(FSD,       S_FORMAT, STORE, RV32D)
+`DEFINE_FP_INSTR(FMADD_D,   R4_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FMSUB_D,   R4_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FNMSUB_D,  R4_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FNMADD_D,  R4_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FADD_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FSUB_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FMUL_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FDIV_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FSQRT_D,   I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FSGNJ_D,   R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FSGNJN_D,  R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FSGNJX_D,  R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FMIN_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FMAX_D,    R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_S_D,  I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_D_S,  I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FEQ_D,     R_FORMAT, COMPARE, RV32D)
+`DEFINE_FP_INSTR(FLT_D,     R_FORMAT, COMPARE, RV32D)
+`DEFINE_FP_INSTR(FLE_D,     R_FORMAT, COMPARE, RV32D)
+`DEFINE_FP_INSTR(FCLASS_D,  R_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_W_D,  I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_WU_D, I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_D_W,  I_FORMAT, ARITHMETIC, RV32D)
+`DEFINE_FP_INSTR(FCVT_D_WU, I_FORMAT, ARITHMETIC, RV32D)
diff --git a/vendor/google_riscv-dv/src/isa/rv32dc_instr.sv b/vendor/google_riscv-dv/src/isa/rv32dc_instr.sv
new file mode 100644
index 00000000..e93116fd
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32dc_instr.sv
@@ -0,0 +1,4 @@
+`DEFINE_FC_INSTR(C_FLD,   CL_FORMAT, LOAD, RV32DC, UIMM)
+`DEFINE_FC_INSTR(C_FSD,   CS_FORMAT, STORE, RV32DC, UIMM)
+`DEFINE_FC_INSTR(C_FLDSP, CI_FORMAT, LOAD, RV32DC, UIMM)
+`DEFINE_FC_INSTR(C_FSDSP, CSS_FORMAT, STORE, RV32DC, UIMM)
diff --git a/vendor/google_riscv-dv/src/isa/rv32f_instr.sv b/vendor/google_riscv-dv/src/isa/rv32f_instr.sv
new file mode 100644
index 00000000..ee2ebd90
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32f_instr.sv
@@ -0,0 +1,26 @@
+`DEFINE_FP_INSTR(FLW,       I_FORMAT, LOAD, RV32F)
+`DEFINE_FP_INSTR(FSW,       S_FORMAT, STORE, RV32F)
+`DEFINE_FP_INSTR(FMADD_S,   R4_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMSUB_S,   R4_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FNMSUB_S,  R4_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FNMADD_S,  R4_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FADD_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FSUB_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMUL_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FDIV_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FSQRT_S,   I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FSGNJ_S,   R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FSGNJN_S,  R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FSGNJX_S,  R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMIN_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMAX_S,    R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FCVT_W_S,  I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FCVT_WU_S, I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMV_X_W,   I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FEQ_S,     R_FORMAT, COMPARE, RV32F)
+`DEFINE_FP_INSTR(FLT_S,     R_FORMAT, COMPARE, RV32F)
+`DEFINE_FP_INSTR(FLE_S,     R_FORMAT, COMPARE, RV32F)
+`DEFINE_FP_INSTR(FCLASS_S,  R_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FCVT_S_W,  I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FCVT_S_WU, I_FORMAT, ARITHMETIC, RV32F)
+`DEFINE_FP_INSTR(FMV_W_X,   I_FORMAT, ARITHMETIC, RV32F)
diff --git a/vendor/google_riscv-dv/src/isa/rv32fc_instr.sv b/vendor/google_riscv-dv/src/isa/rv32fc_instr.sv
new file mode 100644
index 00000000..04d5d1bd
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32fc_instr.sv
@@ -0,0 +1,4 @@
+`DEFINE_FC_INSTR(C_FLW,   CL_FORMAT, LOAD, RV32FC, UIMM)
+`DEFINE_FC_INSTR(C_FSW,   CS_FORMAT, STORE, RV32FC, UIMM)
+`DEFINE_FC_INSTR(C_FLWSP, CI_FORMAT, LOAD, RV32FC, UIMM)
+`DEFINE_FC_INSTR(C_FSWSP, CSS_FORMAT, STORE, RV32FC, UIMM)
diff --git a/vendor/google_riscv-dv/src/isa/rv32i_instr.sv b/vendor/google_riscv-dv/src/isa/rv32i_instr.sv
new file mode 100644
index 00000000..55b2e688
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32i_instr.sv
@@ -0,0 +1,65 @@
+// LOAD instructions
+`DEFINE_INSTR(LB,     I_FORMAT, LOAD, RV32I)
+`DEFINE_INSTR(LH,     I_FORMAT, LOAD, RV32I)
+`DEFINE_INSTR(LW,     I_FORMAT, LOAD, RV32I)
+`DEFINE_INSTR(LBU,    I_FORMAT, LOAD, RV32I)
+`DEFINE_INSTR(LHU,    I_FORMAT, LOAD, RV32I)
+// STORE instructions
+`DEFINE_INSTR(SB,     S_FORMAT, STORE, RV32I)
+`DEFINE_INSTR(SH,     S_FORMAT, STORE, RV32I)
+`DEFINE_INSTR(SW,     S_FORMAT, STORE, RV32I)
+// SHIFT intructions
+`DEFINE_INSTR(SLL,    R_FORMAT, SHIFT, RV32I)
+`DEFINE_INSTR(SLLI,   I_FORMAT, SHIFT, RV32I)
+`DEFINE_INSTR(SRL,    R_FORMAT, SHIFT, RV32I)
+`DEFINE_INSTR(SRLI,   I_FORMAT, SHIFT, RV32I)
+`DEFINE_INSTR(SRA,    R_FORMAT, SHIFT, RV32I)
+`DEFINE_INSTR(SRAI,   I_FORMAT, SHIFT, RV32I)
+// ARITHMETIC intructions
+`DEFINE_INSTR(ADD,    R_FORMAT, ARITHMETIC, RV32I)
+`DEFINE_INSTR(ADDI,   I_FORMAT, ARITHMETIC, RV32I)
+`DEFINE_INSTR(NOP,    I_FORMAT, ARITHMETIC, RV32I)
+`DEFINE_INSTR(SUB,    R_FORMAT, ARITHMETIC, RV32I)
+`DEFINE_INSTR(LUI,    U_FORMAT, ARITHMETIC, RV32I, UIMM)
+`DEFINE_INSTR(AUIPC,  U_FORMAT, ARITHMETIC, RV32I, UIMM)
+// LOGICAL instructions
+`DEFINE_INSTR(XOR,    R_FORMAT, LOGICAL, RV32I)
+`DEFINE_INSTR(XORI,   I_FORMAT, LOGICAL, RV32I)
+`DEFINE_INSTR(OR,     R_FORMAT, LOGICAL, RV32I)
+`DEFINE_INSTR(ORI,    I_FORMAT, LOGICAL, RV32I)
+`DEFINE_INSTR(AND,    R_FORMAT, LOGICAL, RV32I)
+`DEFINE_INSTR(ANDI,   I_FORMAT, LOGICAL, RV32I)
+// COMPARE instructions
+`DEFINE_INSTR(SLT,    R_FORMAT, COMPARE, RV32I)
+`DEFINE_INSTR(SLTI,   I_FORMAT, COMPARE, RV32I)
+`DEFINE_INSTR(SLTU,   R_FORMAT, COMPARE, RV32I)
+`DEFINE_INSTR(SLTIU,  I_FORMAT, COMPARE, RV32I)
+// BRANCH instructions
+`DEFINE_INSTR(BEQ,    B_FORMAT, BRANCH, RV32I)
+`DEFINE_INSTR(BNE,    B_FORMAT, BRANCH, RV32I)
+`DEFINE_INSTR(BLT,    B_FORMAT, BRANCH, RV32I)
+`DEFINE_INSTR(BGE,    B_FORMAT, BRANCH, RV32I)
+`DEFINE_INSTR(BLTU,   B_FORMAT, BRANCH, RV32I)
+`DEFINE_INSTR(BGEU,   B_FORMAT, BRANCH, RV32I)
+// JUMP instructions
+`DEFINE_INSTR(JAL,    J_FORMAT, JUMP, RV32I)
+`DEFINE_INSTR(JALR,   I_FORMAT, JUMP, RV32I)
+// SYNCH instructions
+`DEFINE_INSTR(FENCE,  I_FORMAT, SYNCH, RV32I)
+`DEFINE_INSTR(FENCE_I, I_FORMAT, SYNCH, RV32I)
+`DEFINE_INSTR(SFENCE_VMA, R_FORMAT, SYNCH, RV32I)
+// SYSTEM instructions
+`DEFINE_INSTR(ECALL,   I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(EBREAK,  I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(URET,    I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(SRET,    I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(MRET,    I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(DRET,    I_FORMAT, SYSTEM, RV32I)
+`DEFINE_INSTR(WFI,     I_FORMAT, INTERRUPT, RV32I)
+// CSR instructions
+`DEFINE_INSTR(CSRRW,  R_FORMAT, CSR, RV32I, UIMM)
+`DEFINE_INSTR(CSRRS,  R_FORMAT, CSR, RV32I, UIMM)
+`DEFINE_INSTR(CSRRC,  R_FORMAT, CSR, RV32I, UIMM)
+`DEFINE_INSTR(CSRRWI, I_FORMAT, CSR, RV32I, UIMM)
+`DEFINE_INSTR(CSRRSI, I_FORMAT, CSR, RV32I, UIMM)
+`DEFINE_INSTR(CSRRCI, I_FORMAT, CSR, RV32I, UIMM)
diff --git a/vendor/google_riscv-dv/src/isa/rv32m_instr.sv b/vendor/google_riscv-dv/src/isa/rv32m_instr.sv
new file mode 100644
index 00000000..16765b6b
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv32m_instr.sv
@@ -0,0 +1,9 @@
+////////////  RV32M instructions  //////////////
+`DEFINE_INSTR(MUL,    R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(MULH,   R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(MULHSU, R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(MULHU,  R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(DIV,    R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(DIVU,   R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(REM,    R_FORMAT, ARITHMETIC, RV32M)
+`DEFINE_INSTR(REMU,   R_FORMAT, ARITHMETIC, RV32M)
diff --git a/vendor/google_riscv-dv/src/isa/rv64a_instr.sv b/vendor/google_riscv-dv/src/isa/rv64a_instr.sv
new file mode 100644
index 00000000..4e1e3985
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64a_instr.sv
@@ -0,0 +1,11 @@
+`DEFINE_AMO_INSTR(LR_D,      R_FORMAT, LOAD, RV64A)
+`DEFINE_AMO_INSTR(SC_D,      R_FORMAT, STORE, RV64A)
+`DEFINE_AMO_INSTR(AMOSWAP_D, R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOADD_D,  R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOAND_D,  R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOOR_D,   R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOXOR_D,  R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOMIN_D,  R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOMAX_D,  R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOMINU_D, R_FORMAT, AMO, RV64A)
+`DEFINE_AMO_INSTR(AMOMAXU_D, R_FORMAT, AMO, RV64A)
diff --git a/vendor/google_riscv-dv/src/isa/rv64c_instr.sv b/vendor/google_riscv-dv/src/isa/rv64c_instr.sv
new file mode 100644
index 00000000..cf9e2826
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64c_instr.sv
@@ -0,0 +1,7 @@
+`DEFINE_C_INSTR(C_ADDIW,  CI_FORMAT, ARITHMETIC, RV64C)
+`DEFINE_C_INSTR(C_SUBW,   CA_FORMAT, ARITHMETIC, RV64C)
+`DEFINE_C_INSTR(C_ADDW,   CA_FORMAT, ARITHMETIC, RV64C)
+`DEFINE_C_INSTR(C_LD,     CL_FORMAT, LOAD, RV64C, UIMM)
+`DEFINE_C_INSTR(C_SD,     CS_FORMAT, STORE, RV64C, UIMM)
+`DEFINE_C_INSTR(C_LDSP,   CI_FORMAT, LOAD, RV64C, UIMM)
+`DEFINE_C_INSTR(C_SDSP,   CSS_FORMAT, STORE, RV64C, UIMM)
diff --git a/vendor/google_riscv-dv/src/isa/rv64d_instr.sv b/vendor/google_riscv-dv/src/isa/rv64d_instr.sv
new file mode 100644
index 00000000..2c0f86ed
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64d_instr.sv
@@ -0,0 +1,6 @@
+`DEFINE_FP_INSTR(FMV_X_D,   I_FORMAT, ARITHMETIC, RV64D)
+`DEFINE_FP_INSTR(FMV_D_X,   I_FORMAT, ARITHMETIC, RV64D)
+`DEFINE_FP_INSTR(FCVT_L_D,  I_FORMAT, ARITHMETIC, RV64D)
+`DEFINE_FP_INSTR(FCVT_LU_D, I_FORMAT, ARITHMETIC, RV64D)
+`DEFINE_FP_INSTR(FCVT_D_L,  I_FORMAT, ARITHMETIC, RV64D)
+`DEFINE_FP_INSTR(FCVT_D_LU, I_FORMAT, ARITHMETIC, RV64D)
diff --git a/vendor/google_riscv-dv/src/isa/rv64f_instr.sv b/vendor/google_riscv-dv/src/isa/rv64f_instr.sv
new file mode 100644
index 00000000..2ecab638
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64f_instr.sv
@@ -0,0 +1,4 @@
+`DEFINE_FP_INSTR(FCVT_L_S,  I_FORMAT, ARITHMETIC, RV64F)
+`DEFINE_FP_INSTR(FCVT_LU_S, I_FORMAT, ARITHMETIC, RV64F)
+`DEFINE_FP_INSTR(FCVT_S_L,  I_FORMAT, ARITHMETIC, RV64F)
+`DEFINE_FP_INSTR(FCVT_S_LU, I_FORMAT, ARITHMETIC, RV64F)
diff --git a/vendor/google_riscv-dv/src/isa/rv64i_instr.sv b/vendor/google_riscv-dv/src/isa/rv64i_instr.sv
new file mode 100644
index 00000000..4e94c1eb
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64i_instr.sv
@@ -0,0 +1,14 @@
+`DEFINE_INSTR(LWU,     I_FORMAT, LOAD, RV64I)
+`DEFINE_INSTR(LD,      I_FORMAT, LOAD, RV64I)
+`DEFINE_INSTR(SD,      S_FORMAT, STORE, RV64I)
+// SHIFT intructions
+`DEFINE_INSTR(SLLW,    R_FORMAT, SHIFT, RV64I)
+`DEFINE_INSTR(SLLIW,   I_FORMAT, SHIFT, RV64I)
+`DEFINE_INSTR(SRLW,    R_FORMAT, SHIFT, RV64I)
+`DEFINE_INSTR(SRLIW,   I_FORMAT, SHIFT, RV64I)
+`DEFINE_INSTR(SRAW,    R_FORMAT, SHIFT, RV64I)
+`DEFINE_INSTR(SRAIW,   I_FORMAT, SHIFT, RV64I)
+// ARITHMETIC intructions
+`DEFINE_INSTR(ADDW,    R_FORMAT, ARITHMETIC, RV64I)
+`DEFINE_INSTR(ADDIW,   I_FORMAT, ARITHMETIC, RV64I)
+`DEFINE_INSTR(SUBW,    R_FORMAT, ARITHMETIC, RV64I)
diff --git a/vendor/google_riscv-dv/src/isa/rv64m_instr.sv b/vendor/google_riscv-dv/src/isa/rv64m_instr.sv
new file mode 100644
index 00000000..126f9842
--- /dev/null
+++ b/vendor/google_riscv-dv/src/isa/rv64m_instr.sv
@@ -0,0 +1,5 @@
+`DEFINE_INSTR(MULW,   R_FORMAT, ARITHMETIC, RV64M)
+`DEFINE_INSTR(DIVW,   R_FORMAT, ARITHMETIC, RV64M)
+`DEFINE_INSTR(DIVUW,  R_FORMAT, ARITHMETIC, RV64M)
+`DEFINE_INSTR(REMW,   R_FORMAT, ARITHMETIC, RV64M)
+`DEFINE_INSTR(REMUW,  R_FORMAT, ARITHMETIC, RV64M)
diff --git a/vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv
index ba60035f..9dda45df 100644
--- a/vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv
+++ b/vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv
@@ -65,13 +65,13 @@ class riscv_amo_base_instr_stream extends riscv_mem_access_stream;
   virtual function void gen_amo_instr();
   endfunction
 
-endclass
+endclass : riscv_amo_base_instr_stream
 
 // A pair of LR/SC instruction
 class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
 
-  riscv_rand_instr lr_instr;
-  riscv_rand_instr sc_instr;
+  riscv_instr lr_instr;
+  riscv_instr sc_instr;
 
   constraint legal_c {
     num_amo == 1;
@@ -82,32 +82,40 @@ class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
 
   function new(string name = "");
     super.new(name);
-    lr_instr = riscv_rand_instr::type_id::create("lr_instr");
-    sc_instr = riscv_rand_instr::type_id::create("sc_instr");
   endfunction
 
   virtual function void gen_amo_instr();
-    lr_instr.cfg = cfg;
-    sc_instr.cfg = cfg;
-    lr_instr.disable_a_extension_c.constraint_mode(0);
-    sc_instr.disable_a_extension_c.constraint_mode(0);
+    lr_instr = riscv_instr::get_rand_instr(.include_instr({LR_W, LR_D}));
+    sc_instr = riscv_instr::get_rand_instr(.include_instr({SC_W, SC_D}));
     `DV_CHECK_RANDOMIZE_WITH_FATAL(lr_instr,
-                                   rs1 == rs1_reg;
-                                   rd != rs1_reg;
-                                   instr_name inside {LR_W, LR_D};)
+      rs1 == rs1_reg;
+      if (reserved_rd.size() > 0) {
+        !(rd inside {reserved_rd});
+      }
+      if (cfg.reserved_regs.size() > 0) {
+        !(rd inside {cfg.reserved_regs});
+      }
+      rd != rs1_reg;
+    )
     `DV_CHECK_RANDOMIZE_WITH_FATAL(sc_instr,
-                                   rs1 == rs1_reg;
-                                   rd != rs1_reg;
-                                   instr_name inside {SC_W, SC_D};)
-    instr_list.push_front(lr_instr);
-    instr_list.push_front(sc_instr);
+      rs1 == rs1_reg;
+      if (reserved_rd.size() > 0) {
+        !(rd inside {reserved_rd});
+      }
+      if (cfg.reserved_regs.size() > 0) {
+        !(rd inside {cfg.reserved_regs});
+      }
+      rd != rs1_reg;
+    )
+    instr_list.push_back(lr_instr);
+    instr_list.push_back(sc_instr);
   endfunction
 
-endclass
+endclass : riscv_lr_sc_instr_stream
 
 class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
 
-  riscv_rand_instr amo_instr[];
+  riscv_instr amo_instr[];
 
   constraint reasonable_c {
     solve num_amo before num_mixed_instr;
@@ -121,22 +129,19 @@ class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
   virtual function void gen_amo_instr();
     amo_instr = new[num_amo];
     foreach (amo_instr[i]) begin
-      amo_instr[i] = riscv_rand_instr::type_id::create($sformatf("amo_instr_%0d", i));
-      amo_instr[i].cfg = cfg;
-      amo_instr[i].disable_a_extension_c.constraint_mode(0);
-      `ifdef DSIM
-        `DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
-                                       rs1 == rs1_reg;
-                                       rd != rs1_reg;
-                                       instr_name inside {[AMOSWAP_W:AMOMAXU_D]};)
-      `else
-        `DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
-                                       rs1 == rs1_reg;
-                                       rd != rs1_reg;
-                                       category == AMO;)
-      `endif
+      amo_instr[i] = riscv_instr::get_rand_instr(.include_category({AMO}));
+      `DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
+        if (reserved_rd.size() > 0) {
+          !(rd inside {reserved_rd});
+        }
+        if (cfg.reserved_regs.size() > 0) {
+          !(rd inside {cfg.reserved_regs});
+        }
+        rs1 == rs1_reg;
+        rd != rs1_reg;
+      )
       instr_list.push_front(amo_instr[i]);
     end
   endfunction
 
-endclass
+endclass : riscv_amo_instr_stream
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 ac68d128..f7d924cf 100644
--- a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
+++ b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
@@ -29,8 +29,7 @@ class riscv_asm_program_gen extends uvm_object;
    // User mode programs
    riscv_instr_sequence                main_program;
    riscv_instr_sequence                sub_program[];
-   riscv_instr_sequence                debug_program;
-   riscv_instr_sequence                debug_sub_program[];
+   riscv_asm_program_gen               debug_rom;
    // Kernel programs
    // These programs are called in the interrupt/exception handling routine based on the privileged
    // mode settings. For example, when the interrupt/exception is delegated to S-mode, if both SUM
@@ -110,9 +109,9 @@ class riscv_asm_program_gen extends uvm_object;
       // Privileged mode switch routine
       gen_privileged_mode_switch_routine();
       // Generate debug rom section
-      gen_debug_rom();
-      // Generate debug mode exception handler
-      gen_debug_exception_handler();
+      if (riscv_instr_pkg::support_debug_mode) begin
+        gen_debug_rom();
+      end
     end
     // Starting point of data section
     gen_data_page_begin();
@@ -340,7 +339,7 @@ class riscv_asm_program_gen extends uvm_object;
       init_floating_point_gpr();
     end
     core_is_initialized();
-    gen_dummy_csr_write();
+    gen_dummy_csr_write(); // TODO add a way to disable xStatus read
   endfunction
 
   // Setup MISA based on supported extensions
@@ -522,7 +521,7 @@ class riscv_asm_program_gen extends uvm_object;
       string instr[$];
       string csr_handshake[$];
       string ret_instr;
-      if(riscv_instr_pkg::supported_privileged_mode[i] < cfg.init_privileged_mode) continue;
+      if(riscv_instr_pkg::supported_privileged_mode[i] != cfg.init_privileged_mode) continue;
       `uvm_info(`gfn, $sformatf("Generating privileged mode routing for %0s",
                       riscv_instr_pkg::supported_privileged_mode[i].name()), UVM_LOW)
       // Enter privileged mode
@@ -668,8 +667,9 @@ class riscv_asm_program_gen extends uvm_object;
         SUPERVISOR_MODE:
           gen_trap_handler_section("s", SCAUSE, STVEC, STVAL, SEPC, SSCRATCH, SSTATUS, SIE, SIP);
         USER_MODE:
-          if(riscv_instr_pkg::support_umode_trap)
+          if(riscv_instr_pkg::support_umode_trap) begin
             gen_trap_handler_section("u", UCAUSE, UTVEC, UTVAL, UEPC, USCRATCH, USTATUS, UIE, UIP);
+          end
       endcase
     end
     // Ebreak handler
@@ -963,7 +963,8 @@ class riscv_asm_program_gen extends uvm_object;
     privileged_reg_t status, ip, ie, scratch;
     string interrupt_handler_instr[$];
     ls_unit = (XLEN == 32) ? "w" : "d";
-    if(mode < cfg.init_privileged_mode) return;
+    if (mode < cfg.init_privileged_mode) return;
+    if (mode == USER_MODE && !riscv_instr_pkg::support_umode_trap) return;
     case(mode)
       MACHINE_MODE: begin
         mode_prefix = "m";
@@ -1039,11 +1040,16 @@ class riscv_asm_program_gen extends uvm_object;
 
   // Dump performance CSRs if applicable
   virtual function void dump_perf_stats();
+    string perf_stats[$];
     foreach(implemented_csr[i]) begin
       if (implemented_csr[i] inside {[MCYCLE:MHPMCOUNTER31H]}) begin
-        gen_signature_handshake(.instr(instr_stream), .signature_type(WRITE_CSR), .csr(implemented_csr[i]));
+        gen_signature_handshake(.instr(perf_stats),
+                                .signature_type(WRITE_CSR),
+                                .csr(implemented_csr[i]));
       end
     end
+    format_section(perf_stats);
+    instr_stream = {instr_stream, perf_stats};
   endfunction
 
   // Write the generated program to a file
@@ -1215,208 +1221,15 @@ class riscv_asm_program_gen extends uvm_object;
   endfunction
 
   //---------------------------------------------------------------------------------------
-  // Generate the debug rom, and any related programs
-  // TODO - refactor such that debug_rom is generated by a separate class
+  // Generate the debug ROM, and any related programs
   //---------------------------------------------------------------------------------------
 
-  // Generate the program in the debug ROM
-  // Processor will fetch instruction from here upon receiving debug request from debug module
   virtual function void gen_debug_rom();
-    string instr[$];
-    string debug_end[$];
-    string dret;
-    string debug_sub_program_name[$] = {};
-    string str[$];
-    if (riscv_instr_pkg::support_debug_mode) begin
-      dret = {format_string(" ", LABEL_STR_LEN), "dret"};
-      // The main debug rom
-      if (!cfg.gen_debug_section) begin
-        // If the debug section should not be generated, we just populate it
-        // with a dret instruction.
-        instr = {dret};
-        gen_section("debug_rom", instr);
-      end else begin
-        if (cfg.enable_ebreak_in_debug_rom) begin
-          // As execution of ebreak in D mode causes core to
-          // re-enter D mode, this directed sequence will be a loop that ensures the
-          // ebreak instruction will only be executed once to prevent infinitely
-          // looping back to the beginning of the debug rom.
-          // Write dscratch to random GPR and branch to debug_end if greater
-          // than 0, for ebreak loops.
-          // Use dscratch1 to store original GPR value.
-          str = {$sformatf("csrw 0x%0x, x%0d", DSCRATCH1, cfg.scratch_reg),
-                 $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
-                 $sformatf("beq x%0d, x0, 1f", cfg.scratch_reg),
-                 $sformatf("j debug_end"),
-                 $sformatf("1: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
-          instr = {instr, str};
-        end
-        // Need to save off GPRs to avoid modifying program flow
-        push_gpr_to_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
-        // Signal that the core entered debug rom only if the rom is actually
-        // being filled with random instructions to prevent stress tests from
-        // having to execute unnecessary push/pop of GPRs on the stack ever
-        // time a debug request is sent
-        gen_signature_handshake(instr, CORE_STATUS, IN_DEBUG_MODE);
-        if (cfg.enable_ebreak_in_debug_rom) begin
-          // send dpc and dcsr to testbench, as this handshake will be
-          // executed twice due to the ebreak loop, there should be no change
-          // in their values as by the Debug Mode Spec Ch. 4.1.8
-          gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(DCSR));
-          gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(DPC));
-        end
-        if (cfg.set_dcsr_ebreak) begin
-          // We want to set dcsr.ebreak(m/s/u) to 1'b1, depending on what modes
-          // are available.
-          // TODO(udinator) - randomize the dcsr.ebreak setup
-          gen_dcsr_ebreak(instr);
-        end
-        if (cfg.enable_debug_single_step) begin
-          // To enable debug single stepping, we must set dcsr.step to 1.
-          // We will repeat the debug single stepping process a random number
-          // of times, using a dscratch CSR as the counter, and decrement
-          // this counter by 1 every time we enter debug mode, until this
-          // counter reaches 0, at which point we set dcsr.step to 0 until
-          // the next debug stimulus is asserted.
-
-          // Store our designated scratch_reg to dscratch1
-          str = {$sformatf("csrw 0x%0x, x%0d", DSCRATCH1, cfg.scratch_reg),
-                 // Only un-set dcsr.step if it is 1 and the iterations counter
-                 // is at 0 (has finished iterating)
-                 $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DCSR),
-                 $sformatf("andi x%0d, x%0d, 4", cfg.scratch_reg, cfg.scratch_reg),
-                 // If dcsr.step is 0, set to 1 and set the counter
-                 $sformatf("beqz x%0d, 1f", cfg.scratch_reg),
-                 $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
-                 // if the counter is greater than 0, decrement and continue single stepping
-                 $sformatf("bgtz x%0d, 2f", cfg.scratch_reg),
-                 $sformatf("csrc 0x%0x, 0x4", DCSR),
-                 $sformatf("beqz x0, 3f"),
-                 // Set dcsr.step and the num_iterations counter
-                 $sformatf("1: csrs 0x%0x, 0x4", DCSR),
-                 $sformatf("li x%0d, %0d", cfg.scratch_reg, cfg.single_step_iterations),
-                 $sformatf("csrw 0x%0x, x%0d", DSCRATCH0, cfg.scratch_reg),
-                 $sformatf("beqz x0, 3f"),
-                 // Decrement dscratch counter
-                 $sformatf("2: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
-                 $sformatf("addi x%0d, x%0d, -1", cfg.scratch_reg, cfg.scratch_reg),
-                 $sformatf("csrw 0x%0x, x%0d", DSCRATCH0, cfg.scratch_reg),
-                 // Restore scratch_reg value from dscratch1
-                 $sformatf("3: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)
-                 };
-          instr = {instr, str};
-          // write dpc to testbench
-          gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(DPC));
-          // write out the counter to the testbench
-          gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(DSCRATCH0));
-        end
-        // Check dcsr.cause, and update dpc by 0x4 if the cause is ebreak, as
-        // ebreak will set set dpc to its own address, which will cause an
-        // infinite loop.
-        str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DCSR),
-               $sformatf("slli x%0d, x%0d, 0x17", cfg.scratch_reg, cfg.scratch_reg),
-               $sformatf("srli x%0d, x%0d, 0x1d", cfg.scratch_reg, cfg.scratch_reg),
-               $sformatf("li x%0d, 0x1", cfg.gpr[0]),
-               $sformatf("bne x%0d, x%0d, 4f", cfg.scratch_reg, cfg.gpr[0])};
-        instr = {instr, str};
-        increment_csr(DPC, 4, instr);
-        str = {"4: nop"};
-        instr = {instr, str};
-        // write DCSR to the testbench for any analysis
-        gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(DCSR));
-        // Increment dscratch0 by 1 to update the loop counter for all ebreak
-        // tests
-        if (cfg.enable_ebreak_in_debug_rom || cfg.set_dcsr_ebreak) begin
-          // Add 1 to dscratch0
-          increment_csr(DSCRATCH0, 1, instr);
-          str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
-          instr = {instr, str};
-        end
-        format_section(instr);
-        gen_sub_program(debug_sub_program, debug_sub_program_name,
-                        cfg.num_debug_sub_program, 1'b1, "debug_sub");
-        debug_program = riscv_instr_sequence::type_id::create("debug_program");
-        debug_program.instr_cnt = cfg.debug_program_instr_cnt;
-        debug_program.is_debug_program = 1;
-        debug_program.cfg = cfg;
-        `DV_CHECK_RANDOMIZE_FATAL(debug_program)
-        debug_program.gen_instr(.is_main_program(1'b1), .no_branch(cfg.no_branch_jump));
-        gen_callstack(debug_program, debug_sub_program, debug_sub_program_name,
-                      cfg.num_debug_sub_program);
-        debug_program.post_process_instr();
-        debug_program.generate_instr_stream(.no_label(1'b1));
-        insert_sub_program(debug_sub_program, instr_stream);
-        instr = {instr, debug_program.instr_string_list};
-        gen_section("debug_rom", instr);
-        // Set dscratch0 back to 0x0 to prepare for the next entry into debug
-        // mode, and write dscratch0 and dcsr to the testbench for any
-        // analysis
-        if (cfg.enable_ebreak_in_debug_rom) begin
-          // send dpc and dcsr to testbench, as this handshake will be
-          // executed twice due to the ebreak loop, there should be no change
-          // in their values as by the Debug Mode Spec Ch. 4.1.8
-          gen_signature_handshake(.instr(debug_end), .signature_type(WRITE_CSR), .csr(DCSR));
-          gen_signature_handshake(.instr(debug_end), .signature_type(WRITE_CSR), .csr(DPC));
-          str = {$sformatf("csrwi 0x%0x, 0x0", DSCRATCH0)};
-          debug_end = {debug_end, str};
-        end
-        pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv,
-                                  cfg.sp, cfg.tp, debug_end);
-        // We have been using dscratch1 to store the
-        // value of our given scratch register for use in ebreak loop, so we
-        // need to restore its value before returning from D mode
-        if (cfg.enable_ebreak_in_debug_rom) begin
-          str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
-          debug_end = {debug_end, str};
-        end
-        format_section(debug_end);
-        debug_end = {debug_end, dret};
-        gen_section("debug_end", debug_end);
-      end
-    end
-  endfunction
-
-  // Generate exception handling routine for debug ROM
-  virtual function void gen_debug_exception_handler();
-    if (riscv_instr_pkg::support_debug_mode) begin
-      string instr[];
-      instr = {"dret"};
-      gen_section("debug_exception", instr);
-    end
-  endfunction
-
-  // Set dcsr.ebreak(m/s/u)
-  // TODO(udinator) - randomize the setup for these fields
-  virtual function void gen_dcsr_ebreak(ref string instr[$]);
-    string str;
-    if (MACHINE_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
-      str = $sformatf("li x%0d, 0x8000", cfg.scratch_reg);
-      instr.push_back(str);
-      str = $sformatf("csrs dcsr, x%0d", cfg.scratch_reg);
-      instr.push_back(str);
-    end
-    if (SUPERVISOR_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
-      str = $sformatf("li x%0d, 0x2000", cfg.scratch_reg);
-      instr.push_back(str);
-      str = $sformatf("csrs dcsr, x%0d", cfg.scratch_reg);
-      instr.push_back(str);
-    end
-    if (USER_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
-      str = $sformatf("li x%0d, 0x1000", cfg.scratch_reg);
-      instr.push_back(str);
-      str = $sformatf("csrs dcsr, x%0d", cfg.scratch_reg);
-      instr.push_back(str);
-    end
-  endfunction
-
-  virtual function void increment_csr(privileged_reg_t csr, int val, ref string instr[$]);
-    string str;
-    str = $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, csr);
-    instr.push_back(str);
-    str = $sformatf("addi x%0d, x%0d, 0x%0x", cfg.scratch_reg, cfg.scratch_reg, val);
-    instr.push_back(str);
-    str = $sformatf("csrw 0x%0x, x%0d", csr, cfg.scratch_reg);
-    instr.push_back(str);
+    `uvm_info(`gfn, "Creating debug ROM", UVM_LOW)
+    debug_rom = riscv_asm_program_gen::type_id::create("debug_rom", , {"uvm_test_top", ".", `gfn});
+    debug_rom.cfg = cfg;
+    debug_rom.gen_program();
+    instr_stream = {instr_stream, debug_rom.instr_stream};
   endfunction
 
 endclass
diff --git a/vendor/google_riscv-dv/src/riscv_debug_rom_gen.sv b/vendor/google_riscv-dv/src/riscv_debug_rom_gen.sv
new file mode 100644
index 00000000..d409aef2
--- /dev/null
+++ b/vendor/google_riscv-dv/src/riscv_debug_rom_gen.sv
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2019 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.
+ */
+
+//---------------------------------------------------------------------------------------
+// RISC-V debug ROM class
+//
+// This is the main class to generate a test debug ROM, which includes control knobs to
+// toggle various configuration fields of DCSR.
+//---------------------------------------------------------------------------------------
+
+class riscv_debug_rom_gen extends riscv_asm_program_gen;
+
+  string debug_main[$];
+  string debug_end[$];
+  string str[$];
+  string dret;
+
+  `uvm_object_utils(riscv_debug_rom_gen)
+
+  function new(string name = "");
+    super.new(name);
+    dret = "dret";
+  endfunction
+
+  //-------------------------------------------------------------------------------------
+  // Main function to generate whole debug ROM
+  //-------------------------------------------------------------------------------------
+
+  virtual function void gen_program();
+    string sub_program_name[$] = {};
+    if (!cfg.gen_debug_section) begin
+      // If the debug section should not be generated, we just populate it
+      // with a dret instruction.
+      debug_main = {dret};
+      gen_section("debug_rom", debug_main);
+    end else begin
+      if (cfg.enable_ebreak_in_debug_rom) begin
+        gen_ebreak_header();
+      end
+      // Need to save off GPRs to avoid modifying program flow
+      push_gpr_to_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, debug_main);
+      // Signal that the core entered debug rom only if the rom is actually
+      // being filled with random instructions to prevent stress tests from
+      // having to execute unnecessary push/pop of GPRs on the stack ever
+      // time a debug request is sent
+      gen_signature_handshake(debug_main, CORE_STATUS, IN_DEBUG_MODE);
+      if (cfg.enable_ebreak_in_debug_rom) begin
+        // send dpc and dcsr to testbench, as this handshake will be
+        // executed twice due to the ebreak loop, there should be no change
+        // in their values as by the Debug Mode Spec Ch. 4.1.8
+        gen_signature_handshake(.instr(debug_main), .signature_type(WRITE_CSR), .csr(DCSR));
+        gen_signature_handshake(.instr(debug_main), .signature_type(WRITE_CSR), .csr(DPC));
+      end
+      if (cfg.set_dcsr_ebreak) begin
+        // We want to set dcsr.ebreak(m/s/u) to 1'b1, depending on what modes
+        // are available.
+        // TODO(udinator) - randomize the dcsr.ebreak setup
+        gen_dcsr_ebreak();
+      end
+      if (cfg.enable_debug_single_step) begin
+        gen_single_step_logic();
+      end
+      gen_dpc_update();
+      // write DCSR to the testbench for any analysis
+      gen_signature_handshake(.instr(debug_main), .signature_type(WRITE_CSR), .csr(DCSR));
+      if (cfg.enable_ebreak_in_debug_rom || cfg.set_dcsr_ebreak) begin
+        gen_increment_ebreak_counter();
+      end
+      format_section(debug_main);
+      gen_sub_program(sub_program, sub_program_name,
+                      cfg.num_debug_sub_program, 1'b1, "debug_sub");
+      main_program = riscv_instr_sequence::type_id::create("debug_program");
+      main_program.instr_cnt = cfg.debug_program_instr_cnt;
+      main_program.is_debug_program = 1;
+      main_program.cfg = cfg;
+      `DV_CHECK_RANDOMIZE_FATAL(main_program)
+      main_program.gen_instr(.is_main_program(1'b1), .no_branch(cfg.no_branch_jump));
+      gen_callstack(main_program, sub_program, sub_program_name,
+                    cfg.num_debug_sub_program);
+      main_program.post_process_instr();
+      main_program.generate_instr_stream(.no_label(1'b1));
+      insert_sub_program(sub_program, debug_main);
+      debug_main = {debug_main, main_program.instr_string_list};
+      gen_section("debug_rom", debug_main);
+      if (cfg.enable_ebreak_in_debug_rom) begin
+        gen_ebreak_footer();
+      end
+      pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv,
+                                cfg.sp, cfg.tp, debug_end);
+      if (cfg.enable_ebreak_in_debug_rom) begin
+        gen_restore_ebreak_scratch_reg();
+      end
+      //format_section(debug_end);
+      debug_end = {debug_end, dret};
+      gen_section("debug_end", debug_end);
+    end
+    gen_debug_exception_handler();
+  endfunction
+
+  // Generate exception handling routine for debug ROM
+  // TODO(udinator) - remains empty for now, only a DRET
+  virtual function void gen_debug_exception_handler();
+    str = {"dret"};
+    gen_section("debug_exception", str);
+  endfunction
+
+  //-------------------------------------------------------------------------------------
+  // Helper functions to generate smaller sections of code
+  //-------------------------------------------------------------------------------------
+
+  // As execution of ebreak in D mode causes core to re-enter D mode, this directed
+  // sequence will be a loop that ensures the ebreak instruction will only be executed
+  // once to prevent infinitely looping back to the beginning of the debug rom.
+  // Write dscratch to random GPR and branch to debug_end if greater than 0, for ebreak loops.
+  // Use dscratch1 to store original GPR value.
+  virtual function void gen_ebreak_header();
+    str = {$sformatf("csrw 0x%0x, x%0d", DSCRATCH1, cfg.scratch_reg),
+           $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
+           $sformatf("beq x%0d, x0, 1f", cfg.scratch_reg),
+           $sformatf("j debug_end"),
+           $sformatf("1: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
+    debug_main = {debug_main, str};
+  endfunction
+
+  // Set dscratch0 back to 0x0 to prepare for the next entry into debug
+  // mode, and write dscratch0 and dcsr to the testbench for any
+  // analysis
+  virtual function void gen_ebreak_footer();
+    // send dpc and dcsr to testbench, as this handshake will be
+    // executed twice due to the ebreak loop, there should be no change
+    // in their values as by the Debug Mode Spec Ch. 4.1.8
+    gen_signature_handshake(.instr(debug_end), .signature_type(WRITE_CSR), .csr(DCSR));
+    gen_signature_handshake(.instr(debug_end), .signature_type(WRITE_CSR), .csr(DPC));
+    str = {$sformatf("csrwi 0x%0x, 0x0", DSCRATCH0)};
+    debug_end = {debug_end, str};
+  endfunction
+
+  // Increment dscratch0 by 1 to update the loop counter for all ebreak tests
+  virtual function void gen_increment_ebreak_counter();
+    // Add 1 to dscratch0
+    increment_csr(DSCRATCH0, 1, debug_main);
+    str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
+    debug_main = {debug_main, str};
+  endfunction
+
+  // We have been using dscratch1 to store the
+  // value of our given scratch register for use in ebreak loop, so we
+  // need to restore its value before returning from D mode
+  virtual function void gen_restore_ebreak_scratch_reg();
+    str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)};
+    debug_end = {debug_end, str};
+  endfunction
+
+  // To enable debug single stepping, we must set dcsr.step to 1.
+  // We will repeat the debug single stepping process a random number of times,
+  // using a dscratch CSR as the counter, and decrement this counter by 1 every time we
+  // enter debug mode, until this counter reaches 0, at which point we set
+  // dcsr.step to 0 until the next debug stimulus is asserted.
+  // Store our designated scratch_reg to dscratch1
+  virtual function void gen_single_step_logic();
+    str = {$sformatf("csrw 0x%0x, x%0d", DSCRATCH1, cfg.scratch_reg),
+           // Only un-set dcsr.step if it is 1 and the iterations counter
+           // is at 0 (has finished iterating)
+           $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DCSR),
+           $sformatf("andi x%0d, x%0d, 4", cfg.scratch_reg, cfg.scratch_reg),
+           // If dcsr.step is 0, set to 1 and set the counter
+           $sformatf("beqz x%0d, 1f", cfg.scratch_reg),
+           $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
+           // if the counter is greater than 0, decrement and continue single stepping
+           $sformatf("bgtz x%0d, 2f", cfg.scratch_reg),
+           $sformatf("csrc 0x%0x, 0x4", DCSR),
+           $sformatf("beqz x0, 3f"),
+           // Set dcsr.step and the num_iterations counter
+           $sformatf("1: csrs 0x%0x, 0x4", DCSR),
+           $sformatf("li x%0d, %0d", cfg.scratch_reg, cfg.single_step_iterations),
+           $sformatf("csrw 0x%0x, x%0d", DSCRATCH0, cfg.scratch_reg),
+           $sformatf("beqz x0, 3f"),
+           // Decrement dscratch counter
+           $sformatf("2: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH0),
+           $sformatf("addi x%0d, x%0d, -1", cfg.scratch_reg, cfg.scratch_reg),
+           $sformatf("csrw 0x%0x, x%0d", DSCRATCH0, cfg.scratch_reg),
+           // Restore scratch_reg value from dscratch1
+           $sformatf("3: csrr x%0d, 0x%0x", cfg.scratch_reg, DSCRATCH1)
+    };
+    debug_main = {debug_main, str};
+    // write dpc to testbench
+    gen_signature_handshake(.instr(debug_main), .signature_type(WRITE_CSR), .csr(DPC));
+    // write out the counter to the testbench
+    gen_signature_handshake(.instr(debug_main), .signature_type(WRITE_CSR), .csr(DSCRATCH0));
+  endfunction
+
+  // Check dcsr.cause, and update dpc by 0x4 if the cause is ebreak, as
+  // ebreak will set set dpc to its own address, which will cause an
+  // infinite loop.
+  virtual function void gen_dpc_update();
+    str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DCSR),
+           $sformatf("slli x%0d, x%0d, 0x17", cfg.scratch_reg, cfg.scratch_reg),
+           $sformatf("srli x%0d, x%0d, 0x1d", cfg.scratch_reg, cfg.scratch_reg),
+           $sformatf("li x%0d, 0x1", cfg.gpr[0]),
+           $sformatf("bne x%0d, x%0d, 4f", cfg.scratch_reg, cfg.gpr[0])};
+    debug_main = {debug_main, str};
+    increment_csr(DPC, 4, debug_main);
+    str = {"4: nop"};
+    debug_main = {debug_main, str};
+  endfunction
+
+  // Set dcsr.ebreak(m/s/u)
+  // TODO(udinator) - randomize the setup for these fields
+  virtual function void gen_dcsr_ebreak();
+    if (MACHINE_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
+      str = {$sformatf("li x%0d, 0x8000", cfg.scratch_reg),
+             $sformatf("csrs dcsr, x%0d", cfg.scratch_reg)};
+      debug_main = {debug_main, str};
+    end
+    if (SUPERVISOR_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
+      str = {$sformatf("li x%0d, 0x2000", cfg.scratch_reg),
+             $sformatf("csrs dcsr, x%0d", cfg.scratch_reg)};
+      debug_main = {debug_main, str};
+    end
+    if (USER_MODE inside {riscv_instr_pkg::supported_privileged_mode}) begin
+      str = {$sformatf("li x%0d, 0x1000", cfg.scratch_reg),
+             $sformatf("csrs dcsr, x%0d", cfg.scratch_reg)};
+      debug_main = {debug_main, str};
+    end
+  endfunction
+
+  virtual function void increment_csr(privileged_reg_t csr, int val, ref string instr[$]);
+    str = {$sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, csr),
+           $sformatf("addi x%0d, x%0d, 0x%0x", cfg.scratch_reg, cfg.scratch_reg, val),
+           $sformatf("csrw 0x%0x, x%0d", csr, cfg.scratch_reg)};
+    instr = {instr, str};
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/src/riscv_defines.svh b/vendor/google_riscv-dv/src/riscv_defines.svh
index fe3c7fff..252400fb 100644
--- a/vendor/google_riscv-dv/src/riscv_defines.svh
+++ b/vendor/google_riscv-dv/src/riscv_defines.svh
@@ -33,3 +33,47 @@
     } \
   }
 
+`define INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM) \
+    static bit valid = riscv_instr::register(instr_n);  \
+    `uvm_object_utils(riscv_``instr_n``_instr)  \
+    function new(string name = "");  \
+      super.new(name);  \
+      this.instr_name = ``instr_n; \
+      this.format = ``instr_format;  \
+      this.group = ``instr_group;  \
+      this.category = ``instr_category;  \
+      this.imm_type = ``imm_tp;  \
+      set_imm_len(); \
+      set_rand_mode(); \
+    endfunction \
+  endclass
+
+// Regular integer instruction
+`define DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
+
+// Floating point instruction
+`define DEFINE_FP_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_floating_point_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
+
+// A-extension instruction
+`define DEFINE_AMO_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_amo_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
+
+// Compressed instruction
+`define DEFINE_C_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_compressed_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
+
+// Floating point compressed instruction
+`define DEFINE_FC_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_compressed_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
+
+// Vector instruction
+`define DEFINE_V_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM)  \
+  class riscv_``instr_n``_instr extends riscv_vector_instr;  \
+    `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
diff --git a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
index 30a5343e..ee4328ae 100644
--- a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
+++ b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
@@ -74,10 +74,10 @@ class riscv_mem_access_stream extends riscv_directed_instr_stream;
 
   // Insert some other instructions to mix with mem_access instruction
   virtual function void add_mixed_instr(int instr_cnt);
-    riscv_instr_base instr;
+    riscv_instr      instr;
     setup_allowed_instr(1, 1);
     for(int i = 0; i < instr_cnt; i ++) begin
-      instr = riscv_instr_base::type_id::create("instr");
+      instr = riscv_instr::type_id::create("instr");
       randomize_instr(instr);
       insert_instr(instr);
     end
@@ -92,15 +92,15 @@ endclass
 // For JAL, restore the stack before doing the jump
 class riscv_jump_instr extends riscv_directed_instr_stream;
 
-  riscv_instr_base     jump;
-  riscv_instr_base     addi;
+  riscv_instr          jump;
+  riscv_instr          addi;
   riscv_pseudo_instr   la;
-  riscv_instr_base     branch;
+  riscv_instr          branch;
   rand riscv_reg_t     gpr;
   rand int             imm;
   rand bit             enable_branch;
   rand int             mixed_instr_cnt;
-  riscv_instr_base     stack_exit_instr[];
+  riscv_instr          stack_exit_instr[];
   string               target_program_label;
   int                  idx;
   bit                  use_jalr;
@@ -115,30 +115,32 @@ class riscv_jump_instr extends riscv_directed_instr_stream;
 
   function new(string name = "");
     super.new(name);
-    jump = riscv_instr_base::type_id::create("jump");
     la = riscv_pseudo_instr::type_id::create("la");
-    addi = riscv_instr_base::type_id::create("addi");
-    branch = riscv_instr_base::type_id::create("branch");
+  endfunction
+
+  function void pre_randomize();
+    if (use_jalr) begin
+      jump = riscv_instr::get_rand_instr(.include_instr({JALR}));
+    end else if (cfg.disable_compressed_instr || (cfg.ra != RA)) begin
+      jump = riscv_instr::get_rand_instr(.include_instr({JAL, JALR}));
+    end else begin
+      jump = riscv_instr::get_rand_instr(.include_instr({JAL, JALR, C_JALR}));
+    end
+    addi = riscv_instr::get_rand_instr(.include_instr({ADDI}));
+    branch = riscv_instr::get_rand_instr(.include_instr({BEQ, BNE, BLT, BGE, BLTU, BGEU}));
   endfunction
 
   function void post_randomize();
-    riscv_instr_base instr[];
+    riscv_instr instr[];
     `DV_CHECK_RANDOMIZE_WITH_FATAL(jump,
-      (use_jalr) -> (instr_name == JALR);
-      instr_name dist {JAL := 2, JALR := 6, C_JALR := 2};
-      if (cfg.disable_compressed_instr || (cfg.ra != RA)) {
-        instr_name != C_JALR;
+      if (has_rd) {
+        rd == cfg.ra;
       }
-      rd == cfg.ra;
-      rs1 == gpr;
-    )
-    `DV_CHECK_RANDOMIZE_WITH_FATAL(addi,
-      rs1 == gpr;
-      instr_name == ADDI;
-      rd  == gpr;
-    )
-    `DV_CHECK_RANDOMIZE_WITH_FATAL(branch,
-      instr_name inside {BEQ, BNE, BLT, BGE, BLTU, BGEU};)
+      if (has_rs1) {
+        rs1 == gpr;
+      })
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(addi, rs1 == gpr; rd == gpr;)
+    `DV_CHECK_RANDOMIZE_FATAL(branch)
     la.pseudo_instr_name = LA;
     la.imm_str = target_program_label;
     la.rd = gpr;
@@ -180,9 +182,9 @@ endclass
 // Stress back to back jump instruction
 class riscv_jal_instr extends riscv_rand_instr_stream;
 
-  riscv_instr_base     jump[];
-  riscv_instr_base     jump_start;
-  riscv_instr_base     jump_end;
+  riscv_instr          jump[];
+  riscv_instr          jump_start;
+  riscv_instr          jump_end;
   rand int unsigned    num_of_jump_instr;
   riscv_instr_name_t   jal[$];
 
@@ -213,23 +215,20 @@ class riscv_jal_instr extends riscv_rand_instr_stream;
       end
     end
     // First instruction
-    jump_start = riscv_instr_base::type_id::create("jump_start");
-    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump_start,
-      instr_name == JAL;
-      rd == cfg.ra;
-    )
+    jump_start = riscv_instr::get_rand_instr(.include_instr({JAL}));
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump_start, rd == cfg.ra;)
     jump_start.imm_str = $sformatf("%0df", order[0]);
     jump_start.label = label;
     // Last instruction
-    jump_end = riscv_instr_base::type_id::create("jump_end");
     randomize_instr(jump_end);
     jump_end.label = $sformatf("%0d", num_of_jump_instr);
     foreach (jump[i]) begin
-      jump[i] = riscv_instr_base::type_id::create($sformatf("jump_%0d", i));
+      jump[i] = riscv_instr::get_rand_instr(.include_instr({jal}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(jump[i],
-        instr_name inside {jal};
-        rd dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
-        !(rd inside {cfg.reserved_regs});
+        if (has_rd) {
+          rd dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
+          !(rd inside {cfg.reserved_regs});
+        }
       )
       jump[i].label = $sformatf("%0d", i);
     end
@@ -258,9 +257,9 @@ class riscv_push_stack_instr extends riscv_rand_instr_stream;
   int                      stack_len;
   int                      num_of_reg_to_save;
   int                      num_of_redudant_instr;
-  riscv_instr_base         push_stack_instr[];
+  riscv_instr              push_stack_instr[];
   riscv_reg_t              saved_regs[];
-  rand riscv_rand_instr    branch_instr;
+  riscv_instr              branch_instr;
   rand bit                 enable_branch;
   string                   push_start_label;
 
@@ -289,19 +288,22 @@ class riscv_push_stack_instr extends riscv_rand_instr_stream;
     gen_instr(1'b1);
     push_stack_instr = new[num_of_reg_to_save+1];
     foreach(push_stack_instr[i]) begin
-      push_stack_instr[i] = riscv_instr_base::type_id::
-                             create($sformatf("push_stack_instr_%0d", i));
+      push_stack_instr[i] = riscv_instr::type_id::
+                            create($sformatf("push_stack_instr_%0d", i));
     end
     // addi sp,sp,-imm
+    push_stack_instr[0] = riscv_instr::get_rand_instr(.include_instr({ADDI}));
     `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[0],
-                                   instr_name == ADDI; rd == cfg.sp; rs1 == cfg.sp;
+                                   rd == cfg.sp; rs1 == cfg.sp;
                                    imm == (~stack_len + 1);)
     push_stack_instr[0].imm_str = $sformatf("-%0d", stack_len);
     foreach(saved_regs[i]) begin
       if(XLEN == 32) begin
+        push_stack_instr[i+1] = riscv_instr::get_rand_instr(.include_instr({SW}));
         `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[i+1],
-          instr_name == SW; rs2 == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
+          rs2 == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
       end else begin
+        push_stack_instr[i+1] = riscv_instr::get_rand_instr(.include_instr({SD}));
         `DV_CHECK_RANDOMIZE_WITH_FATAL(push_stack_instr[i+1],
           instr_name == SD; rs2 == saved_regs[i]; rs1 == cfg.sp; imm == 8 * (i+1);)
       end
@@ -313,15 +315,8 @@ class riscv_push_stack_instr extends riscv_rand_instr_stream;
       enable_branch = 0;
     end
     if(enable_branch) begin
-      // Cover jal -> branch scenario, the branch is added before push stack operation
-      branch_instr = riscv_rand_instr::type_id::create("branch_instr");
-      branch_instr.cfg = cfg;
-      `ifdef DSIM
-        `DV_CHECK_RANDOMIZE_WITH_FATAL(branch_instr,
-                                       instr_name inside {[BEQ:BGEU], C_BEQZ, C_BNEZ};)
-      `else
-        `DV_CHECK_RANDOMIZE_WITH_FATAL(branch_instr, category == BRANCH;)
-      `endif
+      branch_instr = riscv_instr::get_rand_instr(.include_category({BRANCH}));
+      `DV_CHECK_RANDOMIZE_FATAL(branch_instr)
       branch_instr.imm_str = push_start_label;
       branch_instr.branch_assigned = 1'b1;
       push_stack_instr[0].label = push_start_label;
@@ -341,11 +336,11 @@ endclass
 // Pop stack instruction stream
 class riscv_pop_stack_instr extends riscv_rand_instr_stream;
 
-  int                      stack_len;
-  int                      num_of_reg_to_save;
-  int                      num_of_redudant_instr;
-  riscv_instr_base         pop_stack_instr[];
-  riscv_reg_t              saved_regs[];
+  int          stack_len;
+  int          num_of_reg_to_save;
+  int          num_of_redudant_instr;
+  riscv_instr  pop_stack_instr[];
+  riscv_reg_t  saved_regs[];
 
   `uvm_object_utils(riscv_pop_stack_instr)
 
@@ -371,22 +366,25 @@ class riscv_pop_stack_instr extends riscv_rand_instr_stream;
     gen_instr(1'b1);
     pop_stack_instr = new[num_of_reg_to_save+1];
     foreach(pop_stack_instr[i]) begin
-      pop_stack_instr[i] = riscv_instr_base::type_id::
-                             create($sformatf("pop_stack_instr_%0d", i));
+      pop_stack_instr[i] = riscv_instr::type_id::
+                           create($sformatf("pop_stack_instr_%0d", i));
     end
     foreach(saved_regs[i]) begin
       if(XLEN == 32) begin
+        pop_stack_instr[i] = riscv_instr::get_rand_instr(.include_instr({LW}));
         `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[i],
-          instr_name == LW; rd == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
+          rd == saved_regs[i]; rs1 == cfg.sp; imm == 4 * (i+1);)
       end else begin
+        pop_stack_instr[i] = riscv_instr::get_rand_instr(.include_instr({LD}));
         `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[i],
-          instr_name == LD; rd == saved_regs[i]; rs1 == cfg.sp; imm == 8 * (i+1);)
+          rd == saved_regs[i]; rs1 == cfg.sp; imm == 8 * (i+1);)
       end
       pop_stack_instr[i].process_load_store = 0;
     end
     // addi sp,sp,imm
+    pop_stack_instr[num_of_reg_to_save] = riscv_instr::get_rand_instr(.include_instr({ADDI}));
     `DV_CHECK_RANDOMIZE_WITH_FATAL(pop_stack_instr[num_of_reg_to_save],
-      instr_name == ADDI; rd == cfg.sp; rs1 == cfg.sp; imm == stack_len;)
+                                   rd == cfg.sp; rs1 == cfg.sp; imm == stack_len;)
     pop_stack_instr[num_of_reg_to_save].imm_str = $sformatf("%0d", stack_len);
     mix_instr_stream(pop_stack_instr);
     foreach(instr_list[i]) begin
@@ -396,136 +394,3 @@ class riscv_pop_stack_instr extends riscv_rand_instr_stream;
   endfunction
 
 endclass
-
-// Cover the long fprward and backward jump
-class riscv_long_branch_instr extends riscv_rand_instr_stream;
-
-  int branch_instr_stream_len = 100;
-  int branch_instr_offset = 999;
-  riscv_rand_instr_stream forward_branch_instr_stream;
-  riscv_rand_instr_stream backward_branch_instr_stream;
-  riscv_instr_base        jump_instr;
-
-  `uvm_object_utils(riscv_long_branch_instr)
-
-  function new(string name = "");
-    super.new(name);
-    forward_branch_instr_stream = riscv_rand_instr_stream::type_id::
-                                  create("forward_branch_instr_stream");
-    backward_branch_instr_stream = riscv_rand_instr_stream::type_id::
-                                  create("backward_branch_instr_stream");
-    jump_instr = riscv_instr_base::type_id::create("jump_instr");
-  endfunction
-
-  function void init(int instr_len);
-    branch_instr_stream_len = instr_len;
-    initialize_instr_list(branch_instr_offset-branch_instr_stream_len);
-    forward_branch_instr_stream.cfg = cfg;
-    backward_branch_instr_stream.cfg = cfg;
-    forward_branch_instr_stream.initialize_instr_list(branch_instr_stream_len);
-    backward_branch_instr_stream.initialize_instr_list(branch_instr_stream_len);
-  endfunction
-
-  virtual function void gen_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1,
-                                  bit is_debug_program = 1'b0);
-    int branch_offset;
-    super.gen_instr(1'b1);
-    forward_branch_instr_stream.gen_instr();
-    backward_branch_instr_stream.gen_instr();
-    `DV_CHECK_RANDOMIZE_WITH_FATAL(jump_instr, instr_name == JAL;)
-    jump_instr.imm_str = "test_done";
-    instr_list = {forward_branch_instr_stream.instr_list, instr_list,
-                  jump_instr, backward_branch_instr_stream.instr_list};
-    foreach(instr_list[i]) begin
-      instr_list[i].atomic = 1'b1;
-      if(!instr_list[i].is_branch_target) begin
-        instr_list[i].has_label = 1'b0;
-      end
-      if(instr_list[i].category == BRANCH) begin
-        if(i < branch_instr_stream_len)
-          branch_offset = branch_instr_offset;
-        else
-          branch_offset = -branch_instr_offset;
-        instr_list[i].imm_str = $sformatf("target_%0d", i);
-        instr_list[i].branch_assigned = 1'b1;
-        // Avoid dead loop
-        if(((instr_list[i+branch_offset].category == BRANCH) ||
-             instr_list[i+branch_offset].is_branch_target) && (branch_offset < 0))
-          branch_offset = branch_offset + 1;
-        `uvm_info(get_full_name(), $sformatf("Branch [%0d] %0s -> [%0d] %0s", i,
-                  instr_list[i].convert2asm(), i+branch_offset,
-                  instr_list[i+branch_offset].convert2asm()), UVM_LOW)
-        if(i < -branch_offset)
-          `uvm_fatal(get_name(), $sformatf("Unexpected branch instr at %0d", i))
-        instr_list[i+branch_offset].label = $sformatf("target_%0d", i);
-        instr_list[i+branch_offset].has_label = 1'b1;
-        instr_list[i+branch_offset].is_branch_target = 1;
-      end
-    end
-  endfunction
-
-endclass
-
-class riscv_sw_interrupt_instr extends riscv_directed_instr_stream;
-
-  rand bit usip;
-  rand bit ssip;
-  rand bit msip;
-  rand privileged_reg_t ip_reg;
-  rand riscv_pseudo_instr li_instr;
-  rand riscv_instr_base csr_instr;
-  riscv_privil_reg ip;
-  rand riscv_reg_t rs1_reg;
-
-  constraint ip_reg_c {
-    if(cfg.init_privileged_mode == MACHINE_MODE) {
-      ip_reg == MIP;
-    } else {
-      ip_reg == SIP;
-    }
-    (ip_reg == MIP) -> (usip || ssip || msip);
-    (ip_reg == SIP) -> (usip || ssip);
-  }
-
-  constraint instr_c {
-    !(rs1_reg inside {cfg.reserved_regs});
-    rs1_reg != ZERO;
-    li_instr.pseudo_instr_name == LI;
-    li_instr.rd == rs1_reg;
-    csr_instr.instr_name == CSRRW;
-    csr_instr.rs1 == rs1_reg;
-    // TODO: Support non-zero rd for SIP, MIP
-    // csr_instr.rd inside {cfg.avail_regs};
-    csr_instr.rd == ZERO;
-    csr_instr.csr == ip_reg;
-  }
-
-  `uvm_object_utils(riscv_sw_interrupt_instr)
-
-  function new(string name = "");
-    super.new(name);
-    li_instr = riscv_pseudo_instr::type_id::create("li_instr");
-    csr_instr = riscv_instr_base::type_id::create("csr_instr");
-    ip = riscv_privil_reg::type_id::create("ip");
-  endfunction
-
-  function void post_randomize();
-    // TODO: Support UIP
-    if(cfg.init_privileged_mode == USER_MODE) return;
-    ip.init_reg(ip_reg);
-    if(ip_reg == SIP) begin
-      ip.set_field("USIP", usip);
-      ip.set_field("SSIP", ssip);
-    end else begin
-      ip.set_field("USIP", usip);
-      ip.set_field("SSIP", ssip);
-      ip.set_field("MSIP", msip);
-    end
-    li_instr.imm_str = $sformatf("0x%0x", ip.get_val());
-    csr_instr.comment = ip_reg.name();
-    instr_list = {li_instr, csr_instr};
-    super.post_randomize();
-  endfunction
-
-endclass
-
diff --git a/vendor/google_riscv-dv/src/riscv_illegal_instr.sv b/vendor/google_riscv-dv/src/riscv_illegal_instr.sv
index a3ed9e1a..a4b263cb 100644
--- a/vendor/google_riscv-dv/src/riscv_illegal_instr.sv
+++ b/vendor/google_riscv-dv/src/riscv_illegal_instr.sv
@@ -281,6 +281,9 @@ class riscv_illegal_instr extends uvm_object;
     if (!compressed) {
       if (exception == kIllegalFunc7) {
         !(func7 inside {7'b0, 7'b0100000, 7'b1});
+        if (opcode == 7'b001001) { // SLLI, SRLI, SRAI
+          !(func7[6:1] inside {6'b0, 6'b010000});
+        }
       } else {
         func7 inside {7'b0, 7'b0100000, 7'b1};
       }
diff --git a/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv b/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv
index b4526388..3919051a 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv
+++ b/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv
@@ -1,4 +1,4 @@
-class riscv_instr_cov_item extends riscv_instr_base;
+class riscv_instr_cov_item extends `INSTR;
 
   typedef enum bit[1:0] {
     POSITIVE, NEGATIVE
@@ -23,6 +23,9 @@ class riscv_instr_cov_item extends riscv_instr_base;
   rand bit [XLEN-1:0]   rs1_value;
   rand bit [XLEN-1:0]   rs2_value;
   rand bit [XLEN-1:0]   rd_value;
+  rand bit [XLEN-1:0]   fs1_value;
+  rand bit [XLEN-1:0]   fs2_value;
+  rand bit [XLEN-1:0]   fd_value;
   bit [31:0]            binary;
   bit [XLEN-1:0]        pc;
   bit [XLEN-1:0]        mem_addr;
@@ -46,6 +49,8 @@ class riscv_instr_cov_item extends riscv_instr_base;
   logical_similarity_e  logical_similarity;
   string                trace;
 
+  `VECTOR_INCLUDE("riscv_instr_cov_item_inc_declares.sv")
+
   `uvm_object_utils(riscv_instr_cov_item)
   `uvm_object_new
 
diff --git a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
index dbc0c407..82bf9082 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
+++ b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
@@ -14,6 +14,14 @@
  * limitations under the License.
  */
 
+`ifndef COMPLIANCE_MODE
+  `define DV(TEXT) TEXT
+`else
+  `define DV(TEXT)
+`endif
+
+`define SAMPLE(cg, val) \
+  if (cg != null) cg.sample(val);
 
 `define INSTR_CG_BEGIN(INSTR_NAME) \
   covergroup ``INSTR_NAME``_cg with function sample(riscv_instr_cov_item instr);
@@ -26,7 +34,7 @@
     cp_rs1_sign    : coverpoint instr.rs1_sign; \
     cp_rs2_sign    : coverpoint instr.rs2_sign; \
     cp_rd_sign     : coverpoint instr.rd_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard; \
+    `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
 
 `define CMP_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -34,7 +42,7 @@
     cp_rd          : coverpoint instr.rd;  \
     cp_rs1_sign    : coverpoint instr.rs1_sign; \
     cp_result      : coverpoint instr.rd_value[0]; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard; \
+    `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
 
 `define SB_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -45,35 +53,35 @@
     cp_imm_sign    : coverpoint instr.imm_sign; \
     cp_branch_hit  : coverpoint instr.branch_hit; \
     cp_sign_cross  : cross cp_rs1_sign, cp_rs2_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    }
+    }) \
 
 `define STORE_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rs1         : coverpoint instr.rs1 { \
-      ignore_bins zero = {ZERO}; \
+        `DV(ignore_bins zero = {ZERO};) \
     } \
     cp_rs2         : coverpoint instr.rs2; \
     cp_imm_sign    : coverpoint instr.imm_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    } \
-    cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
+    }) \
+    `DV(cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
       bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
-    }
+    }) \
 
 `define LOAD_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rs1         : coverpoint instr.rs1 { \
-      ignore_bins zero = {ZERO}; \
+      `DV(ignore_bins zero = {ZERO};) \
     } \
     cp_rd          : coverpoint instr.rd; \
     cp_imm_sign    : coverpoint instr.imm_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard; \
-    cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;) \
+    `DV(cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    }
+    }) \
 
 `define I_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -82,14 +90,13 @@
     cp_rs1_sign    : coverpoint instr.rs1_sign; \
     cp_rd_sign     : coverpoint instr.rd_sign; \
     cp_imm_sign    : coverpoint instr.imm_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
 
 `define U_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rd          : coverpoint instr.rd; \
     cp_rd_sign     : coverpoint instr.rd_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
-
+    `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
 
 `define J_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -97,35 +104,34 @@
     cp_rd          : coverpoint instr.rd; \
     cp_rd_align    : coverpoint instr.rd_value[1];
 
-
 `define CSR_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rd          : coverpoint instr.rd; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
 
 `define CR_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rs2         : coverpoint instr.rs2; \
     cp_rd          : coverpoint instr.rd; \
     cp_rs2_sign    : coverpoint instr.rs2_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
 
 `define CI_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rd       : coverpoint instr.rd; \
     cp_imm_sign : coverpoint instr.imm_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
-    }
+    })
 
 `define CSS_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
     cp_rs2      : coverpoint instr.rs2; \
     cp_imm_sign : coverpoint instr.imm_sign; \
     cp_rs2_sign : coverpoint instr.rs2_sign; \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    }
+    })
 
 `define CIW_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -133,9 +139,9 @@
     cp_rd       : coverpoint instr.rd { \
       bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
     } \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
-    }
+    })
 
 `define CL_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -145,10 +151,10 @@
     cp_rd       : coverpoint instr.rd { \
       bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
     } \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard; \
-    cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;) \
+    `DV(cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    }
+    })
 
 `define CL_SP_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -164,12 +170,12 @@
     cp_rs2      : coverpoint instr.rs2 { \
       bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
     } \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    } \
-    cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
+    }) \
+    `DV(cp_lsu_hazard  : coverpoint instr.lsu_hazard { \
       bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
-    }
+    })
 
 `define CS_SP_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -185,7 +191,7 @@
     cp_rs2      : coverpoint instr.rs2 { \
       bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
     } \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;) \
 
 
 `define CB_INSTR_CG_BEGIN(INSTR_NAME) \
@@ -193,9 +199,9 @@
     cp_rs1      : coverpoint instr.rs1 { \
       bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
     } \
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard { \
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
-    }
+    })
 
 `define CJ_INSTR_CG_BEGIN(INSTR_NAME) \
   `INSTR_CG_BEGIN(INSTR_NAME) \
@@ -203,6 +209,12 @@
 
 `define CG_END endgroup
 
+`define CG_SELECTOR_BEGIN(CG_ISA) \
+    if ((CG_ISA inside {supported_isa}) && (!select_isa || (cov_isa == CG_ISA))) begin
+
+`define CG_SELECTOR_END \
+    end
+
 class riscv_instr_cover_group;
 
   riscv_instr_gen_config  cfg;
@@ -212,6 +224,25 @@ class riscv_instr_cover_group;
   int unsigned            instr_cnt;
   int unsigned            branch_instr_cnt;
   bit [4:0]               branch_hit_history; // The last 5 branch result
+  exception_cause_t       ignored_exceptions[];
+
+  // Mode of the coverage model
+
+  // In complicance mode, all the micro-architecture related covergroups are removed. Only the ones
+  // related to RISC-V specification compliance is sampled.
+  bit                     compliance_mode;
+
+  // By default the coverage model run with instruction trace from ISS simulation. When simulating
+  // with ISS, certain covergroups like debug/interrupt could not be hit as these are not simulated
+  // with ISS. You can turn off this mode by adding +iss_mode=0 if you use the instruction trace
+  // from RTL simulation.
+  bit                     iss_mode = 1'b1;
+
+  // Select an ISA extension to cover
+  bit                     select_isa;
+  riscv_instr_group_t     cov_isa;
+
+  `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cpu_declare.sv")
 
   ///////////// RV32I instruction functional coverage //////////////
 
@@ -252,7 +283,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   `INSTR_CG_BEGIN(slli)
@@ -260,7 +291,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   `INSTR_CG_BEGIN(srli)
@@ -268,7 +299,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   // Logical instructions
@@ -422,7 +453,6 @@ class riscv_instr_cover_group;
   endgroup
 
   // RV32M
-
   `R_INSTR_CG_BEGIN(mul)
     cp_sign_cross: cross cp_rs1_sign, cp_rs2_sign;
   `CG_END
@@ -546,7 +576,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   `INSTR_CG_BEGIN(slliw)
@@ -554,7 +584,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   `INSTR_CG_BEGIN(srliw)
@@ -562,7 +592,7 @@ class riscv_instr_cover_group;
     cp_rd          : coverpoint instr.rd;
     cp_rs1_sign    : coverpoint instr.rs1_sign;
     cp_rd_sign     : coverpoint instr.rd_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard;
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard;)
   `CG_END
 
   `R_INSTR_CG_BEGIN(addw)
@@ -599,9 +629,9 @@ class riscv_instr_cover_group;
 
   `INSTR_CG_BEGIN(c_addi16sp)
     cp_imm_sign : coverpoint instr.imm_sign;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard {
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard {
       bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD};
-    }
+    })
   `CG_END
 
   `CI_INSTR_CG_BEGIN(c_li)
@@ -609,7 +639,7 @@ class riscv_instr_cover_group;
 
   `INSTR_CG_BEGIN(c_lui)
     cp_rd : coverpoint instr.rd {
-      ignore_bins bin = {ZERO, SP};
+     `DV(ignore_bins bin = {ZERO, SP};)
     }
   `CG_END
 
@@ -651,9 +681,9 @@ class riscv_instr_cover_group;
 
   `INSTR_CG_BEGIN(c_slli)
     cp_rd          : coverpoint instr.rd;
-    cp_gpr_hazard  : coverpoint instr.gpr_hazard {
+    `DV(cp_gpr_hazard  : coverpoint instr.gpr_hazard {
       bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
-    }
+    })
   `CG_END
 
   `CJ_INSTR_CG_BEGIN(c_j)
@@ -664,13 +694,13 @@ class riscv_instr_cover_group;
 
   `INSTR_CG_BEGIN(c_jr)
     cp_rs1      : coverpoint instr.rs1 {
-      ignore_bins zero = {ZERO};
+      `DV(ignore_bins zero = {ZERO};)
     }
   `CG_END
 
   `INSTR_CG_BEGIN(c_jalr)
     cp_rs1      : coverpoint instr.rs1 {
-      ignore_bins zero = {ZERO};
+      `DV(ignore_bins zero = {ZERO};)
     }
     cp_rd_align : coverpoint instr.rd_value[1];
   `CG_END
@@ -783,7 +813,8 @@ class riscv_instr_cover_group;
   // Privileged CSR covergroup
   covergroup mcause_exception_cg with function sample(exception_cause_t exception);
     cp_exception: coverpoint exception {
-       bins exception[] = cp_exception with (item inside {implemented_exception});
+       bins exception[] = cp_exception with ((item inside {implemented_exception}) &&
+                                            !(item inside {ignored_exceptions}));
     }
   endgroup
 
@@ -805,65 +836,113 @@ class riscv_instr_cover_group;
     cp_mpp  : coverpoint val[12:11];
   endgroup
 
+  `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cg_add.sv")
+
   function new(riscv_instr_gen_config cfg);
+    string opts;
     this.cfg = cfg;
     cur_instr = riscv_instr_cov_item::type_id::create("cur_instr");
     pre_instr = riscv_instr_cov_item::type_id::create("pre_instr");
     build_instr_list();
-    // RV32I instruction functional coverage instantiation
-    add_cg = new();
-    sub_cg = new();
-    addi_cg = new();
-    lui_cg = new();
-    auipc_cg = new();
-    sll_cg = new();
-    srl_cg = new();
-    sra_cg = new();
-    slli_cg = new();
-    srli_cg = new();
-    srai_cg = new();
-    and_cg = new();
-    or_cg = new();
-    xor_cg = new();
-    andi_cg = new();
-    ori_cg = new();
-    xori_cg = new();
-    slt_cg = new();
-    sltu_cg = new();
-    slti_cg = new();
-    sltiu_cg = new();
-    jal_cg = new();
-    jalr_cg = new();
-    beq_cg = new();
-    bne_cg = new();
-    blt_cg = new();
-    bge_cg = new();
-    bgeu_cg = new();
-    bltu_cg = new();
-    lb_cg = new();
-    lh_cg = new();
-    lw_cg = new();
-    lbu_cg = new();
-    lhu_cg = new();
-    sb_cg = new();
-    sh_cg = new();
-    sw_cg = new();
-    csrrw_cg = new();
-    csrrs_cg = new();
-    csrrc_cg = new();
-    csrrwi_cg = new();
-    csrrsi_cg = new();
-    csrrci_cg = new();
-    // instr_trans_cg = new();
-    branch_hit_history_cg = new();
-    rv32i_misc_cg = new();
-    if (RV32C inside {supported_isa}) begin
-      illegal_compressed_instr_cg = new();
-      compressed_opcode_cg = new();
-      hint_cg = new();
+    `ifdef COMPLIANCE_MODE
+      compliance_mode = 1;
+    `endif
+    // process coverage options
+    void'($value$plusargs("iss_mode=%0d", iss_mode));
+
+    if ($value$plusargs("cov_isa=%0s", opts)) begin
+      if (!uvm_enum_wrapper#(riscv_instr_group_t)::from_name(opts, cov_isa)) begin
+        `uvm_fatal("riscv_instr_covergroup",
+                   $sformatf("Cannot find enum for specifed cov_isa=%0s", opts))
+      end
+      select_isa = 1'b1;
     end
-    opcode_cg = new();
-    if (RV32M inside {supported_isa}) begin
+    // TODO if we want to selectively enable/disable coverage based on categories...
+    // e.g. +cov_category=OPV_CONFIG
+    if ($test$plusargs("cov_category=")) begin
+      string cov_category_str;
+      void'($value$plusargs("cov_category=%0s", cov_category_str));
+      $display("coverage option: +cov_category=%0s", cov_category_str);
+      // used to further subset coverage (used by vectors)
+    end
+
+    if ($test$plusargs("stop_on_first_error")) begin
+      $display("coverage option: +stop_on_first_error");
+    end
+
+   `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cg_instantiation.sv")
+
+    // RV32I instruction functional coverage instantiation
+    `CG_SELECTOR_BEGIN(RV32I)
+        add_cg = new();
+        sub_cg = new();
+        addi_cg = new();
+        lui_cg = new();
+        auipc_cg = new();
+        sll_cg = new();
+        srl_cg = new();
+        sra_cg = new();
+        slli_cg = new();
+        srli_cg = new();
+        srai_cg = new();
+        and_cg = new();
+        or_cg = new();
+        xor_cg = new();
+        andi_cg = new();
+        ori_cg = new();
+        xori_cg = new();
+        slt_cg = new();
+        sltu_cg = new();
+        slti_cg = new();
+        sltiu_cg = new();
+        jal_cg = new();
+        jalr_cg = new();
+        beq_cg = new();
+        bne_cg = new();
+        blt_cg = new();
+        bge_cg = new();
+        bgeu_cg = new();
+        bltu_cg = new();
+        lb_cg = new();
+        lh_cg = new();
+        lw_cg = new();
+        lbu_cg = new();
+        lhu_cg = new();
+        sb_cg = new();
+        sh_cg = new();
+        sw_cg = new();
+    `CG_SELECTOR_END
+
+    // TODO sort when there is a RV32ZICSR isa enum
+    if (RV32I inside {supported_isa}) begin
+      if (!compliance_mode) begin
+        csrrw_cg = new();
+        csrrs_cg = new();
+        csrrc_cg = new();
+        csrrwi_cg = new();
+        csrrsi_cg = new();
+        csrrci_cg = new();
+      end
+    end
+
+    if (!compliance_mode) begin
+        // instr_trans_cg = new();
+        branch_hit_history_cg = new();
+        rv32i_misc_cg = new();
+        opcode_cg = new();
+    end
+
+    if (RV32C inside {supported_isa} || RV64C inside {supported_isa}) begin
+      if (!compliance_mode) begin
+        compressed_opcode_cg = new();
+        hint_cg = new();
+        if (!cfg.disable_compressed_instr) begin
+          illegal_compressed_instr_cg = new();
+        end
+      end
+    end
+
+    `CG_SELECTOR_BEGIN(RV32M)
       mul_cg = new();
       mulh_cg = new();
       mulhsu_cg = new();
@@ -872,15 +951,17 @@ class riscv_instr_cover_group;
       divu_cg = new();
       rem_cg = new();
       remu_cg = new();
-    end
-    if (RV64M inside {supported_isa}) begin
+    `CG_SELECTOR_END
+
+    `CG_SELECTOR_BEGIN(RV64M)
       mulw_cg = new();
       divw_cg = new();
       divuw_cg = new();
       remw_cg = new();
       remuw_cg = new();
-    end
-    if (RV64I inside {supported_isa}) begin
+    `CG_SELECTOR_END
+
+    `CG_SELECTOR_BEGIN(RV64I)
       lwu_cg = new();
       ld_cg = new();
       sd_cg = new();
@@ -896,8 +977,9 @@ class riscv_instr_cover_group;
       addw_cg = new();
       addiw_cg = new();
       subw_cg = new();
-    end
-    if (RV32C inside {supported_isa}) begin
+    `CG_SELECTOR_END
+
+    `CG_SELECTOR_BEGIN(RV32C)
       c_lw_cg = new();
       c_sw_cg = new();
       c_lwsp_cg = new();
@@ -925,8 +1007,9 @@ class riscv_instr_cover_group;
       end
       c_jr_cg = new();
       c_jalr_cg = new();
-    end
-    if (RV64C inside {supported_isa}) begin
+    `CG_SELECTOR_END
+
+    `CG_SELECTOR_BEGIN(RV64C)
       c_ld_cg = new();
       c_sd_cg = new();
       c_ldsp_cg = new();
@@ -934,14 +1017,27 @@ class riscv_instr_cover_group;
       c_addiw_cg = new();
       c_subw_cg = new();
       c_addw_cg = new();
+    `CG_SELECTOR_END
+
+    // Ignore the exception which cannot be covered when running with ISS
+    if (iss_mode) begin
+      ignored_exceptions = {INSTRUCTION_ACCESS_FAULT, LOAD_ACCESS_FAULT};
+      if (support_unaligned_load_store) begin
+        ignored_exceptions = {ignored_exceptions, LOAD_ADDRESS_MISALIGNED};
+      end
     end
-    privileged_csr_cg = new();
-    mcause_exception_cg = new();
-    mcause_interrupt_cg = new();
-    if (RV32C inside {supported_isa}) begin
-      mepc_alignment_cg = new();
+
+    if (!compliance_mode) begin
+      privileged_csr_cg = new();
+      mcause_exception_cg = new();
+      if (!iss_mode) begin
+        mcause_interrupt_cg = new();
+      end
+      if (!cfg.disable_compressed_instr) begin
+        mepc_alignment_cg = new();
+      end
+      mstatus_m_cg = new();
     end
-    mstatus_m_cg = new();
   endfunction
 
   function void sample(riscv_instr_cov_item instr);
@@ -950,134 +1046,143 @@ class riscv_instr_cover_group;
       instr.check_hazard_condition(pre_instr);
     end
     if ((instr.binary[1:0] != 2'b11) && (RV32C inside {supported_isa})) begin
-      hint_cg.sample(instr);
-      compressed_opcode_cg.sample(instr.binary[15:0]);
+      if (!compliance_mode) begin
+        hint_cg.sample(instr);
+        compressed_opcode_cg.sample(instr.binary[15:0]);
+      end
     end
     if (instr.binary[1:0] == 2'b11) begin
-      opcode_cg.sample(instr.binary[6:2]);
+      if (!compliance_mode) begin
+        opcode_cg.sample(instr.binary[6:2]);
+      end
     end
     case (instr.instr_name)
-      ADD        : add_cg.sample(instr);
-      SUB        : sub_cg.sample(instr);
-      ADDI       : addi_cg.sample(instr);
-      LUI        : lui_cg.sample(instr);
-      AUIPC      : auipc_cg.sample(instr);
-      SLL        : sll_cg.sample(instr);
-      SRL        : srl_cg.sample(instr);
-      SRA        : sra_cg.sample(instr);
+      ADD        : `SAMPLE(add_cg, instr)
+      SUB        : `SAMPLE(sub_cg, instr)
+      ADDI       : `SAMPLE(addi_cg, instr)
+      LUI        : `SAMPLE(lui_cg, instr)
+      AUIPC      : `SAMPLE(auipc_cg, instr)
+      SLL        : `SAMPLE(sll_cg, instr)
+      SRL        : `SAMPLE(srl_cg, instr)
+      SRA        : `SAMPLE(sra_cg, instr)
       SLLI       : begin
-                     slli_cg.sample(instr);
+                     `SAMPLE(slli_cg, instr)
                      if (RV64I inside {supported_isa}) begin
-                       slli64_cg.sample(instr);
+                       `SAMPLE(slli64_cg, instr)
                      end
                    end
       SRLI       : begin
-                     srli_cg.sample(instr);
+                     `SAMPLE(srli_cg, instr)
                      if (RV64I inside {supported_isa}) begin
-                       srli64_cg.sample(instr);
+                       `SAMPLE(srli64_cg, instr)
                      end
                    end
       SRAI       : begin
-                     srai_cg.sample(instr);
+                     `SAMPLE(srai_cg, instr)
                      if (RV64I inside {supported_isa}) begin
-                       srai64_cg.sample(instr);
+                       `SAMPLE(srai64_cg, instr)
                      end
                    end
-      AND        : and_cg.sample(instr);
-      OR         : or_cg.sample(instr);
-      XOR        : xor_cg.sample(instr);
-      ANDI       : andi_cg.sample(instr);
-      ORI        : ori_cg.sample(instr);
-      XORI       : xori_cg.sample(instr);
-      SLT        : slt_cg.sample(instr);
-      SLTU       : sltu_cg.sample(instr);
-      SLTI       : slti_cg.sample(instr);
-      SLTIU      : sltiu_cg.sample(instr);
-      JAL        : jal_cg.sample(instr);
-      JALR       : jalr_cg.sample(instr);
-      BEQ        : beq_cg.sample(instr);
-      BNE        : bne_cg.sample(instr);
-      BLT        : blt_cg.sample(instr);
-      BGE        : bge_cg.sample(instr);
-      BLTU       : bltu_cg.sample(instr);
-      BGEU       : bgeu_cg.sample(instr);
-      LW         : lw_cg.sample(instr);
-      LH         : lh_cg.sample(instr);
-      LB         : lb_cg.sample(instr);
-      LBU        : lbu_cg.sample(instr);
-      LHU        : lhu_cg.sample(instr);
-      SW         : sw_cg.sample(instr);
-      SH         : sh_cg.sample(instr);
-      SB         : sb_cg.sample(instr);
-      CSRRW      : csrrw_cg.sample(instr);
-      CSRRS      : csrrs_cg.sample(instr);
-      CSRRC      : csrrc_cg.sample(instr);
-      CSRRWI     : csrrwi_cg.sample(instr);
-      CSRRSI     : csrrsi_cg.sample(instr);
-      CSRRCI     : csrrci_cg.sample(instr);
-      MUL        : mul_cg.sample(instr);
-      MULH       : mulh_cg.sample(instr);
-      MULHSU     : mulhsu_cg.sample(instr);
-      MULHU      : mulhu_cg.sample(instr);
-      DIV        : div_cg.sample(instr);
-      DIVU       : divu_cg.sample(instr);
-      REM        : rem_cg.sample(instr);
-      REMU       : remu_cg.sample(instr);
-      MULW       : mulw_cg.sample(instr);
-      DIVW       : divw_cg.sample(instr);
-      DIVUW      : divuw_cg.sample(instr);
-      REMW       : remw_cg.sample(instr);
-      REMUW      : remuw_cg.sample(instr);
-      LWU        : lwu_cg.sample(instr);
-      LD         : ld_cg.sample(instr);
-      SD         : sd_cg.sample(instr);
-      SLLW       : sllw_cg.sample(instr);
-      SLLIW      : slliw_cg.sample(instr);
-      SRLW       : srlw_cg.sample(instr);
-      SRLIW      : srliw_cg.sample(instr);
-      SRAW       : sraw_cg.sample(instr);
-      SRAIW      : sraiw_cg.sample(instr);
-      ADDW       : addw_cg.sample(instr);
-      ADDIW      : addiw_cg.sample(instr);
-      SUBW       : subw_cg.sample(instr);
-      C_LW       : c_lw_cg.sample(instr);
-      C_SW       : c_sw_cg.sample(instr);
-      C_LWSP     : c_lwsp_cg.sample(instr);
-      C_SWSP     : c_swsp_cg.sample(instr);
-      C_ADDI4SPN : c_addi4spn_cg.sample(instr);
-      C_ADDI     : c_addi_cg.sample(instr);
-      C_ADDI16SP : c_addi16sp_cg.sample(instr);
-      C_LI       : c_li_cg.sample(instr);
-      C_LUI      : c_lui_cg.sample(instr);
-      C_SUB      : c_sub_cg.sample(instr);
-      C_ADD      : c_add_cg.sample(instr);
-      C_MV       : c_mv_cg.sample(instr);
-      C_ANDI     : c_andi_cg.sample(instr);
-      C_XOR      : c_xor_cg.sample(instr);
-      C_OR       : c_or_cg.sample(instr);
-      C_AND      : c_and_cg.sample(instr);
-      C_BEQZ     : c_beqz_cg.sample(instr);
-      C_BNEZ     : c_bnez_cg.sample(instr);
-      C_SRLI     : c_srli_cg.sample(instr);
-      C_SRAI     : c_srai_cg.sample(instr);
-      C_SLLI     : c_slli_cg.sample(instr);
-      C_J        : c_j_cg.sample(instr);
-      C_JAL      : c_jal_cg.sample(instr);
-      C_JR       : c_jr_cg.sample(instr);
-      C_JALR     : c_jalr_cg.sample(instr);
-      C_LD       : c_ld_cg.sample(instr);
-      C_SD       : c_sd_cg.sample(instr);
-      C_LDSP     : c_ldsp_cg.sample(instr);
-      C_SDSP     : c_sdsp_cg.sample(instr);
-      C_SUBW     : c_subw_cg.sample(instr);
-      C_ADDW     : c_addw_cg.sample(instr);
-      C_ADDIW    : c_addiw_cg.sample(instr);
+      AND        : `SAMPLE(and_cg, instr)
+      OR         : `SAMPLE(or_cg, instr)
+      XOR        : `SAMPLE(xor_cg, instr)
+      ANDI       : `SAMPLE(andi_cg, instr)
+      ORI        : `SAMPLE(ori_cg, instr)
+      XORI       : `SAMPLE(xori_cg, instr)
+      SLT        : `SAMPLE(slt_cg, instr)
+      SLTU       : `SAMPLE(sltu_cg, instr)
+      SLTI       : `SAMPLE(slti_cg, instr)
+      SLTIU      : `SAMPLE(sltiu_cg, instr)
+      JAL        : `SAMPLE(jal_cg, instr)
+      JALR       : `SAMPLE(jalr_cg, instr)
+      BEQ        : `SAMPLE(beq_cg, instr)
+      BNE        : `SAMPLE(bne_cg, instr)
+      BLT        : `SAMPLE(blt_cg, instr)
+      BGE        : `SAMPLE(bge_cg, instr)
+      BLTU       : `SAMPLE(bltu_cg, instr)
+      BGEU       : `SAMPLE(bgeu_cg, instr)
+      LW         : `SAMPLE(lw_cg, instr)
+      LH         : `SAMPLE(lh_cg, instr)
+      LB         : `SAMPLE(lb_cg, instr)
+      LBU        : `SAMPLE(lbu_cg, instr)
+      LHU        : `SAMPLE(lhu_cg, instr)
+      SW         : `SAMPLE(sw_cg, instr)
+      SH         : `SAMPLE(sh_cg, instr)
+      SB         : `SAMPLE(sb_cg, instr)
+      CSRRW      : `SAMPLE(csrrw_cg, instr)
+      CSRRS      : `SAMPLE(csrrs_cg, instr)
+      CSRRC      : `SAMPLE(csrrc_cg, instr)
+      CSRRWI     : `SAMPLE(csrrwi_cg, instr)
+      CSRRSI     : `SAMPLE(csrrsi_cg, instr)
+      CSRRCI     : `SAMPLE(csrrci_cg, instr)
+      MUL        : `SAMPLE(mul_cg, instr)
+      MULH       : `SAMPLE(mulh_cg, instr)
+      MULHSU     : `SAMPLE(mulhsu_cg, instr)
+      MULHU      : `SAMPLE(mulhu_cg, instr)
+      DIV        : `SAMPLE(div_cg, instr)
+      DIVU       : `SAMPLE(divu_cg, instr)
+      REM        : `SAMPLE(rem_cg, instr)
+      REMU       : `SAMPLE(remu_cg, instr)
+      MULW       : `SAMPLE(mulw_cg, instr)
+      DIVW       : `SAMPLE(divw_cg, instr)
+      DIVUW      : `SAMPLE(divuw_cg, instr)
+      REMW       : `SAMPLE(remw_cg, instr)
+      REMUW      : `SAMPLE(remuw_cg, instr)
+      LWU        : `SAMPLE(lwu_cg, instr)
+      LD         : `SAMPLE(ld_cg, instr)
+      SD         : `SAMPLE(sd_cg, instr)
+      SLLW       : `SAMPLE(sllw_cg, instr)
+      SLLIW      : `SAMPLE(slliw_cg, instr)
+      SRLW       : `SAMPLE(srlw_cg, instr)
+      SRLIW      : `SAMPLE(srliw_cg, instr)
+      SRAW       : `SAMPLE(sraw_cg, instr)
+      SRAIW      : `SAMPLE(sraiw_cg, instr)
+      ADDW       : `SAMPLE(addw_cg, instr)
+      ADDIW      : `SAMPLE(addiw_cg, instr)
+      SUBW       : `SAMPLE(subw_cg, instr)
+      C_LW       : `SAMPLE(c_lw_cg, instr)
+      C_SW       : `SAMPLE(c_sw_cg, instr)
+      C_LWSP     : `SAMPLE(c_lwsp_cg, instr)
+      C_SWSP     : `SAMPLE(c_swsp_cg, instr)
+      C_ADDI4SPN : `SAMPLE(c_addi4spn_cg, instr)
+      C_ADDI     : `SAMPLE(c_addi_cg, instr)
+      C_ADDI16SP : `SAMPLE(c_addi16sp_cg, instr)
+      C_LI       : `SAMPLE(c_li_cg, instr)
+      C_LUI      : `SAMPLE(c_lui_cg, instr)
+      C_SUB      : `SAMPLE(c_sub_cg, instr)
+      C_ADD      : `SAMPLE(c_add_cg, instr)
+      C_MV       : `SAMPLE(c_mv_cg, instr)
+      C_ANDI     : `SAMPLE(c_andi_cg, instr)
+      C_XOR      : `SAMPLE(c_xor_cg, instr)
+      C_OR       : `SAMPLE(c_or_cg, instr)
+      C_AND      : `SAMPLE(c_and_cg, instr)
+      C_BEQZ     : `SAMPLE(c_beqz_cg, instr)
+      C_BNEZ     : `SAMPLE(c_bnez_cg, instr)
+      C_SRLI     : `SAMPLE(c_srli_cg, instr)
+      C_SRAI     : `SAMPLE(c_srai_cg, instr)
+      C_SLLI     : `SAMPLE(c_slli_cg, instr)
+      C_J        : `SAMPLE(c_j_cg, instr)
+      C_JAL      : `SAMPLE(c_jal_cg, instr)
+      C_JR       : `SAMPLE(c_jr_cg, instr)
+      C_JALR     : `SAMPLE(c_jalr_cg, instr)
+      C_LD       : `SAMPLE(c_ld_cg, instr)
+      C_SD       : `SAMPLE(c_sd_cg, instr)
+      C_LDSP     : `SAMPLE(c_ldsp_cg, instr)
+      C_SDSP     : `SAMPLE(c_sdsp_cg, instr)
+      C_SUBW     : `SAMPLE(c_subw_cg, instr)
+      C_ADDW     : `SAMPLE(c_addw_cg, instr)
+      C_ADDIW    : `SAMPLE(c_addiw_cg, instr)
+      `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cg_sample.sv")
       default: begin
         if (RV32C inside {supported_isa}) begin
-          illegal_compressed_instr_cg.sample(instr.binary);
+          if (!compliance_mode) begin
+            illegal_compressed_instr_cg.sample(instr.binary);
+          end
         end
         if (instr.group == RV32I) begin
-          rv32i_misc_cg.sample(instr);
+          if (!compliance_mode) begin
+            rv32i_misc_cg.sample(instr);
+          end
         end
       end
     endcase
@@ -1085,39 +1190,54 @@ class riscv_instr_cover_group;
       branch_hit_history = (branch_hit_history << 1) | instr.branch_hit;
       branch_instr_cnt += 1;
       if (branch_instr_cnt >= $bits(branch_hit_history)) begin
-        branch_hit_history_cg.sample();
+        if (!compliance_mode) begin
+          branch_hit_history_cg.sample();
+        end
       end
     end
     if (instr.category == CSR) begin
-      privileged_csr_cg.sample(instr.csr);
+      if (!compliance_mode) begin
+        privileged_csr_cg.sample(instr.csr);
+      end
       case (instr.csr)
         MCAUSE: begin
           if (instr.rd_value[XLEN-1]) begin
             interrupt_cause_t interrupt;
             if ($cast(interrupt, instr.rd_value[3:0])) begin
-              mcause_interrupt_cg.sample(interrupt);
+              if (!compliance_mode && !iss_mode) begin
+                mcause_interrupt_cg.sample(interrupt);
+              end
             end
           end else begin
             exception_cause_t exception;
             if ($cast(exception, instr.rd_value[3:0])) begin
-              mcause_exception_cg.sample(exception);
+              if (!compliance_mode) begin
+                mcause_exception_cg.sample(exception);
+              end
             end
           end
         end
         MEPC: begin
           if (RV32C inside {supported_isa}) begin
-            mepc_alignment_cg.sample(instr.rd_value);
+            if (!compliance_mode) begin
+              mepc_alignment_cg.sample(instr.rd_value);
+            end
           end
         end
         MSTATUS: begin
-          mstatus_m_cg.sample(instr.rd_value);
+          if (!compliance_mode) begin
+            mstatus_m_cg.sample(instr.rd_value);
+          end
         end
       endcase
     end
     if (instr_cnt > 1) begin
-      // instr_trans_cg.sample();
+      if (!compliance_mode) begin
+        //instr_trans_cg.sample();
+      end
     end
-    pre_instr.copy_base_instr(instr);
+   `VECTOR_INCLUDE("riscv_instr_cover_group_inc_sample.sv")
+    pre_instr.copy(instr);
     pre_instr.mem_addr = instr.mem_addr;
   endfunction
 
@@ -1144,15 +1264,20 @@ class riscv_instr_cover_group;
     riscv_instr_name_t instr_name;
     instr_name = instr_name.first;
     do begin
-      riscv_instr_base instr;
+      `INSTR instr;
       if (!(instr_name inside {unsupported_instr}) && (instr_name != INVALID_INSTR)) begin
-        instr = riscv_instr_base::type_id::create("instr");
-        if (!instr.randomize() with {instr_name == local::instr_name;}) begin
-          `uvm_fatal("riscv_instr_cover_group",
-                     $sformatf("Instruction %0s randomization failure", instr_name.name()))
-        end
+        `ifdef DEPRECATED
+          instr = riscv_instr_base::type_id::create("instr");
+          if (!instr.randomize() with {instr_name == local::instr_name;}) begin
+            `uvm_fatal("riscv_instr_cover_group",
+                       $sformatf("Instruction %0s randomization failure", instr_name.name()))
+          end
+        `else
+          instr = riscv_instr::create_instr(instr_name);
+        `endif
         if ((instr.group inside {supported_isa}) &&
-            (instr.group inside {RV32I, RV32M, RV64M, RV64I, RV32C, RV64C})) begin
+            (instr.group inside {RV32I, RV32M, RV64M, RV64I, RV32C, RV64C,
+                                 RV32V, RV64V, RV64B, RV32B})) begin
           if (((instr_name inside {URET}) && !support_umode_trap) ||
               ((instr_name inside {SRET, SFENCE_VMA}) &&
               !(SUPERVISOR_MODE inside {supported_privileged_mode})) ||
@@ -1174,6 +1299,13 @@ class riscv_instr_cover_group;
     instr_cnt = 0;
     branch_instr_cnt = 0;
     branch_hit_history = '0;
+    `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cpu_reset.sv")
+  endfunction
+
+  function void fatal(string str);
+    if ($test$plusargs("stop_on_first_error")) begin
+      `uvm_fatal("riscv_instr_cover_group", $sformatf("FATAL Error: %0s", str))
+    end
   endfunction
 
 endclass
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 a0528db0..7cceba50 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv
+++ b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv
@@ -116,14 +116,6 @@ class riscv_instr_gen_config extends uvm_object;
   // Number of instructions for each kernel program
   int kernel_program_instr_cnt = 400;
 
-  //-----------------------------------------------------------------------------
-  // Instruction list based on the config, generate by build_instruction_template
-  //-----------------------------------------------------------------------------
-  riscv_instr_base       instr_template[riscv_instr_name_t];
-  riscv_instr_name_t     basic_instr[$];
-  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[$];
@@ -390,8 +382,54 @@ class riscv_instr_gen_config extends uvm_object;
   }
 
   `uvm_object_utils_begin(riscv_instr_gen_config)
-    `uvm_field_int(main_program_instr_cnt,       UVM_DEFAULT)
+    `uvm_field_int(main_program_instr_cnt, UVM_DEFAULT)
     `uvm_field_sarray_int(sub_program_instr_cnt, UVM_DEFAULT)
+    `uvm_field_int(debug_program_instr_cnt, UVM_DEFAULT)
+    `uvm_field_enum(data_pattern_t, data_page_pattern, UVM_DEFAULT)
+    `uvm_field_enum(privileged_mode_t, init_privileged_mode, UVM_DEFAULT)
+    `uvm_field_array_enum(riscv_reg_t, reserved_regs, UVM_DEFAULT)
+    `uvm_field_enum(riscv_reg_t, ra, UVM_DEFAULT)
+    `uvm_field_enum(riscv_reg_t, sp, UVM_DEFAULT)
+    `uvm_field_enum(riscv_reg_t, tp, UVM_DEFAULT)
+    `uvm_field_int(no_data_page, UVM_DEFAULT)
+    `uvm_field_int(no_branch_jump, UVM_DEFAULT)
+    `uvm_field_int(no_load_store, UVM_DEFAULT)
+    `uvm_field_int(no_csr_instr, UVM_DEFAULT)
+    `uvm_field_int(no_ebreak, UVM_DEFAULT)
+    `uvm_field_int(no_dret, UVM_DEFAULT)
+    `uvm_field_int(no_fence, UVM_DEFAULT)
+    `uvm_field_int(no_wfi, UVM_DEFAULT)
+    `uvm_field_int(enable_unaligned_load_store, UVM_DEFAULT)
+    `uvm_field_int(illegal_instr_ratio, UVM_DEFAULT)
+    `uvm_field_int(hint_instr_ratio, UVM_DEFAULT)
+    `uvm_field_string(boot_mode_opts, UVM_DEFAULT)
+    `uvm_field_int(enable_page_table_exception, UVM_DEFAULT)
+    `uvm_field_int(no_directed_instr, UVM_DEFAULT)
+    `uvm_field_int(enable_interrupt, UVM_DEFAULT)
+    `uvm_field_int(enable_timer_irq, UVM_DEFAULT)
+    `uvm_field_int(bare_program_mode, UVM_DEFAULT)
+    `uvm_field_int(enable_illegal_csr_instruction, UVM_DEFAULT)
+    `uvm_field_int(enable_access_invalid_csr_level, UVM_DEFAULT)
+    `uvm_field_int(enable_dummy_csr_write, UVM_DEFAULT)
+    `uvm_field_int(randomize_csr, UVM_DEFAULT)
+    `uvm_field_int(allow_sfence_exception, UVM_DEFAULT)
+    `uvm_field_int(no_delegation, UVM_DEFAULT)
+    `uvm_field_int(force_m_delegation, UVM_DEFAULT)
+    `uvm_field_int(force_s_delegation, UVM_DEFAULT)
+    `uvm_field_int(support_supervisor_mode, UVM_DEFAULT)
+    `uvm_field_int(disable_compressed_instr, UVM_DEFAULT)
+    `uvm_field_int(signature_addr, UVM_DEFAULT)
+    `uvm_field_int(require_signature_addr, UVM_DEFAULT)
+    `uvm_field_int(gen_debug_section, UVM_DEFAULT)
+    `uvm_field_int(enable_ebreak_in_debug_rom, UVM_DEFAULT)
+    `uvm_field_int(set_dcsr_ebreak, UVM_DEFAULT)
+    `uvm_field_int(num_debug_sub_program, UVM_DEFAULT)
+    `uvm_field_int(enable_debug_single_step, UVM_DEFAULT)
+    `uvm_field_int(single_step_iterations, UVM_DEFAULT)
+    `uvm_field_int(set_mstatus_tw, UVM_DEFAULT)
+    `uvm_field_int(max_branch_step, UVM_DEFAULT)
+    `uvm_field_int(max_directed_instr_stream_seq, UVM_DEFAULT)
+    `uvm_field_int(enable_floating_point, UVM_DEFAULT)
   `uvm_object_utils_end
 
   function new (string name = "");
@@ -539,6 +577,10 @@ class riscv_instr_gen_config extends uvm_object;
     min_stack_len_per_program = 2 * (XLEN/8);
     // Check if the setting is legal
     check_setting();
+    // WFI is not supported in umode
+    if (init_privileged_mode == USER_MODE) begin
+      no_wfi = 1'b1;
+    end
   endfunction
 
   function void check_setting();
@@ -569,7 +611,8 @@ class riscv_instr_gen_config extends uvm_object;
   // TODO(udi) - include performance/pmp/trigger CSRs?
   virtual function void get_invalid_priv_lvl_csr();
     string invalid_lvl[$];
-    string csr;
+    string csr_name;
+    privileged_reg_t 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)
@@ -587,8 +630,9 @@ class riscv_instr_gen_config extends uvm_object;
       end
     endcase
     foreach (implemented_csr[i]) begin
-      csr = implemented_csr[i].name();
-      if (csr[0] inside {invalid_lvl}) begin
+      privileged_reg_t csr = implemented_csr[i];
+      csr_name = csr.name();
+      if (csr_name[0] inside {invalid_lvl}) begin
         invalid_priv_mode_csrs.push_back(implemented_csr[i]);
       end
     end
@@ -618,73 +662,4 @@ class riscv_instr_gen_config extends uvm_object;
     end
   endfunction
 
-  // Build instruction template
-  virtual function void build_instruction_template(bit skip_instr_exclusion = 0);
-    riscv_instr_name_t instr_name;
-    riscv_instr_name_t excluded_instr[$];
-    excluded_instr = {INVALID_INSTR};
-    if (!skip_instr_exclusion) begin
-      get_excluded_instr(excluded_instr);
-    end
-    instr_name = instr_name.first;
-    do begin
-      riscv_instr_base instr;
-      if (!(instr_name inside {unsupported_instr, excluded_instr})) begin
-        instr = riscv_instr_base::type_id::create("instr");
-        `DV_CHECK_RANDOMIZE_WITH_FATAL(instr, instr_name == local::instr_name;)
-        if ((instr.group inside {supported_isa}) &&
-            !(disable_compressed_instr && instr.is_compressed) &&
-            !(!enable_floating_point && (instr.group inside {RV32F, RV64F, RV32D, RV64D}))) begin
-          `uvm_info(`gfn, $sformatf("Adding [%s] %s to the list",
-                          instr.group.name(), instr.instr_name.name()), UVM_HIGH)
-          instr_group[instr.group].push_back(instr_name);
-          instr_category[instr.category].push_back(instr_name);
-          instr_template[instr_name] = instr;
-        end
-      end
-      instr_name = instr_name.next;
-    end
-    while (instr_name != instr_name.first);
-  endfunction
-
-  virtual function void build_instruction_list();
-    basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
-                   instr_category[LOGICAL], instr_category[COMPARE]};
-    basic_instr = {basic_instr, EBREAK};
-    foreach(riscv_instr_pkg::supported_isa[i]) begin
-      if (riscv_instr_pkg::supported_isa[i] inside {RV32C, RV64C, RV128C, RV32DC, RV32FC}) begin
-        basic_instr = {basic_instr, C_EBREAK};
-        break;
-      end
-    end
-    if (no_dret == 0) begin
-      basic_instr = {basic_instr, DRET};
-    end
-    if (no_fence == 0) begin
-      basic_instr = {basic_instr, instr_category[SYNCH]};
-    end
-    // TODO: Support CSR instruction in other mode
-    if ((no_csr_instr == 0) && (init_privileged_mode == MACHINE_MODE)) begin
-      `uvm_info(`gfn, $sformatf("Adding CSR instr, mode: %0s", init_privileged_mode.name()), UVM_LOW)
-      basic_instr = {basic_instr, instr_category[CSR]};
-    end
-    if (no_wfi == 0) begin
-      basic_instr = {basic_instr, WFI};
-    end
-  endfunction
-
-  virtual function void get_excluded_instr(ref riscv_instr_name_t excluded[$]);
-    // Below instrutions will modify stack pointer, not allowed in normal instruction stream.
-    // It can be used in stack operation instruction stream.
-    excluded = {excluded, C_SWSP, C_SDSP, C_ADDI16SP};
-    if (!enable_sfence) begin
-      excluded = {excluded, SFENCE_VMA};
-    end
-    if (no_fence) begin
-      excluded = {excluded, FENCE, FENCE_I, SFENCE_VMA};
-    end
-    // TODO: Support C_ADDI4SPN
-    excluded = {excluded, C_ADDI4SPN};
-  endfunction
-
 endclass
diff --git a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
index 6439deb0..fa7d1b9a 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
+++ b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
@@ -86,7 +86,11 @@ package riscv_instr_pkg;
     RV32C,
     RV64C,
     RV128I,
-    RV128C
+    RV128C,
+    RV32V,
+    RV32B,
+    RV64V,
+    RV64B
   } riscv_instr_group_t;
 
   typedef enum {
@@ -318,6 +322,7 @@ package riscv_instr_pkg;
     SRET,
     WFI,
     SFENCE_VMA,
+    `VECTOR_INCLUDE("riscv_instr_pkg_inc_riscv_instr_name_t.sv")
     // You can add other instructions here
     INVALID_INSTR
   } riscv_instr_name_t;
@@ -331,12 +336,14 @@ package riscv_instr_pkg;
     S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
   } riscv_reg_t;
 
+  `VECTOR_INCLUDE("riscv_instr_pkg_inc_enum.sv")
+
   typedef enum bit [4:0] {
     F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
     F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31
   } riscv_fpr_t;
 
-  typedef enum bit [3:0] {
+  typedef enum bit [5:0] {
     J_FORMAT = 0,
     U_FORMAT,
     I_FORMAT,
@@ -352,10 +359,11 @@ package riscv_instr_pkg;
     CL_FORMAT,
     CS_FORMAT,
     CSS_FORMAT,
-    CIW_FORMAT
+    `VECTOR_INCLUDE("riscv_instr_pkg_inc_riscv_instr_format_t.sv")
+    CIW_FORMAT // (last one)
   } riscv_instr_format_t;
 
-  typedef enum bit [3:0] {
+  typedef enum bit [5:0] {
     LOAD = 0,
     STORE,
     SHIFT,
@@ -371,7 +379,8 @@ package riscv_instr_pkg;
     CHANGELEVEL,
     TRAP,
     INTERRUPT,
-    AMO
+    `VECTOR_INCLUDE("riscv_instr_pkg_inc_riscv_instr_category_t.sv")
+    AMO // (last one)
   } riscv_instr_category_t;
 
   typedef bit [11:0] riscv_csr_t;
@@ -602,7 +611,8 @@ package riscv_instr_pkg;
     DCSR            = 'h7B0,  // Debug control and status register
     DPC             = 'h7B1,  // Debug PC
     DSCRATCH0       = 'h7B2,  // Debug scratch register
-    DSCRATCH1       = 'h7B3   // Debug scratch register
+    `VECTOR_INCLUDE("riscv_instr_pkg_inc_privileged_reg_t.sv")
+    DSCRATCH1       = 'h7B3  // Debug scratch register (last one)
   } privileged_reg_t;
 
   typedef enum bit [5:0] {
@@ -715,6 +725,21 @@ package riscv_instr_pkg;
 
   `include "riscv_core_setting.sv"
 
+  // TODO hardware target definition so should move to riscv_core_setting.sv
+  `ifdef ENABLE_VECTORS
+    parameter bit has_vector_engine = 'b1;
+    parameter int VLEN = `VLEN;
+    parameter int ELEN = `ELEN;
+    parameter int SLEN = `SLEN;
+  `else
+    parameter bit has_vector_engine = 'b0;
+    parameter int VLEN = 512;
+    parameter int ELEN = 64;
+    parameter int SLEN = 64;
+  `endif
+
+  `VECTOR_INCLUDE("riscv_instr_pkg_inc_variables.sv")
+
   typedef bit [15:0] program_id_t;
 
   // xSTATUS bit mask
@@ -844,8 +869,42 @@ package riscv_instr_pkg;
 
   riscv_reg_t compressed_gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5};
 
-  `include "riscv_instr_base.sv"
-  `include "riscv_instr_gen_config.sv"
+  riscv_instr_category_t all_categories[] = {
+    LOAD, STORE, SHIFT, ARITHMETIC, LOGICAL, COMPARE, BRANCH, JUMP,
+    SYNCH, SYSTEM, COUNTER, CSR, CHANGELEVEL, TRAP, INTERRUPT, AMO
+  };
+
+  `ifdef DEPRECATED
+    `define INSTR riscv_instr_base
+    `include "deprecated/riscv_instr_base.sv"
+    `include "deprecated/riscv_instr_gen_config.sv"
+  `else
+    `define INSTR riscv_instr
+    typedef class riscv_instr;
+    `include "riscv_instr_gen_config.sv"
+    `include "isa/riscv_instr.sv"
+    `include "isa/riscv_amo_instr.sv"
+    `include "isa/riscv_floating_point_instr.sv"
+    `include "isa/riscv_vector_instr.sv"
+    `include "isa/riscv_compressed_instr.sv"
+    `include "isa/rv32a_instr.sv"
+    `include "isa/rv32c_instr.sv"
+    `include "isa/rv32dc_instr.sv"
+    `include "isa/rv32d_instr.sv"
+    `include "isa/rv32fc_instr.sv"
+    `include "isa/rv32f_instr.sv"
+    `include "isa/rv32i_instr.sv"
+    `include "isa/rv32m_instr.sv"
+    `include "isa/rv64a_instr.sv"
+    `include "isa/rv64c_instr.sv"
+    `include "isa/rv64d_instr.sv"
+    `include "isa/rv64f_instr.sv"
+    `include "isa/rv64i_instr.sv"
+    `include "isa/rv64m_instr.sv"
+    `include "isa/rv128c_instr.sv"
+  `endif
+
+  `include "riscv_pseudo_instr.sv"
   `include "riscv_illegal_instr.sv"
   `include "riscv_reg.sv"
   `include "riscv_privil_reg.sv"
@@ -856,14 +915,25 @@ package riscv_instr_pkg;
   `include "riscv_privileged_common_seq.sv"
   `include "riscv_callstack_gen.sv"
   `include "riscv_data_page_gen.sv"
-  `include "riscv_rand_instr.sv"
+
+`ifdef DEPRECATED
+  `include "deprecated/riscv_rand_instr.sv"
+  `include "deprecated/riscv_instr_stream.sv"
+  `include "deprecated/riscv_loop_instr.sv"
+  `include "deprecated/riscv_directed_instr_lib.sv"
+  `include "deprecated/riscv_load_store_instr_lib.sv"
+  `include "deprecated/riscv_amo_instr_lib.sv"
+`else
   `include "riscv_instr_stream.sv"
   `include "riscv_loop_instr.sv"
   `include "riscv_directed_instr_lib.sv"
   `include "riscv_load_store_instr_lib.sv"
   `include "riscv_amo_instr_lib.sv"
+`endif
+
   `include "riscv_instr_sequence.sv"
   `include "riscv_asm_program_gen.sv"
+  `include "riscv_debug_rom_gen.sv"
   `include "riscv_instr_cov_item.sv"
   `include "riscv_instr_cover_group.sv"
   `include "user_extension.svh"
diff --git a/vendor/google_riscv-dv/src/riscv_instr_stream.sv b/vendor/google_riscv-dv/src/riscv_instr_stream.sv
index a38c4e9a..2b53985d 100644
--- a/vendor/google_riscv-dv/src/riscv_instr_stream.sv
+++ b/vendor/google_riscv-dv/src/riscv_instr_stream.sv
@@ -20,7 +20,7 @@
 // instruction, mix two instruction streams etc.
 class riscv_instr_stream extends uvm_object;
 
-  riscv_instr_base      instr_list[$];
+  `INSTR                instr_list[$];
   int unsigned          instr_cnt;
   string                label = "";
   // User can specify a small group of available registers to generate various hazard condition
@@ -40,16 +40,16 @@ class riscv_instr_stream extends uvm_object;
   endfunction
 
   virtual function void create_instr_instance();
-    riscv_instr_base instr;
+    `INSTR instr;
     for(int i = 0; i < instr_cnt; i++) begin
-      instr = riscv_instr_base::type_id::create($sformatf("instr_%0d", i));
+      instr = `INSTR::type_id::create($sformatf("instr_%0d", i));
       instr_list.push_back(instr);
     end
   endfunction
 
   // Insert an instruction to the existing instruction stream at the given index
   // When index is -1, the instruction is injected at a random location
-  function void insert_instr(riscv_instr_base instr, int idx = -1);
+  function void insert_instr(`INSTR instr, int idx = -1);
     int current_instr_cnt = instr_list.size();
     if(idx == -1) begin
       idx = $urandom_range(0, current_instr_cnt-1);
@@ -70,7 +70,7 @@ class riscv_instr_stream extends uvm_object;
   // Insert an instruction to the existing instruction stream at the given index
   // When index is -1, the instruction is injected at a random location
   // When replace is 1, the original instruction at the inserted position will be replaced
-  function void insert_instr_stream(riscv_instr_base new_instr[], int idx = -1, bit replace = 1'b0);
+  function void insert_instr_stream(`INSTR new_instr[], int idx = -1, bit replace = 1'b0);
     int current_instr_cnt = instr_list.size();
     int new_instr_cnt = new_instr.size();
     if(current_instr_cnt == 0) begin
@@ -119,7 +119,7 @@ class riscv_instr_stream extends uvm_object;
   // Mix the input instruction stream with the original instruction, the instruction order is
   // preserved. When 'contained' is set, the original instruction stream will be inside the
   // new instruction stream with the first and last instruction from the input instruction stream.
-  function void mix_instr_stream(riscv_instr_base new_instr[], bit contained = 1'b0);
+  function void mix_instr_stream(`INSTR new_instr[], bit contained = 1'b0);
     int current_instr_cnt = instr_list.size();
     int insert_instr_position[];
     int new_instr_cnt = new_instr.size();
@@ -167,25 +167,25 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
   `uvm_object_new
 
   virtual function void create_instr_instance();
-    riscv_instr_base instr;
-    for(int i = 0; i < instr_cnt; i++) begin
-      instr = riscv_instr_base::type_id::create($sformatf("instr_%0d", i));
-      instr_list.push_back(instr);
+    `INSTR instr;
+    for (int i = 0; i < instr_cnt; i++) begin
+      instr_list.push_back(null);
     end
   endfunction
 
   virtual function void setup_allowed_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1);
-    allowed_instr = cfg.basic_instr;
+    allowed_instr = riscv_instr::basic_instr;
     if (no_branch == 0) begin
-      allowed_instr = {allowed_instr, cfg.instr_category[BRANCH]};
+      allowed_instr = {allowed_instr, riscv_instr::instr_category[BRANCH]};
     end
     if (no_load_store == 0) begin
-      allowed_instr = {allowed_instr, cfg.instr_category[LOAD], cfg.instr_category[STORE]};
+      allowed_instr = {allowed_instr, riscv_instr::instr_category[LOAD],
+                                      riscv_instr::instr_category[STORE]};
     end
     setup_instruction_dist(no_branch, no_load_store);
   endfunction
 
-  function setup_instruction_dist(bit no_branch = 1'b0, bit no_load_store = 1'b1);
+  function void setup_instruction_dist(bit no_branch = 1'b0, bit no_load_store = 1'b1);
     if (cfg.dist_control_mode) begin
       category_dist = cfg.category_dist;
       if (no_branch) begin
@@ -213,94 +213,51 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
     end
   endfunction
 
-  function void randomize_instr(riscv_instr_base instr,
-                                bit is_in_debug = 1'b0,
-                                bit skip_rs1 = 1'b0,
-                                bit skip_rs2 = 1'b0,
-                                bit skip_rd  = 1'b0,
-                                bit skip_imm = 1'b0,
-                                bit skip_csr = 1'b0,
-                                bit disable_dist = 1'b0);
-    riscv_instr_name_t instr_name;
-    if ((cfg.dist_control_mode == 1) && !disable_dist) begin
-      riscv_instr_category_t category;
-      int unsigned idx;
-      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(category,
-        category dist {LOAD       := category_dist[LOAD],
-                       STORE      := category_dist[STORE],
-                       SHIFT      := category_dist[SHIFT],
-                       ARITHMETIC := category_dist[ARITHMETIC],
-                       LOGICAL    := category_dist[LOGICAL],
-                       COMPARE    := category_dist[COMPARE],
-                       BRANCH     := category_dist[BRANCH],
-                       SYNCH      := category_dist[SYNCH],
-                       CSR        := category_dist[CSR]};)
-      idx = $urandom_range(0, cfg.instr_category[category].size() - 1);
-      instr_name = cfg.instr_category[category][idx];
-    // if set_dcsr_ebreak is set, we do not want to generate any ebreak
-    // instructions inside the debug_rom
-    end else if ((cfg.no_ebreak && !is_in_debug) ||
-                 (!cfg.enable_ebreak_in_debug_rom && is_in_debug)) begin
-      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(instr_name,
-                                        instr_name inside {allowed_instr};
-                                        !(instr_name inside {EBREAK, C_EBREAK});)
-    end else begin
-      `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(instr_name,
-                                         instr_name inside {allowed_instr};)
-    end
-    instr.copy_base_instr(cfg.instr_template[instr_name]);
-    `uvm_info(`gfn, $sformatf("%s: rs1:%0d, rs2:%0d, rd:%0d, imm:%0d",
-                              instr.instr_name.name(),
-                              instr.has_rs1,
-                              instr.has_rs2,
-                              instr.has_rd,
-                              instr.has_imm), UVM_FULL)
-    if (instr.has_imm && !skip_imm) begin
-      instr.gen_rand_imm();
-    end
-    if (instr.has_rs1 && !skip_rs1) begin
-      if (instr.is_compressed) begin
-        // Compressed instruction could use the same register for rs1 and rd
-        instr.rs1 = instr.gen_rand_gpr(
-                         .included_reg(avail_regs),
-                         .excluded_reg({reserved_rd, cfg.reserved_regs}));
-      end else begin
-        instr.rs1 = instr.gen_rand_gpr(.included_reg(avail_regs));
-      end
-    end
-    if (instr.has_rs2 && !skip_rs2) begin
-      instr.rs2 = instr.gen_rand_gpr(.included_reg(avail_regs));
-    end
-    if (instr.has_rd && !skip_rd) begin
-      if (instr_name == C_LUI) begin
-        instr.rd = instr.gen_rand_gpr(
-                        .included_reg(avail_regs),
-                        .excluded_reg({reserved_rd, cfg.reserved_regs, SP}));
-      end else begin
-        instr.rd = instr.gen_rand_gpr(
-                        .included_reg(avail_regs),
-                        .excluded_reg({reserved_rd, cfg.reserved_regs}));
-      end
-    end
-    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),
-                         .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();
-    end
-    if (instr.has_fs2) begin
-      instr.fs2 = instr.gen_rand_fpr();
-    end
-    if (instr.has_fs3) begin
-      instr.fs3 = instr.gen_rand_fpr();
-    end
-    if (instr.has_fd) begin
-      instr.fd = instr.gen_rand_fpr();
+  function void randomize_instr(output riscv_instr instr,
+                                input  bit is_in_debug = 1'b0,
+                                input  bit disable_dist = 1'b0);
+    riscv_instr_name_t exclude_instr[];
+    if ((SP inside {reserved_rd, cfg.reserved_regs}) ||
+        ((avail_regs.size() > 0) && !(SP inside {avail_regs}))) begin
+      exclude_instr = {C_ADDI4SPN, C_ADDI16SP, C_LWSP, C_LDSP};
     end
+    instr = riscv_instr::get_rand_instr(.include_instr(allowed_instr),
+                                        .exclude_instr(exclude_instr));
+    randomize_gpr(instr);
   endfunction
 
+  function void randomize_gpr(ref riscv_instr instr);
+    `DV_CHECK_RANDOMIZE_WITH_FATAL(instr,
+      if (avail_regs.size() > 0) {
+        if (has_rs1) {
+          rs1 inside {avail_regs};
+        }
+        if (has_rs2) {
+          rs2 inside {avail_regs};
+        }
+        if (has_rd) {
+          rd  inside {avail_regs};
+        }
+      }
+      if (reserved_rd.size() > 0) {
+        if (has_rd) {
+          !(rd inside {reserved_rd});
+        }
+        if (format == CB_FORMAT) {
+          !(rs1 inside {reserved_rd});
+        }
+      }
+      if (cfg.reserved_regs.size() > 0) {
+        if (has_rd) {
+          !(rd inside {cfg.reserved_regs});
+        }
+        if (format == CB_FORMAT) {
+          !(rs1 inside {cfg.reserved_regs});
+        }
+      }
+      // TODO: Add constraint for CSR, floating point register
+    )
+  endfunction
+
+
 endclass
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 92b05706..0c3e0712 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,14 +30,23 @@ 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[$];
+  riscv_instr        load_store_instr[$];
   rand int unsigned  data_page_id;
   rand riscv_reg_t   rs1_reg;
   rand locality_e    locality;
   rand int           max_load_store_offset;
+  rand bit           use_sp_as_rs1;
 
   `uvm_object_utils(riscv_load_store_base_instr_stream)
 
+  constraint sp_c {
+    solve use_sp_as_rs1 before rs1_reg;
+    use_sp_as_rs1 dist {1 := 1, 0 := 2};
+    if (use_sp_as_rs1) {
+      rs1_reg == SP;
+    }
+  }
+
   constraint rs1_c {
     !(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
   }
@@ -64,7 +73,6 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
     addr = new[num_load_store];
     for (int i=0; i 0) begin
       `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
                                          unique{avail_regs};
@@ -109,11 +125,10 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
                                          },
                                          "Cannot randomize avail_regs")
     end
-    if ((rs1_reg inside {[S0 : A5]}) && !cfg.disable_compressed_instr) begin
+    if ((rs1_reg inside {[S0 : A5], SP}) && !cfg.disable_compressed_instr) begin
       enable_compressed_load_store = 1;
     end
     foreach(addr[i]) begin
-      instr = riscv_instr_base::type_id::create("instr");
       // Assign the allowed load/store instructions based on address alignment
       // This is done separately rather than a constraint to improve the randomization performance
       allowed_instr = {LB, LBU, SB};
@@ -129,9 +144,14 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
           if((offset[i] inside {[0:127]}) && (offset[i] % 4 == 0) &&
              (RV32C inside {riscv_instr_pkg::supported_isa}) &&
              enable_compressed_load_store) begin
-            allowed_instr = {C_LW, C_SW, allowed_instr};
-            if (cfg.enable_floating_point && (RV32FC inside {supported_isa})) begin
-              allowed_instr = {C_FLW, C_FSW, allowed_instr};
+            if (rs1_reg == SP) begin
+              `uvm_info(`gfn, "Add LWSP/SWSP to allowed instr", UVM_LOW)
+              allowed_instr = {C_LWSP, C_SWSP};
+            end else begin
+              allowed_instr = {C_LW, C_SW, allowed_instr};
+              if (cfg.enable_floating_point && (RV32FC inside {supported_isa})) begin
+                allowed_instr = {C_FLW, C_FSW, allowed_instr};
+              end
             end
           end
         end
@@ -143,31 +163,47 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
           if((offset[i] inside {[0:255]}) && (offset[i] % 8 == 0) &&
              (RV64C inside {riscv_instr_pkg::supported_isa} &&
              enable_compressed_load_store)) begin
-            allowed_instr = {C_LD, C_SD, allowed_instr};
-            if (cfg.enable_floating_point && (RV32DC inside {supported_isa})) begin
-              allowed_instr = {C_FLD, C_FSD, allowed_instr};
+            if (rs1_reg == SP) begin
+              allowed_instr = {C_LDSP, C_SDSP};
+            end else begin
+              allowed_instr = {C_LD, C_SD, allowed_instr};
+              if (cfg.enable_floating_point && (RV32DC inside {supported_isa})) begin
+                allowed_instr = {C_FLD, C_FSD, allowed_instr};
+              end
             end
           end
         end
-      end else begin
+      end else begin // unaligned load/store
         allowed_instr = {LW, SW, LH, LHU, SH, allowed_instr};
+        // Compressed load/store still needs to be aligned
         if ((offset[i] inside {[0:127]}) && (offset[i] % 4 == 0) &&
             (RV32C inside {riscv_instr_pkg::supported_isa}) &&
             enable_compressed_load_store) begin
-          allowed_instr = {C_LW, C_SW, allowed_instr};
+            if (rs1_reg == SP) begin
+              allowed_instr = {C_LWSP, C_SWSP};
+            end else begin
+              allowed_instr = {C_LW, C_SW, allowed_instr};
+            end
         end
         if (XLEN >= 64) begin
           allowed_instr = {LWU, LD, SD, allowed_instr};
           if ((offset[i] inside {[0:255]}) && (offset[i] % 8 == 0) &&
               (RV64C inside {riscv_instr_pkg::supported_isa}) &&
               enable_compressed_load_store) begin
-              allowed_instr = {C_LD, C_SD, allowed_instr};
+              if (rs1_reg == SP) begin
+                allowed_instr = {C_LWSP, C_SWSP};
+              end else begin
+                allowed_instr = {C_LD, C_SD, allowed_instr};
+              end
            end
         end
       end
-      randomize_instr(instr, .skip_rs1(1'b1), .skip_imm(1'b1), .disable_dist(1'b1));
+      instr = riscv_instr::get_load_store_instr(allowed_instr);
+      instr.has_rs1 = 0;
+      instr.has_imm = 0;
+      randomize_gpr(instr);
       instr.rs1 = rs1_reg;
-      instr.set_imm(offset[i]);
+      instr.imm_str = $sformatf("%0d", $signed(offset[i]));
       instr.process_load_store = 0;
       instr_list.push_back(instr);
       load_store_instr.push_back(instr);
@@ -318,6 +354,7 @@ class riscv_multi_page_load_store_instr_stream extends riscv_mem_access_stream;
       load_store_instr_stream[i].min_instr_cnt = 5;
       load_store_instr_stream[i].max_instr_cnt = 10;
       load_store_instr_stream[i].cfg = cfg;
+      load_store_instr_stream[i].sp_c.constraint_mode(0);
       // Make sure each load/store sequence doesn't override the rs1 of other sequences.
       foreach(rs1_reg[j]) begin
         if(i != j) begin
@@ -396,10 +433,10 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
   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_instr instr[$];
     riscv_pseudo_instr li_instr;
-    riscv_instr_base store_instr;
-    riscv_instr_base add_instr;
+    riscv_instr store_instr;
+    riscv_instr add_instr;
     int min_offset[$];
     int max_offset[$];
     min_offset = offset.min();
@@ -413,9 +450,8 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
     )
     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");
+    add_instr = riscv_instr::get_rand_instr(.include_instr({ADD}));
     `DV_CHECK_RANDOMIZE_WITH_FATAL(add_instr,
-       instr_name == ADD;
        rs1 == gpr;
        rs2 == li_instr.rd;
        rd  == gpr;
@@ -423,7 +459,7 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
     instr.push_back(li_instr);
     instr.push_back(add_instr);
     // Create SW instruction template
-    store_instr = riscv_instr_base::type_id::create("store_instr");
+    store_instr = riscv_instr::get_rand_instr(.include_instr({SB}));
     `DV_CHECK_RANDOMIZE_WITH_FATAL(store_instr,
        instr_name == SB;
        rs1 == gpr;
@@ -431,9 +467,9 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
     // 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);
+        riscv_instr store;
+        store = riscv_instr::type_id::create("store");
+        store.copy(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
diff --git a/vendor/google_riscv-dv/src/riscv_loop_instr.sv b/vendor/google_riscv-dv/src/riscv_loop_instr.sv
index 671c967c..c2fcecc6 100644
--- a/vendor/google_riscv-dv/src/riscv_loop_instr.sv
+++ b/vendor/google_riscv-dv/src/riscv_loop_instr.sv
@@ -27,12 +27,12 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
   rand bit [2:0]           num_of_nested_loop;
   rand int                 num_of_instr_in_loop;
   rand riscv_instr_name_t  branch_type[];
-  riscv_instr_base         loop_init_instr[];
-  riscv_instr_base         loop_update_instr[];
-  riscv_instr_base         loop_branch_instr[];
-  riscv_rand_instr         loop_branch_target_instr[];
+  riscv_instr              loop_init_instr[];
+  riscv_instr              loop_update_instr[];
+  riscv_instr              loop_branch_instr[];
+  riscv_instr              loop_branch_target_instr[];
   // Aggregated loop instruction stream
-  riscv_instr_base         loop_instr[];
+  riscv_instr         loop_instr[];
 
   constraint legal_loop_regs_c {
     solve num_of_nested_loop before loop_cnt_reg;
@@ -124,9 +124,8 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
     loop_branch_target_instr = new[num_of_nested_loop];
     for(int i = 0; i < num_of_nested_loop; i++) begin
       // Instruction to init the loop counter
-      loop_init_instr[2*i] = riscv_instr_base::type_id::create("loop_init_instr");
+      loop_init_instr[2*i] = riscv_instr::get_rand_instr(.include_instr({ADDI}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_init_instr[2*i],
-                                     instr_name == ADDI;
                                      rd == loop_cnt_reg[i];
                                      rs1 == ZERO;
                                      imm == loop_init_val[i];,
@@ -134,9 +133,8 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
       loop_init_instr[2*i].comment = $sformatf("init loop %0d counter", i);
 
       // Instruction to init loop limit
-      loop_init_instr[2*i+1] = riscv_instr_base::type_id::create("loop_init_instr");
+      loop_init_instr[2*i+1] = riscv_instr::get_rand_instr(.include_instr({ADDI}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_init_instr[2*i+1],
-                                     instr_name == ADDI;
                                      rd == loop_limit_reg[i];
                                      rs1 == ZERO;
                                      imm == loop_limit_val[i];,
@@ -144,28 +142,30 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
       loop_init_instr[2*i+1].comment = $sformatf("init loop %0d limit", i);
 
       // Branch target instruction, can be anything
-      loop_branch_target_instr[i] = riscv_rand_instr::type_id::create("loop_branch_target_instr");
-      loop_branch_target_instr[i].cfg = cfg;
-      loop_branch_target_instr[i].reserved_rd = reserved_rd;
+      loop_branch_target_instr[i] = riscv_instr::get_rand_instr(
+          .include_category({ARITHMETIC, LOGICAL, COMPARE}),
+          .exclude_instr({C_ADDI16SP}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_target_instr[i],
-                                     !(category inside {LOAD, STORE, BRANCH, JUMP});,
-                                     "Cannot randomize branch target instruction")
+                                     if (format == CB_FORMAT) {
+                                       !(rs1 inside {reserved_rd, cfg.reserved_regs});
+                                     }
+                                     if (has_rd) {
+                                       !(rd inside {reserved_rd, cfg.reserved_regs});
+                                     }, "Cannot randomize branch target instruction")
       loop_branch_target_instr[i].label = $sformatf("%0s_%0d_t", label, i);
 
       // Instruction to update loop counter
-      loop_update_instr[i] = riscv_instr_base::type_id::create("loop_update_instr");
+      loop_update_instr[i] = riscv_instr::get_rand_instr(.include_instr({ADDI}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_update_instr[i],
-                                     instr_name == ADDI;
                                      rd == loop_cnt_reg[i];
-                                     rs1== loop_cnt_reg[i];
+                                     rs1 == loop_cnt_reg[i];
                                      imm == loop_step_val[i];,
                                      "Cannot randomize loop update instruction")
       loop_update_instr[i].comment = $sformatf("update loop %0d counter", i);
 
       // Backward branch instruction
-      loop_branch_instr[i] = riscv_instr_base::type_id::create("loop_branch_instr");
+      loop_branch_instr[i] = riscv_instr::get_rand_instr(.include_instr({branch_type[i]}));
       `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_instr[i],
-                                     instr_name == branch_type[i];
                                      rs1 == loop_cnt_reg[i];
                                      if (!(branch_type[i] inside {C_BEQZ, C_BNEZ})) {
                                        rs2 == loop_limit_reg[i];
diff --git a/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv b/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv
new file mode 100644
index 00000000..6423be4e
--- /dev/null
+++ b/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv
@@ -0,0 +1,32 @@
+// Psuedo instructions are used to simplify assembly program writing
+class riscv_pseudo_instr extends `INSTR;
+
+  rand riscv_pseudo_instr_name_t  pseudo_instr_name;
+
+  `add_pseudo_instr(LI, I_FORMAT, LOAD, RV32I)
+  `add_pseudo_instr(LA, I_FORMAT, LOAD, RV32I)
+
+  `uvm_object_utils(riscv_pseudo_instr)
+
+  function new(string name = "");
+    super.new(name);
+    process_load_store = 0;
+    this.format = I_FORMAT;
+  endfunction
+
+  // Convert the instruction to assembly code
+  virtual function string convert2asm(string prefix = "");
+    string asm_str;
+    asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
+    // instr rd,imm
+    asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
+    if(comment != "")
+      asm_str = {asm_str, " #",comment};
+    return asm_str.tolower();
+  endfunction
+
+  virtual function string get_instr_name();
+    return pseudo_instr_name.name();
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/target/exp/riscvOVPsim.ic b/vendor/google_riscv-dv/target/exp/riscvOVPsim.ic
new file mode 100644
index 00000000..efe857bc
--- /dev/null
+++ b/vendor/google_riscv-dv/target/exp/riscvOVPsim.ic
@@ -0,0 +1,18 @@
+# riscOVPsim configuration file converted from YAML
+--variant RV64GC
+--override riscvOVPsim/cpu/misa_MXL=2
+--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
+--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0
+--override riscvOVPsim/cpu/unaligned=T
+--override riscvOVPsim/cpu/mtvec_mask=0x0 # 0
+--override riscvOVPsim/cpu/user_version=2.3
+--override riscvOVPsim/cpu/priv_version=1.11
+--override riscvOVPsim/cpu/mvendorid=0
+--override riscvOVPsim/cpu/marchid=0
+--override riscvOVPsim/cpu/mimpid=0
+--override riscvOVPsim/cpu/mhartid=0
+--override riscvOVPsim/cpu/cycle_undefined=F
+--override riscvOVPsim/cpu/instret_undefined=F
+--override riscvOVPsim/cpu/time_undefined=T
+--override riscvOVPsim/cpu/reset_address=0x80000000
+--override riscvOVPsim/cpu/simulateexceptions=T
diff --git a/vendor/google_riscv-dv/target/exp/riscv_core_setting.sv b/vendor/google_riscv-dv/target/exp/riscv_core_setting.sv
new file mode 100644
index 00000000..d94572be
--- /dev/null
+++ b/vendor/google_riscv-dv/target/exp/riscv_core_setting.sv
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2019 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.
+ */
+
+`define EXPERIMENTAL
+
+//-----------------------------------------------------------------------------
+// Processor feature configuration
+//-----------------------------------------------------------------------------
+// XLEN
+parameter int XLEN = 64;
+
+// Parameter for SATP mode, set to BARE if address translation is not supported
+parameter satp_mode_t SATP_MODE = SV39;
+
+// Supported Privileged mode
+privileged_mode_t supported_privileged_mode[] = {USER_MODE, SUPERVISOR_MODE, MACHINE_MODE};
+
+// Unsupported instructions
+riscv_instr_name_t unsupported_instr[];
+
+// ISA supported by the processor
+riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A,
+                                        RV32F, RV64F, RV32D, RV64D};
+
+// Interrupt mode support
+mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
+
+// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is
+// supported
+int max_interrupt_vector_num = 16;
+
+// Debug mode support
+bit support_debug_mode = 0;
+
+// Support delegate trap to user mode
+bit support_umode_trap = 0;
+
+// Support sfence.vma instruction
+bit support_sfence = 1;
+
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
+// ----------------------------------------------------------------------------
+// Previleged CSR implementation
+// ----------------------------------------------------------------------------
+
+// Implemented previlieged CSR list
+`ifdef DSIM
+privileged_reg_t implemented_csr[] = {
+`else
+parameter privileged_reg_t implemented_csr[] = {
+`endif
+    // User mode CSR
+    USTATUS,    // User status
+    UIE,        // User interrupt-enable register
+    UTVEC,      // User trap-handler base address
+    USCRATCH,   // Scratch register for user trap handlers
+    UEPC,       // User exception program counter
+    UCAUSE,     // User trap cause
+    UTVAL,      // User bad address or instruction
+    UIP,        // User interrupt pending
+    // Supervisor mode CSR
+    SSTATUS,    // Supervisor status
+    SEDELEG,    // Supervisor exception delegation register
+    SIDELEG,    // Supervisor interrupt delegation register
+    SIE,        // Supervisor interrupt-enable register
+    STVEC,      // Supervisor trap-handler base address
+    SCOUNTEREN, // Supervisor counter enable
+    SSCRATCH,   // Scratch register for supervisor trap handlers
+    SEPC,       // Supervisor exception program counter
+    SCAUSE,     // Supervisor trap cause
+    STVAL,      // Supervisor bad address or instruction
+    SIP,        // Supervisor interrupt pending
+    SATP,       // Supervisor address translation and protection
+    // Machine mode mode CSR
+    MVENDORID,  // Vendor ID
+    MARCHID,    // Architecture ID
+    MIMPID,     // Implementation ID
+    MHARTID,    // Hardware thread ID
+    MSTATUS,    // Machine status
+    MISA,       // ISA and extensions
+    MEDELEG,    // Machine exception delegation register
+    MIDELEG,    // Machine interrupt delegation register
+    MIE,        // Machine interrupt-enable register
+    MTVEC,      // Machine trap-handler base address
+    MCOUNTEREN, // Machine counter enable
+    MSCRATCH,   // Scratch register for machine trap handlers
+    MEPC,       // Machine exception program counter
+    MCAUSE,     // Machine trap cause
+    MTVAL,      // Machine bad address or instruction
+    MIP,        // Machine interrupt pending
+    // Floating point CSR
+    FCSR        // Floating point control and status
+};
+
+// ----------------------------------------------------------------------------
+// Supported interrupt/exception setting, used for functional coverage
+// ----------------------------------------------------------------------------
+
+`ifdef DSIM
+interrupt_cause_t implemented_interrupt[] = {
+`else
+parameter interrupt_cause_t implemented_interrupt[] = {
+`endif
+    U_SOFTWARE_INTR,
+    S_SOFTWARE_INTR,
+    M_SOFTWARE_INTR,
+    U_TIMER_INTR,
+    S_TIMER_INTR,
+    M_TIMER_INTR,
+    U_EXTERNAL_INTR,
+    S_EXTERNAL_INTR,
+    M_EXTERNAL_INTR
+};
+
+`ifdef DSIM
+exception_cause_t implemented_exception[] = {
+`else
+parameter exception_cause_t implemented_exception[] = {
+`endif
+    INSTRUCTION_ADDRESS_MISALIGNED,
+    INSTRUCTION_ACCESS_FAULT,
+    ILLEGAL_INSTRUCTION,
+    BREAKPOINT,
+    LOAD_ADDRESS_MISALIGNED,
+    LOAD_ACCESS_FAULT,
+    STORE_AMO_ADDRESS_MISALIGNED,
+    STORE_AMO_ACCESS_FAULT,
+    ECALL_UMODE,
+    ECALL_SMODE,
+    ECALL_MMODE,
+    INSTRUCTION_PAGE_FAULT,
+    LOAD_PAGE_FAULT,
+    STORE_AMO_PAGE_FAULT
+};
diff --git a/vendor/google_riscv-dv/target/exp/testlist.yaml b/vendor/google_riscv-dv/target/exp/testlist.yaml
new file mode 100644
index 00000000..904deb63
--- /dev/null
+++ b/vendor/google_riscv-dv/target/exp/testlist.yaml
@@ -0,0 +1,42 @@
+# 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
+# --------------------------------------------------------------------------------
+
+- import: /target/rv64gc/testlist.yaml
+
+- test: riscv_instr_test
+  description: >
+    New experimental instruction class test
+  iterations: 0
+  gen_test: riscv_instr_test
+  gen_opts: >
+    +instr_cnt=10000
+    +num_of_sub_program=5
+    +boot_mode=m
diff --git a/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv b/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
index 207df4d2..2cbe134b 100644
--- a/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
+++ b/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
@@ -48,6 +48,9 @@ bit support_umode_trap = 0;
 // Support sfence.vma instruction
 bit support_sfence = 0;
 
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
 // ----------------------------------------------------------------------------
 // Previleged CSR implementation
 // ----------------------------------------------------------------------------
diff --git a/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
index 14889dac..54b1c774 100644
--- a/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
+++ b/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
@@ -48,6 +48,9 @@ bit support_umode_trap = 0;
 // Support sfence.vma instruction
 bit support_sfence = 0;
 
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
 // ----------------------------------------------------------------------------
 // Previleged CSR implementation
 // ----------------------------------------------------------------------------
diff --git a/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
index 8699ca1a..830d4641 100644
--- a/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
+++ b/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
@@ -48,6 +48,9 @@ bit support_umode_trap = 0;
 // Support sfence.vma instruction
 bit support_sfence = 0;
 
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
 // ----------------------------------------------------------------------------
 // Previleged CSR implementation
 // ----------------------------------------------------------------------------
diff --git a/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
index aafb3b67..61830b6c 100644
--- a/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
+++ b/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
@@ -32,7 +32,6 @@ riscv_instr_name_t unsupported_instr[];
 // ISA supported by the processor
 riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A,
                                         RV32F, RV64F, RV32D, RV64D};
-
 // Interrupt mode support
 mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
 
@@ -49,6 +48,9 @@ bit support_umode_trap = 0;
 // Support sfence.vma instruction
 bit support_sfence = 1;
 
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
 // ----------------------------------------------------------------------------
 // Previleged CSR implementation
 // ----------------------------------------------------------------------------
diff --git a/vendor/google_riscv-dv/target/rv64gc/testlist.yaml b/vendor/google_riscv-dv/target/rv64gc/testlist.yaml
index 27db94dd..9170eec0 100644
--- a/vendor/google_riscv-dv/target/rv64gc/testlist.yaml
+++ b/vendor/google_riscv-dv/target/rv64gc/testlist.yaml
@@ -60,7 +60,6 @@
   iterations: 2
   gen_test: riscv_rand_instr_test
   gen_opts: >
-    +require_signature_addr=1
     +instr_cnt=6000
     +num_of_sub_program=0
     +enable_access_invalid_csr_level=1
@@ -122,8 +121,15 @@
     Enable floating point instructions
   gen_opts: >
     +enable_floating_point=1
+    +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_multi_page_load_store_instr_stream,4
+    +directed_instr_3=riscv_mem_region_stress_test,4
+    +directed_instr_4=riscv_jal_instr,4
   iterations: 1
-  gen_test: riscv_rand_instr_test
+  gen_test: riscv_instr_base_test
   rtl_test: core_base_test
 
 - test: riscv_floating_point_mmu_stress_test
diff --git a/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
index bdf28245..6cf37439 100644
--- a/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
+++ b/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
@@ -48,6 +48,9 @@ bit support_umode_trap = 0;
 // Support sfence.vma instruction
 bit support_sfence = 0;
 
+// Support unaligned load/store
+bit support_unaligned_load_store = 1'b1;
+
 // ----------------------------------------------------------------------------
 // Previleged CSR implementation
 // ----------------------------------------------------------------------------
diff --git a/vendor/google_riscv-dv/test/riscv_instr_base_test.sv b/vendor/google_riscv-dv/test/riscv_instr_base_test.sv
index 09694376..1de3d875 100644
--- a/vendor/google_riscv-dv/test/riscv_instr_base_test.sv
+++ b/vendor/google_riscv-dv/test/riscv_instr_base_test.sv
@@ -24,6 +24,8 @@ class riscv_instr_base_test extends uvm_test;
   riscv_asm_program_gen   asm_gen;
   string                  instr_seq;
   int                     start_idx;
+  uvm_coreservice_t       coreservice;
+  uvm_factory             factory;
 
   `uvm_component_utils(riscv_instr_base_test)
 
@@ -35,6 +37,8 @@ class riscv_instr_base_test extends uvm_test;
 
   virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
+    coreservice = uvm_coreservice_t::get();
+    factory = coreservice.get_factory();
     `uvm_info(`gfn, "Create configuration instance", UVM_LOW)
     cfg = riscv_instr_gen_config::type_id::create("cfg");
     `uvm_info(`gfn, "Create configuration instance...done", UVM_LOW)
@@ -43,10 +47,13 @@ class riscv_instr_base_test extends uvm_test;
       asm_file_name = {asm_file_name, ".", cfg.asm_test_suffix};
     // Override the default riscv instruction sequence
     if($value$plusargs("instr_seq=%0s", instr_seq)) begin
-      uvm_coreservice_t coreservice = uvm_coreservice_t::get();
-      uvm_factory factory = coreservice.get_factory();
       factory.set_type_override_by_name("riscv_instr_sequence", instr_seq);
     end
+    if (riscv_instr_pkg::support_debug_mode) begin
+      factory.set_inst_override_by_name("riscv_asm_program_gen",
+                                        "riscv_debug_rom_gen",
+                                        {`gfn, ".asm_gen.debug_rom"});
+    end
   endfunction
 
   function void report_phase(uvm_phase phase);
@@ -73,12 +80,18 @@ class riscv_instr_base_test extends uvm_test;
 
   task run_phase(uvm_phase phase);
     int fd;
-    cfg.build_instruction_template();
+    `ifdef DEPRECATED
+      cfg.build_instruction_template();
+    `endif
     for(int i = 0; i < cfg.num_of_tests; i++) begin
       string test_name;
       randomize_cfg();
-      cfg.build_instruction_list();
-      asm_gen = riscv_asm_program_gen::type_id::create("asm_gen");
+      `ifdef DEPRECATED
+        cfg.build_instruction_list();
+      `else
+        riscv_instr::create_instr_list(cfg);
+      `endif
+      asm_gen = riscv_asm_program_gen::type_id::create("asm_gen", , `gfn);
       asm_gen.cfg = cfg;
       asm_gen.get_directed_instr_stream();
       test_name = $sformatf("%0s_%0d.S", asm_file_name, i+start_idx);
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 373f566f..10175fe0 100644
--- a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv
+++ b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv
@@ -4,6 +4,7 @@ class riscv_instr_cov_test extends uvm_test;
   typedef uvm_enum_wrapper#(riscv_instr_name_t) instr_enum;
   typedef uvm_enum_wrapper#(riscv_reg_t) gpr_enum;
   typedef uvm_enum_wrapper#(privileged_reg_t) preg_enum;
+  `VECTOR_INCLUDE("riscv_instr_cov_test_inc_typedef.sv")
 
   riscv_instr_gen_config    cfg;
   riscv_instr_cover_group   instr_cg;
@@ -38,11 +39,17 @@ class riscv_instr_cov_test extends uvm_test;
     cfg = riscv_instr_gen_config::type_id::create("cfg");
     // disable_compressed_instr is not relevant to coverage test
     cfg.disable_compressed_instr = 0;
-    cfg.build_instruction_template(.skip_instr_exclusion(1));
+    `ifdef DEPRECATED
+      cfg.build_instruction_template(.skip_instr_exclusion(1));
+    `else
+      riscv_instr::create_instr_list(cfg);
+    `endif
     instr = riscv_instr_cov_item::type_id::create("instr");
     instr.rand_mode(0);
+    `ifdef DEPRECATED
     instr.no_hint_illegal_instr_c.constraint_mode(0);
     instr.imm_val_c.constraint_mode(0);
+    `endif
     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
@@ -81,16 +88,11 @@ 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
-              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))
+             `uvm_info(`gfn, $sformatf("Found illegal instr: %0s [%0s]",
+                             trace["instr"], line), UVM_HIGH)
+              if (!expect_illegal_instr) begin
+                unexpected_illegal_instr_cnt++;
               end
             end
           end
@@ -108,39 +110,55 @@ class riscv_instr_cov_test extends uvm_test;
     if ((skipped_cnt > 0) || (unexpected_illegal_instr_cnt > 0)) begin
       `uvm_error(`gfn, $sformatf("%0d instructions skipped, %0d illegal instruction",
                        skipped_cnt, unexpected_illegal_instr_cnt))
+
+    end else begin
+      `uvm_info(`gfn, "TEST PASSED", UVM_NONE);
     end
   endtask
 
   virtual function void post_process_trace();
   endfunction
 
+  function void fatal (string str);
+    `uvm_info(`gfn, str, UVM_NONE);
+    if ($test$plusargs("stop_on_first_error")) begin
+      `uvm_fatal(`gfn, "Errors: *. Warnings: * (written by riscv_instr_cov.sv)")
+    end
+  endfunction
+
   function bit sample();
     riscv_instr_name_t instr_name;
     bit [XLEN-1:0] val;
     if (instr_enum::from_name(process_instr_name(trace["instr"]), instr_name)) begin
+    `ifdef DEPRECATED
       if (cfg.instr_template.exists(instr_name)) begin
         instr.copy_base_instr(cfg.instr_template[instr_name]);
+    `else
+      if (riscv_instr::instr_template.exists(instr_name)) begin
+        instr.copy(riscv_instr::instr_template[instr_name]);
+    `endif
         assign_trace_info_to_instr(instr);
         instr.pre_sample();
         instr_cg.sample(instr);
         return 1'b1;
       end
     end
+    `uvm_info(`gfn, $sformatf("Cannot find opcode: %0s",
+                              process_instr_name(trace["instr"])), UVM_LOW)
     get_val(trace["binary"], val);
     if ((val[1:0] != 2'b11) && (RV32C inside {supported_isa})) begin
-      instr_cg.compressed_opcode_cg.sample(val[15:0]);
-      instr_cg.illegal_compressed_instr_cg.sample(val);
+      `SAMPLE(instr_cg.compressed_opcode_cg, val[15:0])
+      `SAMPLE(instr_cg.illegal_compressed_instr_cg, val)
     end
     if (val[1:0] == 2'b11) begin
-      `uvm_info("DBG", $sformatf("Sample illegal opcode: %0x [%0s]",
-                                 val[6:2], trace["instr_str"]), UVM_LOW)
-      instr_cg.opcode_cg.sample(val[6:2]);
+      `uvm_info("DBG", $sformatf("Sample opcode: %0x [%0s]", val[6:2], trace["instr"]), UVM_LOW)
+      `SAMPLE(instr_cg.opcode_cg, val[6:2])
     end
-    return 1'b0;
   endfunction
 
   virtual function void assign_trace_info_to_instr(riscv_instr_cov_item instr);
     riscv_reg_t gpr;
+   `VECTOR_INCLUDE("riscv_instr_cov_test_inc_assign_trace_info_to_instr_declares.sv")
     privileged_reg_t preg;
     get_val(trace["addr"], instr.pc);
     get_val(trace["binary"], instr.binary);
@@ -154,7 +172,7 @@ class riscv_instr_cov_test extends uvm_test;
         instr.rs2 = gpr;
         get_val(trace["rs2_val"], instr.rs2_value);
       end else begin
-        `uvm_error(`gfn, $sformatf("Unrecoganized rs2: [%0s] (%0s)",
+        `uvm_error(`gfn, $sformatf("Unrecognized rs2: [%0s] (%0s)",
                                    trace["rs2"], trace["csv_entry"]))
       end
     end
@@ -163,7 +181,7 @@ class riscv_instr_cov_test extends uvm_test;
         instr.rd = gpr;
         get_val(trace["rd_val"], instr.rd_value);
       end else begin
-        `uvm_error(`gfn, $sformatf("Unrecoganized rd: [%0s] (%0s)",
+        `uvm_error(`gfn, $sformatf("Unrecognized rd: [%0s] (%0s)",
                                    trace["rd"], trace["csv_entry"]))
       end
     end
@@ -176,7 +194,7 @@ class riscv_instr_cov_test extends uvm_test;
           instr.rs1 = gpr;
           get_val(trace["rs1_val"], instr.rs1_value);
         end else begin
-          `uvm_error(`gfn, $sformatf("Unrecoganized rs1: [%0s] (%0s)",
+          `uvm_error(`gfn, $sformatf("Unrecognized rs1: [%0s] (%0s)",
                                      trace["rs1"], trace["csv_entry"]))
         end
       end
@@ -204,6 +222,9 @@ class riscv_instr_cov_test extends uvm_test;
         instr.mem_addr = instr.rs1_value + {padding, instr.imm};
       end
     end
+
+   `VECTOR_INCLUDE("riscv_instr_cov_test_inc_assign_trace_info_to_instr.sv")
+
   endfunction
 
   function bit get_gpr(input string str, output riscv_reg_t gpr);
@@ -215,6 +236,8 @@ class riscv_instr_cov_test extends uvm_test;
     end
   endfunction
 
+   `VECTOR_INCLUDE("riscv_instr_cov_test_inc_assign_trace_info_to_instr_functions.sv")
+
   function void get_val(input string str, output bit [XLEN-1:0] val);
     val = str.atohex();
   endfunction
diff --git a/vendor/google_riscv-dv/test/riscv_instr_test.sv b/vendor/google_riscv-dv/test/riscv_instr_test.sv
new file mode 100644
index 00000000..779b6a7b
--- /dev/null
+++ b/vendor/google_riscv-dv/test/riscv_instr_test.sv
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 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.
+ */
+
+// Sanity test for riscv_instr_test class
+class riscv_instr_test extends riscv_instr_base_test;
+
+  `uvm_component_utils(riscv_instr_test)
+  `uvm_component_new
+
+  task run_phase(uvm_phase phase);
+    int fd;
+    riscv_instr instr;
+    riscv_instr_name_t instr_name;
+    string test_name = $sformatf("%0s_0.S", asm_file_name);
+    fd = $fopen(test_name,"w");
+    `uvm_info(`gfn, "Creating instruction list", UVM_LOW)
+    riscv_instr::create_instr_list(cfg);
+    `uvm_info(`gfn, "Randomizing instruction list now...", UVM_LOW)
+    repeat (10000) begin
+      instr = riscv_instr::get_rand_instr();
+      `DV_CHECK_RANDOMIZE_FATAL(instr);
+      $fwrite(fd, {instr.convert2asm(),"\n"});
+    end
+    repeat (10000) begin
+      instr = riscv_instr::get_rand_instr(.include_category({LOAD, STORE}));
+      `DV_CHECK_RANDOMIZE_FATAL(instr);
+      $fwrite(fd, {instr.convert2asm(),"\n"});
+    end
+    repeat (10000) begin
+      instr = riscv_instr::get_rand_instr(.exclude_category({LOAD, STORE , BRANCH}),
+                                          .include_group({RV32I, RV32M}));
+      `DV_CHECK_RANDOMIZE_FATAL(instr);
+      $fwrite(fd, {instr.convert2asm(),"\n"});
+    end
+    $fclose(fd);
+    `uvm_info(get_full_name(), $sformatf("%0s is generated", test_name), UVM_LOW)
+  endtask
+
+  virtual function void randomize_cfg();
+    `DV_CHECK_RANDOMIZE_FATAL(cfg);
+    `uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
+                    cfg.sprint()), UVM_LOW)
+  endfunction
+
+endclass
diff --git a/vendor/google_riscv-dv/test/riscv_instr_test_pkg.sv b/vendor/google_riscv-dv/test/riscv_instr_test_pkg.sv
index 5e93bd0a..da0342af 100644
--- a/vendor/google_riscv-dv/test/riscv_instr_test_pkg.sv
+++ b/vendor/google_riscv-dv/test/riscv_instr_test_pkg.sv
@@ -23,5 +23,8 @@ package riscv_instr_test_pkg;
   `include "riscv_instr_test_lib.sv"
   `include "riscv_instr_cov_debug_test.sv"
   `include "riscv_instr_cov_test.sv"
+  `ifdef EXPERIMENTAL
+    `include "riscv_instr_test.sv"
+  `endif
 
 endpackage
diff --git a/vendor/google_riscv-dv/yaml/base_testlist.yaml b/vendor/google_riscv-dv/yaml/base_testlist.yaml
index e02753f9..6953344d 100644
--- a/vendor/google_riscv-dv/yaml/base_testlist.yaml
+++ b/vendor/google_riscv-dv/yaml/base_testlist.yaml
@@ -59,7 +59,6 @@
     +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
@@ -91,7 +90,7 @@
   gen_test: riscv_instr_base_test
   gen_opts: >
     +instr_cnt=10000
-    +num_of_sub_program=20
+    +num_of_sub_program=10
     +directed_instr_0=riscv_load_store_rand_instr_stream,8
   rtl_test: core_base_test
 
@@ -151,10 +150,8 @@
   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
@@ -166,11 +163,9 @@
   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
 
diff --git a/vendor/google_riscv-dv/yaml/simulator.yaml b/vendor/google_riscv-dv/yaml/simulator.yaml
index 082d41e8..09313c30 100644
--- a/vendor/google_riscv-dv/yaml/simulator.yaml
+++ b/vendor/google_riscv-dv/yaml/simulator.yaml
@@ -68,6 +68,7 @@
     cov_opts: >
       -do "coverage save -onexit /cov.ucdb;"
 
+# TODO: Remove +DEPRECATED for dsim
 - tool: dsim
   env_var: DSIM,DSIM_LIB_PATH
   compile:
@@ -76,6 +77,7 @@
       - " -sv -work /dsim
                 -genimage image
                 +incdir+$UVM_HOME/src
+                +define+DEPRECATED
                 $UVM_HOME/src/uvm_pkg.sv
                 +define+DSIM
                 +incdir+
@@ -86,3 +88,17 @@
     cmd: >
         -sv_seed  -pli_lib /libuvm_dpi.so +acc+rwb -image image -work /dsim
 
+- tool: qrun
+  compile:
+    cmd:
+      - "qrun -f /qrun_option.f
+        +incdir+
+        +incdir+
+        -f /files.f 
+        -l /qrun_compile_optimize.log
+        -outdir /qrun.out"
+  sim:
+    cmd: >
+      qrun -64 -simulate -snapshot design_opt -c   -sv_seed  -outdir /qrun.out
+    cov_opts: >
+      -coverage -ucdb /cov.ucdb