Update google_riscv-dv to google/riscv-dv@033fccf (#406)

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

* Add more ebreak generation control (google/riscv-dv#229) (udinator)
* Fix timemout, misc update to README (google/riscv-dv#228) (taoliug)
* Fix CSR test setup (Udi)
* Update spike setup instruction for commit log (google/riscv-dv#226)
  (taoliug)
* Fix spike arguments to generate commit log (google/riscv-dv#225)
  (Greg Chadwick)
* Minor README typo (google/riscv-dv#219) (Dan Petrisko)
* Add random FCSR programing, add RV32FC/DC support (google/riscv-
  dv#221) (taoliug)
* Add floating point load/store support (google/riscv-dv#220)
  (taoliug)
* Fix floating point comparison issue (google/riscv-dv#218) (taoliug)
* Add basic support for F/D extension (google/riscv-dv#217) (taoliug)
* Generate the ucdb file inside output directory (google/riscv-dv#215)
  (Hai Hoang Dang)
* cov.py: Allow coverage to run with different simulator
  (google/riscv-dv#214) (Hai Hoang Dang)
This commit is contained in:
udinator 2019-10-16 17:50:23 -07:00 committed by GitHub
parent fc80203af3
commit b2e36ec345
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 477 additions and 141 deletions

View file

@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: ad6fe565a91445cc3ea3e32119360b57af4f19b2
rev: 033fccfbd50f6412e66b448a1d04245d787004bd
}
}

View file

@ -3,7 +3,7 @@
RISCV-DV is a SV/UVM based open-source instruction generator for RISC-V
processor verification. It currently supports the following features:
- Supported instruction set: RV32IMAC, RV64IMAC
- Supported instruction set: RV32IMAFDC, RV64IMAFDC
- Supported privileged mode: machine mode, supervisor mode, user mode
- Page table randomization and exception
- Privileged CSR setup randomization
@ -324,7 +324,7 @@ one of below to run ISS simulation.
- [spike](https://github.com/riscv/riscv-isa-sim#) setup
- Follow the [steps](https://github.com/riscv/riscv-isa-sim#build-steps) to build spike
- Make sure RISCV_ENABLE_COMMITLOG is defined in [config.h.in](https://github.com/riscv/riscv-isa-sim/blob/master/config.h.in)
- Install spike with "--enable-commitlog"
- Set environment variable SPIKE_PATH to the directory of the spike binary
- [riscv-ovpsim](https://github.com/riscv/riscv-ovpsim) setup
- Download the riscv-ovpsim binary
@ -389,8 +389,8 @@ it as a reference to setup end-to-end co-simulation flow.
This repo is still under active development, here's recommended approach to
customize the instruction generator while keeping the minimum effort of merging
upstream changes.
- Do not modify the upstream classes directly. When possible, extending from
the upstream classses and implment your own functionalities.
- Do not modify the upstream classes directly. When possible, extend from
the upstream classses and implement your own functionalities.
- Add your extensions under user_extension directory, and add the files to
user_extension/user_extension.svh. If you prefer to put your extensions in a
different directory, you can use "-ext <user_extension_path>" to override the

View file

@ -31,7 +31,7 @@ from scripts.sail_log_to_trace_csv import *
LOGGER = logging.getLogger()
def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, timeout):
def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, timeout, si):
"""Collect functional coverage from the instruction trace
Args:
@ -44,6 +44,7 @@ def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, t
steps : csv:log to CSV, cov:sample coverage
opts : Additional options to the instruction generator
timeout : Timeout limit in seconds
si : Simulator used to run
"""
log_list = []
csv_list = []
@ -67,11 +68,11 @@ def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, t
logging.error("Full trace for %s is not supported yet" % iss)
sys.exit(1)
if steps == "all" or re.match("cov", steps):
build_cmd = ("python3 run.py --co -o %s --cov -tl %s %s" %
(out, testlist, opts))
base_sim_cmd = ("python3 run.py --so -o %s --cov -tl %s %s "
build_cmd = ("python3 run.py -si %s --co -o %s --cov -tl %s %s" %
(si, out, testlist, opts))
base_sim_cmd = ("python3 run.py -si %s --so -o %s --cov -tl %s %s "
"-tn riscv_instr_cov_test --steps gen --sim_opts \"<trace_csv_opts>\"" %
(out, testlist, opts))
(si, out, testlist, opts))
logging.info("Building the coverage collection framework")
run_cmd(build_cmd)
file_idx = 0
@ -106,7 +107,7 @@ def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, t
logging.info("Collecting functional coverage from %0d trace CSV...done" % len(csv_list))
def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd, timeout):
def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd, timeout, si):
"""Collect functional coverage from the instruction trace
Args:
@ -117,16 +118,17 @@ def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd, time
lsf_cmd : LSF command used to run the instruction generator
opts : Additional options to the instruction generator
timeout : Timeout limit in seconds
si : Simulator used to run
"""
sim_cmd_list = []
logging.info("Building the coverage collection framework")
build_cmd = ("python3 run.py --co -o %s --cov -tl %s %s" %
(out, testlist, opts))
build_cmd = ("python3 run.py -si %s --co -o %s --cov -tl %s %s" %
(si, out, testlist, opts))
run_cmd(build_cmd)
base_sim_cmd = ("python3 run.py --so -o %s --cov -tl %s %s "
base_sim_cmd = ("python3 run.py -si %s --so -o %s --cov -tl %s %s "
"-tn riscv_instr_cov_debug_test --steps gen "
"--sim_opts \"+num_of_iterations=<instr_cnt>\"" %
(out, testlist, opts))
(si, out, testlist, opts))
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))
@ -186,6 +188,8 @@ def setup_parser():
parser.add_argument("--lsf_cmd", type=str, default="",
help="LSF command. Run in local sequentially if lsf \
command is not specified")
parser.add_argument("-si", "--simulator", type=str, default="vcs",
help="Simulator used to run the generator, default VCS", dest="simulator")
parser.set_defaults(verbose=False)
parser.set_defaults(debug_mode=False)
return parser
@ -213,10 +217,10 @@ def main():
if args.debug_mode:
run_cov_debug_test(output_dir, args.instr_cnt, args.testlist,
args.batch_size, args.opts, args.lsf_cmd, args.timeout)
args.batch_size, args.opts, args.lsf_cmd, args.timeout, args.simulator)
else:
collect_cov(args.dir, output_dir, args.iss, args.testlist, args.batch_size,
args.lsf_cmd, args.steps, args.opts, args.timeout)
args.lsf_cmd, args.steps, args.opts, args.timeout, args.simulator)
if __name__ == "__main__":
main()

View file

@ -212,8 +212,6 @@ def gen_setup(test_file):
test_file.write(f".section .text.init\n")
test_file.write(f".globl _start\n")
test_file.write(f".option norvc\n")
for i in range(32):
test_file.write(f"j csr_fail\n")
test_file.write(f"_start:\n")

View file

@ -110,7 +110,7 @@ def run_cmd(cmd, timeout_s = 999):
"""
logging.debug(cmd)
try:
ps = subprocess.Popen(cmd,
ps = subprocess.Popen("exec " + cmd,
shell=True,
universal_newlines=True,
stdout=subprocess.PIPE,
@ -139,7 +139,7 @@ def run_parallel_cmd(cmd_list, timeout_s = 999):
"""
children = []
for cmd in cmd_list:
ps = subprocess.Popen(cmd,
ps = subprocess.Popen("exec " + cmd,
shell=True,
universal_newlines=True,
stdout=subprocess.PIPE,

View file

@ -55,18 +55,18 @@ def process_ovpsim_sim_log(ovpsim_log, csv):
instr_cnt += 1
else:
# Extract register value information
n = re.search(r" (?P<rd>[a-z0-9]{2,3}?) (?P<pre>[a-f0-9]+?)" \
n = re.search(r" (?P<rd>[a-z]{1,3}[0-9]{0,2}?) (?P<pre>[a-f0-9]+?)" \
" -> (?P<val>[a-f0-9]+?)$", line)
if n:
# Write the extracted instruction to a csvcol buffer file
# print("%0s %0s = %0s" % (trace_instr, m.group("rd"), m.group("val")))
rv_instr_trace = RiscvInstructiontTraceEntry()
rv_instr_trace.rd = n.group("rd")
rv_instr_trace.rd_val = n.group("val")
rv_instr_trace.instr_str = trace_instr
rv_instr_trace.binary = trace_bin
rv_instr_trace.addr = trace_addr
trace_csv.write_trace_entry(rv_instr_trace)
if n.group("rd") != "frm":
rv_instr_trace = RiscvInstructiontTraceEntry()
rv_instr_trace.rd = n.group("rd")
rv_instr_trace.rd_val = n.group("val")
rv_instr_trace.instr_str = trace_instr
rv_instr_trace.binary = trace_bin
rv_instr_trace.addr = trace_addr
trace_csv.write_trace_entry(rv_instr_trace)
logging.info("Processed instruction count : %d" % instr_cnt)

View file

@ -124,6 +124,38 @@ def gpr_to_abi(gpr):
"x28" : "t3",
"x29" : "t4",
"x30" : "t5",
"x31" : "t6"
"x31" : "t6",
"f0" : "ft0",
"f1" : "ft1",
"f2" : "ft2",
"f3" : "ft3",
"f4" : "ft4",
"f5" : "ft5",
"f6" : "ft6",
"f7" : "ft7",
"f8" : "fs0",
"f9" : "fs1",
"f10" : "fa0",
"f11" : "fa1",
"f12" : "fa2",
"f13" : "fa3",
"f14" : "fa4",
"f15" : "fa5",
"f16" : "fa6",
"f17" : "fa7",
"f18" : "fs2",
"f19" : "fs3",
"f20" : "fs4",
"f21" : "fs5",
"f22" : "fs6",
"f23" : "fs7",
"f24" : "fs8",
"f25" : "fs9",
"f26" : "fs10",
"f27" : "fs11",
"f28" : "ft8",
"f29" : "ft9",
"f30" : "ft10",
"f31" : "ft11",
}
return switcher.get(gpr, "na")

View file

@ -28,7 +28,7 @@ from riscv_trace_csv import *
from lib import *
RD_RE = re.compile(r"(?P<pri>\d) 0x(?P<addr>[a-f0-9]+?) " \
"\((?P<bin>.*?)\) x\s*(?P<reg>\d*?) 0x(?P<val>[a-f0-9]+)")
"\((?P<bin>.*?)\) (?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
CORE_RE = re.compile(r"core.*0x(?P<addr>[a-f0-9]+?) \(0x(?P<bin>.*?)\) (?P<instr>.*?)$")
INSTR_RE = re.compile(r"(?P<instr>[a-z\.0-9]+?)(\s+?)(?P<operand>.*)")
GPR_RE = re.compile(r"^[a-z][0-9a-z]$")
@ -85,7 +85,7 @@ def process_spike_sim_log(spike_log, csv, full_trace = 0):
if m:
# Extract RD information
instr_cnt += 1
rv_instr_trace.rd = gpr_to_abi("x%0s" % m.group("reg"))
rv_instr_trace.rd = gpr_to_abi(m.group("reg").replace(" ",""))
rv_instr_trace.rd_val = m.group("val")
rv_instr_trace.privileged_mode = m.group("pri")
gpr[rv_instr_trace.rd] = rv_instr_trace.rd_val

View file

@ -30,7 +30,8 @@ privileged_mode_t supported_privileged_mode[] = {USER_MODE, SUPERVISOR_MODE, MAC
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};
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};
@ -96,7 +97,9 @@ parameter privileged_reg_t implemented_csr[] = {
MEPC, // Machine exception program counter
MCAUSE, // Machine trap cause
MTVAL, // Machine bad address or instruction
MIP // Machine interrupt pending
MIP, // Machine interrupt pending
// Floating point CSR
FCSR // Floating point control and status
};
// ----------------------------------------------------------------------------

View file

@ -337,6 +337,9 @@ class riscv_asm_program_gen extends uvm_object;
// Init stack pointer to point to the end of the user stack
str = {indent, $sformatf("la x%0d, _user_stack_end", cfg.sp)};
instr_stream.push_back(str);
if (cfg.enable_floating_point) begin
init_floating_point_gpr();
end
core_is_initialized();
endfunction
@ -354,7 +357,10 @@ class riscv_asm_program_gen extends uvm_object;
RV32I, RV64I, RV128I : misa[MISA_EXT_I] = 1'b1;
RV32M, RV64M : misa[MISA_EXT_M] = 1'b1;
RV32A, RV64A : misa[MISA_EXT_A] = 1'b1;
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported", supported_isa[i].name()))
RV32F, RV64F, RV32FC : misa[MISA_EXT_F] = 1'b1;
RV32D, RV64D, RV32DC : misa[MISA_EXT_D] = 1'b1;
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported",
supported_isa[i].name()))
endcase
end
if (SUPERVISOR_MODE inside {supported_privileged_mode}) begin
@ -398,6 +404,26 @@ class riscv_asm_program_gen extends uvm_object;
end
endfunction
// Initialize floating point general purpose registers
virtual function void init_floating_point_gpr();
int int_gpr;
string str;
// TODO: Initialize floating point GPR with more interesting numbers
for(int i = 0; i < 32; i++) begin
int_gpr = $urandom_range(0, 31);
// Use a random integer GPR to initialize floating point GPR
if (RV64F inside {supported_isa}) begin
str = $sformatf("%0sfcvt.d.l f%0d, x%0d", indent, i, int_gpr);
end else begin
str = $sformatf("%0sfcvt.s.w f%0d, x%0d", indent, i, int_gpr);
end
instr_stream.push_back(str);
end
// Initialize rounding mode of FCSR
str = $sformatf("%0sfsrmi %0d", indent, cfg.fcsr_rm);
instr_stream.push_back(str);
endfunction
// Generate "test_done" section, test is finished by an ECALL instruction
// The ECALL trap handler will handle the clean up procedure before finishing the test.
virtual function void gen_test_done();
@ -1173,14 +1199,8 @@ class riscv_asm_program_gen extends uvm_object;
// 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)};
instr = {instr, str};
// 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));
str = {$sformatf("beq x%0d, x0, 1f", 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};
@ -1192,6 +1212,13 @@ class riscv_asm_program_gen extends uvm_object;
// 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.
@ -1279,6 +1306,11 @@ class riscv_asm_program_gen extends uvm_object;
// 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

View file

@ -25,6 +25,10 @@ class riscv_instr_base extends uvm_object;
rand riscv_reg_t rs2;
rand riscv_reg_t rs1;
rand riscv_reg_t rd;
rand riscv_fpr_t fs1;
rand riscv_fpr_t fs2;
rand riscv_fpr_t fs3;
rand riscv_fpr_t fd;
rand bit [31:0] imm;
rand imm_t imm_type;
rand bit [4:0] imm_len;
@ -43,6 +47,11 @@ class riscv_instr_base extends uvm_object;
bit has_rs1;
bit has_rs2;
bit has_rd;
bit has_fs1;
bit has_fs2;
bit has_fs3;
bit has_fd;
bit is_floating_point;
bit [31:0] imm_mask = '1;
string imm_str;
string comment;
@ -123,7 +132,7 @@ class riscv_instr_base extends uvm_object;
}
}
// Registers specified by the three-bit rs1', rs2', and rd' fields of the CIW, CL, CS,
// Registers specified by the three-bit rs1, rs2, and rd fields of the CIW, CL, CS,
// and CB formats
constraint compressed_three_bits_csr_c {
if(format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT}) {
@ -168,7 +177,7 @@ class riscv_instr_base extends uvm_object;
}
constraint rvc_csr_c {
// Registers specified by the three-bit rs1', rs2', and rd' fields of the CIW, CL, CS,
// Registers specified by the three-bit rs1, rs2, and rd fields of the CIW, CL, CS,
// and CB formats
if(format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT}) {
rs1 inside {[S0:A5]};
@ -265,36 +274,74 @@ class riscv_instr_base extends uvm_object;
`add_instr(REMUW, R_FORMAT, ARITHMETIC, RV64M)
//////////// RV32F instructions //////////////
`add_instr(FLW, R_FORMAT, LOAD, RV32F)
`add_instr(FSW, R_FORMAT, STORE, RV32F)
`add_instr(FMADD_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMSUB_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FNMSUB_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FNMADD_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FLW, I_FORMAT, LOAD, RV32F)
`add_instr(FSW, S_FORMAT, STORE, RV32F)
`add_instr(FMADD_S, R4_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMSUB_S, R4_FORMAT, ARITHMETIC, RV32F)
`add_instr(FNMSUB_S, R4_FORMAT, ARITHMETIC, RV32F)
`add_instr(FNMADD_S, R4_FORMAT, ARITHMETIC, RV32F)
`add_instr(FADD_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSUB_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMUL_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FDIV_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSQRT_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSQRT_S, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSGNJ_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSGNJN_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FSGNJX_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMIN_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMAX_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_W_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_WU_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMV_X_W, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FEQ_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FLT_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FLE_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_W_S, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_WU_S, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMV_X_W, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FEQ_S, R_FORMAT, COMPARE, RV32F)
`add_instr(FLT_S, R_FORMAT, COMPARE, RV32F)
`add_instr(FLE_S, R_FORMAT, COMPARE, RV32F)
`add_instr(FCLASS_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_W, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_WU, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMV_W_X, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_L_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_LU_S, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_L, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_LU, R_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_W, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FCVT_S_WU, I_FORMAT, ARITHMETIC, RV32F)
`add_instr(FMV_W_X, I_FORMAT, ARITHMETIC, RV32F)
///////////// RV64F instruction /////////////////
`add_instr(FCVT_L_S, I_FORMAT, ARITHMETIC, RV64F)
`add_instr(FCVT_LU_S, I_FORMAT, ARITHMETIC, RV64F)
`add_instr(FCVT_S_L, I_FORMAT, ARITHMETIC, RV64F)
`add_instr(FCVT_S_LU, I_FORMAT, ARITHMETIC, RV64F)
//////////// RV32D instructions ////////////////
`add_instr(FLD, I_FORMAT, LOAD, RV32D)
`add_instr(FSD, S_FORMAT, STORE, RV32D)
`add_instr(FMADD_D, R4_FORMAT, ARITHMETIC, RV32D)
`add_instr(FMSUB_D, R4_FORMAT, ARITHMETIC, RV32D)
`add_instr(FNMSUB_D, R4_FORMAT, ARITHMETIC, RV32D)
`add_instr(FNMADD_D, R4_FORMAT, ARITHMETIC, RV32D)
`add_instr(FADD_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FSUB_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FMUL_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FDIV_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FSQRT_D, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FSGNJ_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FSGNJN_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FSGNJX_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FMIN_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FMAX_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_S_D, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_D_S, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FEQ_D, R_FORMAT, COMPARE, RV32D)
`add_instr(FLT_D, R_FORMAT, COMPARE, RV32D)
`add_instr(FLE_D, R_FORMAT, COMPARE, RV32D)
`add_instr(FCLASS_D, R_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_W_D, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_WU_D, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_D_W, I_FORMAT, ARITHMETIC, RV32D)
`add_instr(FCVT_D_WU, I_FORMAT, ARITHMETIC, RV32D)
////////////// RV64D instruction ///////////////
`add_instr(FMV_X_D, I_FORMAT, ARITHMETIC, RV64D)
`add_instr(FMV_D_X, I_FORMAT, ARITHMETIC, RV64D)
`add_instr(FCVT_L_D, I_FORMAT, ARITHMETIC, RV64D)
`add_instr(FCVT_LU_D, I_FORMAT, ARITHMETIC, RV64D)
`add_instr(FCVT_D_L, I_FORMAT, ARITHMETIC, RV64D)
`add_instr(FCVT_D_LU, I_FORMAT, ARITHMETIC, RV64D)
// RV64I instructions
// LOAD/STORE instructions
@ -429,6 +476,43 @@ class riscv_instr_base extends uvm_object;
has_rs1 = 1'b0;
end
end
// TODO(taliu) Add support for compressed floating point format
if (group inside {RV32F, RV64F, RV32D, RV64D, RV32FC, RV32DC}) begin
is_floating_point = 1'b1;
has_rs1 = 1'b0;
has_rs2 = 1'b0;
has_rd = 1'b0;
has_fs1 = 1'b1;
if (format == R4_FORMAT) begin
has_fs3 = 1'b1;
end
if (format != S_FORMAT) begin
if ((category == COMPARE) || (instr_name inside {FCLASS_S, FCLASS_D})) begin
has_rd = 1'b1;
end else begin
has_fd = 1'b1;
end
end
if (format != I_FORMAT) begin
has_fs2 = 1'b1;
end
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
// Floating point to integer operation
has_rd = 1'b1;
has_fs1 = 1'b1;
has_fd = 1'b0;
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, FLW, FLD, FSW, FSD,
C_FLW, C_FLD, C_FSW, C_FSD}) begin
// Integer to floating point operation
has_fd = 1'b1;
has_fs1 = 1'b0;
has_rs1 = 1'b1;
end
end
endfunction
function void mask_imm();
@ -501,18 +585,38 @@ class riscv_instr_base extends uvm_object;
return gpr;
endfunction
function riscv_fpr_t gen_rand_fpr(riscv_fpr_t excluded_reg[] = {});
riscv_fpr_t fpr;
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(fpr,
if (excluded_reg.size() > 0) {
!(fpr inside {excluded_reg});
}
if (is_compressed) {
fpr inside {[F8:F15]};
});
return fpr;
endfunction
function void gen_rand_csr(bit illegal_csr_instr = 0,
bit enable_floating_point = 0,
privileged_mode_t privileged_mode = MACHINE_MODE);
privileged_reg_t preg[$];
if (illegal_csr_instr) begin
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(csr, !(csr inside {implemented_csr});)
end else begin
// Use scratch register to avoid the side effect of modifying other privileged mode CSR.
if (privileged_mode == MACHINE_MODE)
csr = MSCRATCH;
preg = {MSCRATCH};
else if (privileged_mode == SUPERVISOR_MODE)
csr = SSCRATCH;
preg = {SSCRATCH};
else
csr = USCRATCH;
preg = {USCRATCH};
if (enable_floating_point) begin
preg = {preg, FFLAGS, FRM, FCSR};
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(csr, csr inside {preg};)
end else begin
csr = preg[0];
end
end
endfunction
@ -533,7 +637,43 @@ class riscv_instr_base extends uvm_object;
virtual function string convert2asm(string prefix = "");
string asm_str;
asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
if((category != SYSTEM) && !(group inside {RV32A, RV64A})) begin
if (is_floating_point) begin
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
end else if((category != SYSTEM) && !(group inside {RV32A, RV64A})) begin
case(format)
J_FORMAT, U_FORMAT : // instr rd,imm
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
@ -982,6 +1122,12 @@ class riscv_instr_base extends uvm_object;
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 if (group inside {RV32F, RV64F, RV32D, RV64D}) begin
foreach(get_instr_name[i]) begin
if (get_instr_name[i] == "_") begin
get_instr_name[i] = ".";
end
end
end
return get_instr_name;
endfunction
@ -1005,26 +1151,35 @@ class riscv_instr_base extends uvm_object;
// Copy the rand fields of the base instruction
virtual function void copy_base_instr(riscv_instr_base obj);
this.group = obj.group;
this.format = obj.format;
this.category = obj.category;
this.instr_name = obj.instr_name;
this.rs2 = obj.rs2;
this.rs1 = obj.rs1;
this.rd = obj.rd;
this.imm = obj.imm;
this.imm_type = obj.imm_type;
this.imm_len = obj.imm_len;
this.imm_mask = obj.imm_mask;
this.imm_str = obj.imm_str;
this.is_pseudo_instr = obj.is_pseudo_instr;
this.aq = obj.aq;
this.rl = obj.rl;
this.is_compressed = obj.is_compressed;
this.has_imm = obj.has_imm;
this.has_rs1 = obj.has_rs1;
this.has_rs2 = obj.has_rs2;
this.has_rd = obj.has_rd;
this.group = obj.group;
this.format = obj.format;
this.category = obj.category;
this.instr_name = obj.instr_name;
this.rs2 = obj.rs2;
this.rs1 = obj.rs1;
this.rd = obj.rd;
this.imm = obj.imm;
this.imm_type = obj.imm_type;
this.imm_len = obj.imm_len;
this.imm_mask = obj.imm_mask;
this.imm_str = obj.imm_str;
this.is_pseudo_instr = obj.is_pseudo_instr;
this.aq = obj.aq;
this.rl = obj.rl;
this.is_compressed = obj.is_compressed;
this.has_imm = obj.has_imm;
this.has_rs1 = obj.has_rs1;
this.has_rs2 = obj.has_rs2;
this.has_rd = obj.has_rd;
this.fs3 = obj.fs3;
this.fs2 = obj.fs2;
this.fs1 = obj.fs1;
this.fd = obj.fd;
this.has_fs1 = obj.has_fs1;
this.has_fs2 = obj.has_fs2;
this.has_fs3 = obj.has_fs3;
this.has_fd = obj.has_fd;
this.is_floating_point = obj.is_floating_point;
endfunction
endclass

View file

@ -59,8 +59,12 @@ class riscv_instr_gen_config extends uvm_object;
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;
@ -196,6 +200,8 @@ class riscv_instr_gen_config extends uvm_object;
int max_directed_instr_stream_seq = 20;
// Reserved registers
riscv_reg_t reserved_regs[];
// Floating point support
bit enable_floating_point;
uvm_cmdline_processor inst;
@ -346,6 +352,14 @@ class riscv_instr_gen_config extends uvm_object;
}
}
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)
@ -390,6 +404,7 @@ class riscv_instr_gen_config extends uvm_object;
get_bool_arg_value("+enable_ebreak_in_debug_rom=", enable_ebreak_in_debug_rom);
get_bool_arg_value("+set_dcsr_ebreak=", set_dcsr_ebreak);
get_bool_arg_value("+enable_debug_single_step=", enable_debug_single_step);
get_bool_arg_value("+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)
@ -528,7 +543,8 @@ class riscv_instr_gen_config extends uvm_object;
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)) begin
!(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);
@ -544,13 +560,11 @@ class riscv_instr_gen_config extends uvm_object;
virtual function void build_instruction_list();
basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
instr_category[LOGICAL], instr_category[COMPARE]};
if (no_ebreak == 0) begin
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
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

View file

@ -42,6 +42,14 @@ package riscv_instr_pkg;
SV64 = 4'b1011
} satp_mode_t;
typedef enum bit [2:0] {
RNE = 3'b000,
RTZ = 3'b001,
RDN = 3'b010,
RUP = 3'b011,
RMM = 3'b100
} f_rounding_mode_t;
typedef enum bit [1:0] {
DIRECT = 2'b00,
VECTORED = 2'b01
@ -173,10 +181,45 @@ package riscv_instr_pkg;
FCVT_S_W,
FCVT_S_WU,
FMV_W_X,
// RV64F instruction
FCVT_L_S,
FCVT_LU_S,
FCVT_S_L,
FCVT_S_LU,
// RV32D instructions
FLD,
FSD,
FMADD_D,
FMSUB_D,
FNMSUB_D,
FNMADD_D,
FADD_D,
FSUB_D,
FMUL_D,
FDIV_D,
FSQRT_D,
FSGNJ_D,
FSGNJN_D,
FSGNJX_D,
FMIN_D,
FMAX_D,
FCVT_S_D,
FCVT_D_S,
FEQ_D,
FLT_D,
FLE_D,
FCLASS_D,
FCVT_W_D,
FCVT_WU_D,
FCVT_D_W,
FCVT_D_WU,
// RV64D
FCVT_L_D,
FCVT_LU_D,
FMV_X_D,
FCVT_D_L,
FCVT_D_LU,
FMV_D_X,
// RV64I
LWU,
LD,
@ -284,39 +327,15 @@ package riscv_instr_pkg;
typedef enum bit [4:0] {
ZERO = 5'b00000,
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
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
} riscv_reg_t;
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] {
J_FORMAT = 0,
U_FORMAT,
@ -324,6 +343,7 @@ package riscv_instr_pkg;
B_FORMAT,
R_FORMAT,
S_FORMAT,
R4_FORMAT,
CI_FORMAT,
CB_FORMAT,
CJ_FORMAT,

View file

@ -203,7 +203,7 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
riscv_instr_name_t instr_name;
// if set_dcsr_ebreak is set, we do not want to generate any ebreak
// instructions inside the debug_rom
if (!cfg.enable_ebreak_in_debug_rom && is_in_debug) begin
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});)
@ -247,8 +247,21 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
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));
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

View file

@ -122,18 +122,30 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
if (!cfg.enable_unaligned_load_store) begin
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

View file

@ -56,20 +56,18 @@ class riscv_privileged_common_seq extends uvm_sequence;
mstatus = riscv_privil_reg::type_id::create("mstatus");
mstatus.init_reg(MSTATUS);
if (cfg.randomize_csr) begin
mstatus.set_val({cfg.mstatus[XLEN-1:XLEN-21], cfg.mstatus_tvm, cfg.mstatus_mxr,
cfg.mstatus_sum, cfg.mstatus_mprv, cfg.mstatus[16:0]});
end else begin
mstatus.set_field("MPRV", cfg.mstatus_mprv);
mstatus.set_field("MXR", cfg.mstatus_mxr);
mstatus.set_field("SUM", cfg.mstatus_sum);
mstatus.set_field("TVM", cfg.mstatus_tvm);
mstatus.set_val(cfg.mstatus);
end
mstatus.set_field("MPRV", cfg.mstatus_mprv);
mstatus.set_field("MXR", cfg.mstatus_mxr);
mstatus.set_field("SUM", cfg.mstatus_sum);
mstatus.set_field("TVM", cfg.mstatus_tvm);
mstatus.set_field("FS", cfg.mstatus_fs);
if(XLEN==64) begin
mstatus.set_field("UXL", 2'b10);
mstatus.set_field("SXL", 2'b10);
end
mstatus.set_field("XS", 0);
mstatus.set_field("FS", 0);
mstatus.set_field("SD", 0);
mstatus.set_field("UIE", 0);
// Set the previous privileged mode as the target mode
@ -121,8 +119,8 @@ class riscv_privileged_common_seq extends uvm_sequence;
if(XLEN==64) begin
sstatus.set_field("UXL", 2'b10);
end
sstatus.set_field("FS", cfg.mstatus_fs);
sstatus.set_field("XS", 0);
sstatus.set_field("FS", 0);
sstatus.set_field("SD", 0);
sstatus.set_field("UIE", 0);
sstatus.set_field("SPP", 0);

View file

@ -113,6 +113,21 @@ class riscv_rand_instr extends riscv_instr_base;
}
}
constraint floating_point_c {
if (!cfg.enable_floating_point) {
!(group inside {RV32F, RV64F, RV32D, RV64D});
}
}
function void pre_randomize();
if (!cfg.enable_floating_point) begin
fs1.rand_mode(0);
fs2.rand_mode(0);
fs3.rand_mode(0);
fd.rand_mode(0);
end
endfunction
// No label is needed if there's no branch/jump instruction
function void post_randomize();
super.post_randomize();

View file

@ -15,7 +15,7 @@
- iss: spike
path_var: SPIKE_PATH
cmd: >
<path_var>/spike --isa=<variant> -l <elf>
<path_var>/spike --log-commits --isa=<variant> -l <elf>
- iss: ovpsim
path_var: OVPSIM_PATH

View file

@ -66,7 +66,7 @@
cmd: >
vsim -64 -c <cov_opts> -do <cwd>/questa_sim.tcl design_opt <sim_opts> -sv_seed <seed>
cov_opts: >
-do "coverage save -onexit cov.ucdb;"
-do "coverage save -onexit <out>/cov.ucdb;"
- tool: dsim
env_var: DSIM,DSIM_LIB_PATH

View file

@ -255,3 +255,43 @@
+directed_instr_0=riscv_lr_sc_instr_stream,10
+directed_instr_1=riscv_amo_instr_stream,10
rtl_test: core_base_test
- test: riscv_floating_point_arithmetic_test
description: >
Enable floating point instructions
gen_opts: >
+instr_cnt=10000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+enable_floating_point=1
+boot_mode=m
iterations: 1
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_floating_point_rand_test
description: >
Enable floating point instructions
gen_opts: >
+enable_floating_point=1
iterations: 1
gen_test: riscv_rand_instr_test
rtl_test: core_base_test
- test: riscv_floating_point_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
iterations: 2
gen_test: riscv_instr_base_test
gen_opts: >
+instr_cnt=5000
+num_of_sub_program=5
+enable_floating_point=1
+directed_instr_0=riscv_load_store_rand_instr_stream,40
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
rtl_test: core_base_test