mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
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:
parent
fc80203af3
commit
b2e36ec345
20 changed files with 477 additions and 141 deletions
2
vendor/google_riscv-dv.lock.hjson
vendored
2
vendor/google_riscv-dv.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/google/riscv-dv
|
||||
rev: ad6fe565a91445cc3ea3e32119360b57af4f19b2
|
||||
rev: 033fccfbd50f6412e66b448a1d04245d787004bd
|
||||
}
|
||||
}
|
||||
|
|
8
vendor/google_riscv-dv/README.md
vendored
8
vendor/google_riscv-dv/README.md
vendored
|
@ -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
|
||||
|
|
28
vendor/google_riscv-dv/cov.py
vendored
28
vendor/google_riscv-dv/cov.py
vendored
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
4
vendor/google_riscv-dv/scripts/lib.py
vendored
4
vendor/google_riscv-dv/scripts/lib.py
vendored
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
247
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
247
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
82
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
82
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
|
@ -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,
|
||||
|
|
15
vendor/google_riscv-dv/src/riscv_instr_stream.sv
vendored
15
vendor/google_riscv-dv/src/riscv_instr_stream.sv
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
15
vendor/google_riscv-dv/src/riscv_rand_instr.sv
vendored
15
vendor/google_riscv-dv/src/riscv_rand_instr.sv
vendored
|
@ -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();
|
||||
|
|
2
vendor/google_riscv-dv/yaml/iss.yaml
vendored
2
vendor/google_riscv-dv/yaml/iss.yaml
vendored
|
@ -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
|
||||
|
|
2
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
2
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
|
@ -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
|
||||
|
|
40
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
40
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue