mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 13:07:46 -04:00
Update google_riscv-dv to google/riscv-dv@5baf82a (#723)
Update code from upstream repository https://github.com/google/riscv- dv to revision 5baf82a24347dae3cb71c8ab66a66494666d2291 * Fix illegal func3/func7 instruction generation for B-extension (google/riscv-dv#525) (taoliug) * more tightly constrain pmpaddr values (google/riscv-dv#524) (udinator) * Update style check (Weicai Yang) * Bump verible (Tomasz Gorochowik) * Add target for B-extension (google/riscv-dv#521) (taoliug) * [cov] tag coverage database directories with <test_id> (Udi Jonnalagadda) * Add bit manipulation (google/riscv-dv#518) (weicaiyang) * Don't change input file in spike_log_to_trace_csv.py (google/riscv- dv#504) (Rupert Swarbrick) * Fix ius constraint solver failure (google/riscv-dv#515) (taoliug) * Fix AMO sequence address generation issue (google/riscv-dv#514) (taoliug) * Remove alignment constraint (google/riscv-dv#513) (taoliug) * Add section for each data region (google/riscv-dv#512) (taoliug) Signed-off-by: Udi <udij@google.com>
This commit is contained in:
parent
3af3e72b2f
commit
2c198383a3
27 changed files with 1292 additions and 138 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: 3f584adef07b7f04edda8a6ba1dfc01a14df5d98
|
||||
rev: 5baf82a24347dae3cb71c8ab66a66494666d2291
|
||||
}
|
||||
}
|
||||
|
|
11
vendor/google_riscv-dv/run.py
vendored
11
vendor/google_riscv-dv/run.py
vendored
|
@ -250,6 +250,7 @@ def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file,
|
|||
if verbose:
|
||||
cmd += "+UVM_VERBOSITY=UVM_HIGH "
|
||||
cmd = re.sub("<seed>", str(rand_seed), cmd)
|
||||
cmd = re.sub("<test_id>", test_id, cmd)
|
||||
sim_seed[test_id] = str(rand_seed)
|
||||
if "gen_opts" in test:
|
||||
cmd += test['gen_opts']
|
||||
|
@ -730,6 +731,8 @@ def setup_parser():
|
|||
help="Stop on detecting first error")
|
||||
parser.add_argument("--noclean", action="store_true", default=True,
|
||||
help="Do not clean the output of the previous runs")
|
||||
parser.add_argument("--verilog_style_check", action="store_true", default=False,
|
||||
help="Run verilog style check")
|
||||
parser.add_argument("-d", "--debug", type=str, default="",
|
||||
help="Generate debug command log file")
|
||||
return parser
|
||||
|
@ -772,6 +775,9 @@ def load_config(args, cwd):
|
|||
elif args.target == "multi_harts":
|
||||
args.mabi = "ilp32"
|
||||
args.isa = "rv32gc"
|
||||
elif args.target == "rv32imcb":
|
||||
args.mabi = "ilp32"
|
||||
args.isa = "rv32imcb"
|
||||
elif args.target == "rv32i":
|
||||
args.mabi = "ilp32"
|
||||
args.isa = "rv32i"
|
||||
|
@ -813,6 +819,11 @@ def main():
|
|||
# Create output directory
|
||||
output_dir = create_output(args.o, args.noclean)
|
||||
|
||||
if args.verilog_style_check:
|
||||
logging.debug("Run style check")
|
||||
style_err = run_cmd("verilog_style/run.sh")
|
||||
if style_err: logging.info("Found style error: \nERROR: " + style_err)
|
||||
|
||||
# Run any handcoded/directed assembly tests specified by args.asm_tests
|
||||
if args.asm_tests != "":
|
||||
asm_test = args.asm_tests.split(',')
|
||||
|
|
|
@ -34,70 +34,6 @@ ILLE_RE = re.compile(r"trap_illegal_instruction")
|
|||
|
||||
LOGGER = logging.getLogger()
|
||||
|
||||
def process_spike_sim_log(spike_log, csv, full_trace = 0):
|
||||
"""Process SPIKE simulation log.
|
||||
|
||||
Extract instruction and affected register information from spike simulation
|
||||
log and save to a list.
|
||||
"""
|
||||
logging.info("Processing spike log : %s" % spike_log)
|
||||
instr_cnt = 0
|
||||
spike_instr = ""
|
||||
|
||||
# Remove all the init spike boot instructions
|
||||
cmd = ("sed -i '/core.*0x0000000000001010/,$!d' %s" % spike_log)
|
||||
os.system(cmd)
|
||||
# Remove all instructions after ecall (end of program excecution)
|
||||
cmd = ("sed -i '/ecall/q' %s" % spike_log)
|
||||
os.system(cmd)
|
||||
|
||||
with open(spike_log, "r") as f, open(csv, "w") as csv_fd:
|
||||
trace_csv = RiscvInstructionTraceCsv(csv_fd)
|
||||
trace_csv.start_new_trace()
|
||||
for line in f:
|
||||
# Extract instruction infromation
|
||||
m = CORE_RE.search(line)
|
||||
if m:
|
||||
instr_cnt += 1
|
||||
spike_instr = m.group("instr").replace("pc + ", "")
|
||||
spike_instr = spike_instr.replace("pc - ", "-")
|
||||
rv_instr_trace = RiscvInstructionTraceEntry()
|
||||
rv_instr_trace.pc = m.group("addr")
|
||||
rv_instr_trace.instr_str = spike_instr
|
||||
rv_instr_trace.binary = m.group("bin")
|
||||
if full_trace:
|
||||
rv_instr_trace.instr = spike_instr.split(" ")[0]
|
||||
rv_instr_trace.operand = spike_instr[len(rv_instr_trace.instr):]
|
||||
rv_instr_trace.operand = rv_instr_trace.operand.replace(" ", "")
|
||||
rv_instr_trace.instr, rv_instr_trace.operand = convert_pseudo_instr(
|
||||
rv_instr_trace.instr, rv_instr_trace.operand, rv_instr_trace.binary)
|
||||
process_instr(rv_instr_trace)
|
||||
if spike_instr == "wfi":
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
continue
|
||||
nextline = f.readline()
|
||||
if nextline != "":
|
||||
if ILLE_RE.search(nextline):
|
||||
if full_trace:
|
||||
logging.debug("Illegal instruction: %s, opcode:%s" %
|
||||
(rv_instr_trace.instr_str, rv_instr_trace.binary))
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
continue
|
||||
m = RD_RE.search(nextline)
|
||||
if m:
|
||||
# Extract RD information
|
||||
rv_instr_trace.gpr.append(
|
||||
gpr_to_abi(m.group("reg").replace(" ","")) + ":" + m.group("val"))
|
||||
rv_instr_trace.mode = m.group("pri")
|
||||
else:
|
||||
# If full trace is not enabled, skip the entry that doesn't have
|
||||
# architectural state update.
|
||||
if not full_trace:
|
||||
continue
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
logging.info("Processed instruction count : %d" % instr_cnt)
|
||||
logging.info("CSV saved to : %s" % csv)
|
||||
|
||||
|
||||
def process_instr(trace):
|
||||
if trace.instr == "jal":
|
||||
|
@ -113,6 +49,171 @@ def process_instr(trace):
|
|||
trace.operand = trace.operand.replace(")", "")
|
||||
|
||||
|
||||
def read_spike_instr(match, full_trace):
|
||||
'''Unpack a regex match for CORE_RE to a RiscvInstructionTraceEntry
|
||||
|
||||
If full_trace is true, extract operand data from the disassembled
|
||||
instruction.
|
||||
|
||||
'''
|
||||
|
||||
# Extract the disassembled instruction.
|
||||
disasm = match.group('instr')
|
||||
|
||||
# Spike's disassembler shows a relative jump as something like "j pc +
|
||||
# 0x123" or "j pc - 0x123". We just want the relative offset.
|
||||
disasm = disasm.replace('pc + ', '').replace('pc - ', '-')
|
||||
|
||||
instr = RiscvInstructionTraceEntry()
|
||||
instr.pc = match.group('addr')
|
||||
instr.instr_str = disasm
|
||||
instr.binary = match.group('bin')
|
||||
|
||||
if full_trace:
|
||||
opcode = disasm.split(' ')[0]
|
||||
operand = disasm[len(opcode):].replace(' ', '')
|
||||
instr.instr, instr.operand = \
|
||||
convert_pseudo_instr(opcode, operand, instr.binary)
|
||||
|
||||
process_instr(instr)
|
||||
|
||||
return instr
|
||||
|
||||
|
||||
def read_spike_trace(path, full_trace):
|
||||
'''Read a Spike simulation log at <path>, yielding executed instructions.
|
||||
|
||||
This assumes that the log was generated with the -l and --log-commits options
|
||||
to Spike.
|
||||
|
||||
If full_trace is true, extract operands from the disassembled instructions.
|
||||
|
||||
Since Spike has a strange trampoline that always runs at the start, we skip
|
||||
instructions up to and including the one at PC 0x1010 (the end of the
|
||||
trampoline). At the end of a DV program, there's an ECALL instruction, which
|
||||
we take as a signal to stop checking, so we ditch everything that follows
|
||||
that instruction.
|
||||
|
||||
This function yields instructions as it parses them as tuples of the form
|
||||
(entry, illegal). entry is a RiscvInstructionTraceEntry. illegal is a
|
||||
boolean, which is true if the instruction caused an illegal instruction trap.
|
||||
|
||||
'''
|
||||
|
||||
# This loop is a simple FSM with states TRAMPOLINE, INSTR, EFFECT. The idea
|
||||
# is that we're in state TRAMPOLINE until we get to the end of Spike's
|
||||
# trampoline, then we switch between INSTR (where we expect to read an
|
||||
# instruction) and EFFECT (where we expect to read commit information).
|
||||
#
|
||||
# We yield a RiscvInstructionTraceEntry object each time we leave EFFECT
|
||||
# (going back to INSTR), we loop back from INSTR to itself, or we get to the
|
||||
# end of the file and have an instruction in hand.
|
||||
#
|
||||
# On entry to the loop body, we are in state TRAMPOLINE if in_trampoline is
|
||||
# true. Otherwise, we are in state EFFECT if instr is not None, otherwise we
|
||||
# are in state INSTR.
|
||||
|
||||
end_trampoline_re = re.compile(r'core.*: 0x0*1010 ')
|
||||
|
||||
in_trampoline = True
|
||||
instr = None
|
||||
|
||||
with open(path, 'r') as handle:
|
||||
for line in handle:
|
||||
if in_trampoline:
|
||||
# The TRAMPOLINE state
|
||||
if end_trampoline_re.match(line):
|
||||
in_trampoline = False
|
||||
continue
|
||||
|
||||
if instr is None:
|
||||
# The INSTR state. We expect to see a line matching CORE_RE. We'll
|
||||
# discard any other lines.
|
||||
instr_match = CORE_RE.match(line)
|
||||
if not instr_match:
|
||||
continue
|
||||
|
||||
instr = read_spike_instr(instr_match, full_trace)
|
||||
|
||||
# If instr.instr_str is 'ecall', we should stop.
|
||||
if instr.instr_str == 'ecall':
|
||||
break
|
||||
|
||||
continue
|
||||
|
||||
# The EFFECT state. If the line matches CORE_RE, we should have been in
|
||||
# state INSTR, so we yield the instruction we had, read the new
|
||||
# instruction and continue. As above, if the new instruction is 'ecall',
|
||||
# we need to stop immediately.
|
||||
instr_match = CORE_RE.match(line)
|
||||
if instr_match:
|
||||
yield (instr, False)
|
||||
instr = read_spike_instr(instr_match, full_trace)
|
||||
if instr.instr_str == 'ecall':
|
||||
break
|
||||
continue
|
||||
|
||||
# The line doesn't match CORE_RE, so we are definitely on a follow-on
|
||||
# line in the log. First, check for illegal instructions
|
||||
if 'trap_illegal_instruction' in line:
|
||||
yield (instr, True)
|
||||
instr = None
|
||||
continue
|
||||
|
||||
# The instruction seems to have been fine. Do we have commit data (from
|
||||
# the --log-commits Spike option)?
|
||||
commit_match = RD_RE.match(line)
|
||||
if commit_match:
|
||||
instr.gpr.append(gpr_to_abi(commit_match.group('reg')
|
||||
.replace(' ', '')) +
|
||||
':' + commit_match.group('val'))
|
||||
instr.mode = commit_match.group('pri')
|
||||
|
||||
# At EOF, we might have an instruction in hand. Yield it if so.
|
||||
if instr is not None:
|
||||
yield (instr, False)
|
||||
|
||||
|
||||
def process_spike_sim_log(spike_log, csv, full_trace = 0):
|
||||
"""Process SPIKE simulation log.
|
||||
|
||||
Extract instruction and affected register information from spike simulation
|
||||
log and write the results to a CSV file at csv. Returns the number of
|
||||
instructions written.
|
||||
|
||||
"""
|
||||
logging.info("Processing spike log : %s" % spike_log)
|
||||
instrs_in = 0
|
||||
instrs_out = 0
|
||||
|
||||
with open(csv, "w") as csv_fd:
|
||||
trace_csv = RiscvInstructionTraceCsv(csv_fd)
|
||||
trace_csv.start_new_trace()
|
||||
|
||||
for (entry, illegal) in read_spike_trace(spike_log, full_trace):
|
||||
instrs_in += 1
|
||||
|
||||
if illegal and full_trace:
|
||||
logging.debug("Illegal instruction: {}, opcode:{}"
|
||||
.format(entry.instr_str, entry.binary))
|
||||
|
||||
# Instructions that cause no architectural update (which includes illegal
|
||||
# instructions) are ignored if full_trace is false.
|
||||
#
|
||||
# We say that an instruction caused an architectural update if either we
|
||||
# saw a commit line (in which case, entry.gpr will contain a single
|
||||
# entry) or the instruction was 'wfi' or 'ecall'.
|
||||
if not (full_trace or entry.gpr or entry.instr_str in ['wfi', 'ecall']):
|
||||
continue
|
||||
|
||||
trace_csv.write_trace_entry(entry)
|
||||
instrs_out += 1
|
||||
|
||||
logging.info("Processed instruction count : %d" % instrs_in)
|
||||
logging.info("CSV saved to : %s" % csv)
|
||||
return instrs_out
|
||||
|
||||
|
||||
def main():
|
||||
# Parse input arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
|
|
459
vendor/google_riscv-dv/src/isa/riscv_b_instr.sv
vendored
Executable file
459
vendor/google_riscv-dv/src/isa/riscv_b_instr.sv
vendored
Executable file
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* Copyright 2019 Mellanox Technologies Ltd
|
||||
*
|
||||
* 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_b_instr extends riscv_instr;
|
||||
|
||||
rand riscv_reg_t rs3;
|
||||
bit has_rs3 = 1'b0;
|
||||
|
||||
`uvm_object_utils(riscv_b_instr)
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
virtual function void set_rand_mode();
|
||||
super.set_rand_mode();
|
||||
has_rs3 = 1'b0;
|
||||
case (format) inside
|
||||
R4_FORMAT: begin
|
||||
has_imm = 1'b0;
|
||||
has_rs3 = 1'b1;
|
||||
end
|
||||
I_FORMAT: begin
|
||||
has_rs2 = 1'b0;
|
||||
if (instr_name inside {FSRI, FSRIW}) begin
|
||||
has_rs3 = 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
endfunction
|
||||
|
||||
function void pre_randomize();
|
||||
super.pre_randomize();
|
||||
rs3.rand_mode(has_rs3);
|
||||
endfunction
|
||||
|
||||
|
||||
virtual function void set_imm_len();
|
||||
|
||||
if (format inside {I_FORMAT}) begin
|
||||
if (category inside {SHIFT, LOGICAL}) begin
|
||||
imm_len = 7;
|
||||
|
||||
if (group == RV64B) begin
|
||||
imm_len = 5;
|
||||
if (instr_name inside {SLLIU_W}) begin
|
||||
imm_len = 6;
|
||||
end
|
||||
end
|
||||
|
||||
if ((group == RV32B) && (imm_type == UIMM)) begin
|
||||
imm_len = 6;
|
||||
end
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV32B)) begin
|
||||
imm_len = 5;
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV64B)) begin
|
||||
imm_len = 12;
|
||||
end
|
||||
end
|
||||
|
||||
imm_mask = imm_mask << imm_len;
|
||||
endfunction
|
||||
|
||||
// Convert the instruction to assembly code
|
||||
virtual function string convert2asm(string prefix = "");
|
||||
string asm_str_super, asm_str;
|
||||
asm_str_super = super.convert2asm(prefix);
|
||||
asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
|
||||
|
||||
case (format)
|
||||
I_FORMAT: begin
|
||||
if (instr_name inside {FSRI, FSRIW}) begin // instr rd,rs1,rs3,imm
|
||||
asm_str_super = $sformatf("%0s%0s, %0s, %0s, %0s", asm_str, rd.name(), rs1.name(),
|
||||
rs3.name(), get_imm());
|
||||
end
|
||||
end
|
||||
|
||||
R_FORMAT: begin //instr rd rs1
|
||||
if (instr_name inside {CLZW, CTZW, PCNTW, SEXT_B, SEXT_H, CLZ, CTZ, PCNT, BMATFLIP}) begin
|
||||
asm_str_super = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs1.name());
|
||||
end
|
||||
|
||||
if (instr_name inside {CRC32_B, CRC32_H, CRC32_W, CRC32C_B, CRC32C_H, CRC32C_W, CRC32_D,
|
||||
CRC32C_D}) begin
|
||||
asm_str_super = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs1.name());
|
||||
end
|
||||
end
|
||||
|
||||
R4_FORMAT: begin // instr rd,rs1,rs2,rs3
|
||||
asm_str_super = $sformatf("%0s%0s, %0s, %0s, %0s", asm_str, rd.name(), rs1.name(),
|
||||
rs2.name(), rs3.name());
|
||||
end
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
|
||||
endcase
|
||||
|
||||
if (comment != "") begin
|
||||
asm_str = {asm_str, " #", comment};
|
||||
return asm_str.tolower();
|
||||
end
|
||||
|
||||
return asm_str_super.tolower();
|
||||
endfunction
|
||||
|
||||
function bit [6:0] get_opcode();
|
||||
case (instr_name) inside
|
||||
ANDN, ORN, XNOR, GORC, SLO, SRO, ROL, ROR, SBCLR, SBSET, SBINV, SBEXT,
|
||||
GREV: get_opcode = 7'b0110011;
|
||||
SLOI, SROI, RORI, SBCLRI, SBSETI, SBINVI, SBEXTI, GORCI, GREVI, CMIX, CMOV,
|
||||
FSL: get_opcode = 7'b0010011;
|
||||
FSR, FSRI, CLZ, CTZ, PCNT, BMATFLIP, SEXT_B, SEXT_H, CRC32_B, CRC32_H, CRC32_W, CRC32C_B,
|
||||
CRC32C_H: get_opcode = 7'b0010011;
|
||||
CRC32C_W, CRC32_D, CRC32C_D: get_opcode = 7'b0010011;
|
||||
CLMUL, CLMULR, CLMULH, MIN, MAX, MINU, MAXU, SHFL, UNSHFL, BDEP, BEXT, PACK, PACKU, BMATOR,
|
||||
BMATXOR, PACKH, BFP: get_opcode = 7'b0110011;
|
||||
SHFLI, UNSHFLI: get_opcode = 7'b0010011;
|
||||
ADDIWU, SLLIU_W: get_opcode = 7'b0011011;
|
||||
ADDWU, SUBWU, ADDU_W, SUBU_W, SLOW, SROW, ROLW, RORW, SBCLRW, SBSETW, SBINVW, SBEXTW, GORCW,
|
||||
GREVW: get_opcode = 7'b0111011;
|
||||
SLOIW, SROIW, RORIW, SBCLRIW, SBSETIW, SBINVIW, GORCIW, GREVIW: get_opcode = 7'b0011011;
|
||||
FSLW, FSRW: get_opcode = 7'b0111011;
|
||||
FSRIW, CLZW, CTZW, PCNTW: get_opcode = 7'b0011011;
|
||||
CLMULW, CLMULRW, CLMULHW, SHFLW, UNSHFLW, BDEPW, BEXTW, PACKW, PACKUW,
|
||||
BFPW: get_opcode = 7'b0111011;
|
||||
default: get_opcode = super.get_opcode();
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
virtual function bit [2:0] get_func3();
|
||||
case (instr_name) inside
|
||||
ANDN: get_func3 = 3'b111;
|
||||
ORN: get_func3 = 3'b110;
|
||||
XNOR: get_func3 = 3'b100;
|
||||
GORC: get_func3 = 3'b101;
|
||||
SLO: get_func3 = 3'b001;
|
||||
SRO: get_func3 = 3'b101;
|
||||
ROL: get_func3 = 3'b001;
|
||||
ROR: get_func3 = 3'b101;
|
||||
SBCLR: get_func3 = 3'b001;
|
||||
SBSET: get_func3 = 3'b001;
|
||||
SBINV: get_func3 = 3'b001;
|
||||
SBEXT: get_func3 = 3'b101;
|
||||
GREV: get_func3 = 3'b101;
|
||||
SLOI: get_func3 = 3'b001;
|
||||
SROI: get_func3 = 3'b101;
|
||||
RORI: get_func3 = 3'b101;
|
||||
SBCLRI: get_func3 = 3'b001;
|
||||
SBSETI: get_func3 = 3'b001;
|
||||
SBINVI: get_func3 = 3'b001;
|
||||
SBEXTI: get_func3 = 3'b101;
|
||||
GORCI: get_func3 = 3'b101;
|
||||
GREVI: get_func3 = 3'b101;
|
||||
CMIX: get_func3 = 3'b001;
|
||||
CMOV: get_func3 = 3'b101;
|
||||
FSL: get_func3 = 3'b001;
|
||||
FSR: get_func3 = 3'b101;
|
||||
FSRI: get_func3 = 3'b101;
|
||||
CLZ: get_func3 = 3'b001;
|
||||
CTZ: get_func3 = 3'b001;
|
||||
PCNT: get_func3 = 3'b001;
|
||||
BMATFLIP: get_func3 = 3'b001;
|
||||
SEXT_B: get_func3 = 3'b001;
|
||||
SEXT_H: get_func3 = 3'b001;
|
||||
CRC32_B: get_func3 = 3'b001;
|
||||
CRC32_H: get_func3 = 3'b001;
|
||||
CRC32_W: get_func3 = 3'b001;
|
||||
CRC32C_B: get_func3 = 3'b001;
|
||||
CRC32C_H: get_func3 = 3'b001;
|
||||
CRC32C_W: get_func3 = 3'b001;
|
||||
CRC32_D: get_func3 = 3'b001;
|
||||
CRC32C_D: get_func3 = 3'b001;
|
||||
CLMUL: get_func3 = 3'b001;
|
||||
CLMULR: get_func3 = 3'b010;
|
||||
CLMULH: get_func3 = 3'b011;
|
||||
MIN: get_func3 = 3'b100;
|
||||
MAX: get_func3 = 3'b101;
|
||||
MINU: get_func3 = 3'b110;
|
||||
MAXU: get_func3 = 3'b111;
|
||||
SHFL: get_func3 = 3'b001;
|
||||
UNSHFL: get_func3 = 3'b101;
|
||||
BDEP: get_func3 = 3'b110;
|
||||
BEXT: get_func3 = 3'b110;
|
||||
PACK: get_func3 = 3'b100;
|
||||
PACKU: get_func3 = 3'b100;
|
||||
BMATOR: get_func3 = 3'b011;
|
||||
BMATXOR: get_func3 = 3'b011;
|
||||
PACKH: get_func3 = 3'b111;
|
||||
BFP: get_func3 = 3'b111;
|
||||
SHFLI: get_func3 = 3'b001;
|
||||
UNSHFLI: get_func3 = 3'b101;
|
||||
ADDIWU: get_func3 = 3'b100;
|
||||
SLLIU_W: get_func3 = 3'b001;
|
||||
ADDWU: get_func3 = 3'b000;
|
||||
SUBWU: get_func3 = 3'b000;
|
||||
ADDU_W: get_func3 = 3'b000;
|
||||
SUBU_W: get_func3 = 3'b000;
|
||||
SLOW: get_func3 = 3'b001;
|
||||
SROW: get_func3 = 3'b101;
|
||||
ROLW: get_func3 = 3'b001;
|
||||
RORW: get_func3 = 3'b101;
|
||||
SBCLRW: get_func3 = 3'b001;
|
||||
SBSETW: get_func3 = 3'b001;
|
||||
SBINVW: get_func3 = 3'b001;
|
||||
SBEXTW: get_func3 = 3'b101;
|
||||
GORCW: get_func3 = 3'b101;
|
||||
GREVW: get_func3 = 3'b101;
|
||||
SLOIW: get_func3 = 3'b001;
|
||||
SROIW: get_func3 = 3'b101;
|
||||
RORIW: get_func3 = 3'b101;
|
||||
SBCLRIW: get_func3 = 3'b001;
|
||||
SBSETIW: get_func3 = 3'b001;
|
||||
SBINVIW: get_func3 = 3'b001;
|
||||
GORCIW: get_func3 = 3'b101;
|
||||
GREVIW: get_func3 = 3'b101;
|
||||
FSLW: get_func3 = 3'b001;
|
||||
FSRW: get_func3 = 3'b101;
|
||||
FSRIW: get_func3 = 3'b101;
|
||||
CLZW: get_func3 = 3'b001;
|
||||
CTZW: get_func3 = 3'b001;
|
||||
PCNTW: get_func3 = 3'b001;
|
||||
CLMULW: get_func3 = 3'b001;
|
||||
CLMULRW: get_func3 = 3'b010;
|
||||
CLMULHW: get_func3 = 3'b011;
|
||||
SHFLW: get_func3 = 3'b001;
|
||||
UNSHFLW: get_func3 = 3'b101;
|
||||
BDEPW: get_func3 = 3'b110;
|
||||
BEXTW: get_func3 = 3'b110;
|
||||
PACKW: get_func3 = 3'b100;
|
||||
PACKUW: get_func3 = 3'b100;
|
||||
BFPW: get_func3 = 3'b111;
|
||||
default: get_func3 = super.get_func3();
|
||||
endcase
|
||||
;
|
||||
endfunction
|
||||
|
||||
function bit [6:0] get_func7();
|
||||
case (instr_name) inside
|
||||
ANDN: get_func7 = 7'b0100000;
|
||||
ORN: get_func7 = 7'b0100000;
|
||||
XNOR: get_func7 = 7'b0100000;
|
||||
GORC: get_func7 = 7'b0010100;
|
||||
SLO: get_func7 = 7'b0010000;
|
||||
SRO: get_func7 = 7'b0010000;
|
||||
ROL: get_func7 = 7'b0110000;
|
||||
ROR: get_func7 = 7'b0110000;
|
||||
SBCLR: get_func7 = 7'b0100100;
|
||||
SBSET: get_func7 = 7'b0010100;
|
||||
SBINV: get_func7 = 7'b0110100;
|
||||
SBEXT: get_func7 = 7'b0100100;
|
||||
GREV: get_func7 = 7'b0110100;
|
||||
CLZ: get_func7 = 7'b0110000;
|
||||
CTZ: get_func7 = 7'b0110000;
|
||||
PCNT: get_func7 = 7'b0110000;
|
||||
BMATFLIP: get_func7 = 7'b0110000;
|
||||
SEXT_B: get_func7 = 7'b0110000;
|
||||
SEXT_H: get_func7 = 7'b0110000;
|
||||
CRC32_B: get_func7 = 7'b0110000;
|
||||
CRC32_H: get_func7 = 7'b0110000;
|
||||
CRC32_W: get_func7 = 7'b0110000;
|
||||
CRC32C_B: get_func7 = 7'b0110000;
|
||||
CRC32C_H: get_func7 = 7'b0110000;
|
||||
CRC32C_W: get_func7 = 7'b0110000;
|
||||
CRC32_D: get_func7 = 7'b0110000;
|
||||
CRC32C_D: get_func7 = 7'b0110000;
|
||||
CLMUL: get_func7 = 7'b0000101;
|
||||
CLMULR: get_func7 = 7'b0000101;
|
||||
CLMULH: get_func7 = 7'b0000101;
|
||||
MIN: get_func7 = 7'b0000101;
|
||||
MAX: get_func7 = 7'b0000101;
|
||||
MINU: get_func7 = 7'b0000101;
|
||||
MAXU: get_func7 = 7'b0000101;
|
||||
SHFL: get_func7 = 7'b0000100;
|
||||
UNSHFL: get_func7 = 7'b0000100;
|
||||
BDEP: get_func7 = 7'b0100100;
|
||||
BEXT: get_func7 = 7'b0000100;
|
||||
PACK: get_func7 = 7'b0000100;
|
||||
PACKU: get_func7 = 7'b0100100;
|
||||
BMATOR: get_func7 = 7'b0000100;
|
||||
BMATXOR: get_func7 = 7'b0100100;
|
||||
PACKH: get_func7 = 7'b0000100;
|
||||
BFP: get_func7 = 7'b0100100;
|
||||
ADDWU: get_func7 = 7'b0000101;
|
||||
SUBWU: get_func7 = 7'b0100101;
|
||||
ADDU_W: get_func7 = 7'b0000100;
|
||||
SUBU_W: get_func7 = 7'b0100100;
|
||||
SLOW: get_func7 = 7'b0010000;
|
||||
SROW: get_func7 = 7'b0010000;
|
||||
ROLW: get_func7 = 7'b0110000;
|
||||
RORW: get_func7 = 7'b0110000;
|
||||
SBCLRW: get_func7 = 7'b0100100;
|
||||
SBSETW: get_func7 = 7'b0010100;
|
||||
SBINVW: get_func7 = 7'b0110100;
|
||||
SBEXTW: get_func7 = 7'b0100100;
|
||||
GORCW: get_func7 = 7'b0010100;
|
||||
GREVW: get_func7 = 7'b0110100;
|
||||
SLOIW: get_func7 = 7'b0010000;
|
||||
SROIW: get_func7 = 7'b0010000;
|
||||
RORIW: get_func7 = 7'b0110000;
|
||||
SBCLRIW: get_func7 = 7'b0100100;
|
||||
SBSETIW: get_func7 = 7'b0010100;
|
||||
SBINVIW: get_func7 = 7'b0110100;
|
||||
GORCIW: get_func7 = 7'b0010100;
|
||||
GREVIW: get_func7 = 7'b0110100;
|
||||
CLZW: get_func7 = 7'b0110000;
|
||||
CTZW: get_func7 = 7'b0110000;
|
||||
PCNTW: get_func7 = 7'b0110000;
|
||||
CLMULW: get_func7 = 7'b0000101;
|
||||
CLMULRW: get_func7 = 7'b0000101;
|
||||
CLMULHW: get_func7 = 7'b0000101;
|
||||
SHFLW: get_func7 = 7'b0000100;
|
||||
UNSHFLW: get_func7 = 7'b0000100;
|
||||
BDEPW: get_func7 = 7'b0100100;
|
||||
BEXTW: get_func7 = 7'b0000100;
|
||||
PACKW: get_func7 = 7'b0000100;
|
||||
PACKUW: get_func7 = 7'b0100100;
|
||||
BFPW: get_func7 = 7'b0100100;
|
||||
default: get_func7 = super.get_func7();
|
||||
endcase
|
||||
|
||||
endfunction
|
||||
|
||||
function bit [4:0] get_func5();
|
||||
case (instr_name) inside
|
||||
SLOI: get_func5 = 5'b00100;
|
||||
SROI: get_func5 = 5'b00100;
|
||||
RORI: get_func5 = 5'b01100;
|
||||
SBCLRI: get_func5 = 5'b01001;
|
||||
SBSETI: get_func5 = 5'b01001;
|
||||
SBINVI: get_func5 = 5'b01101;
|
||||
SBEXTI: get_func5 = 5'b01001;
|
||||
GORCI: get_func5 = 5'b00101;
|
||||
GREVI: get_func5 = 5'b01101;
|
||||
|
||||
CLZW: get_func5 = 5'b00000;
|
||||
CTZW: get_func5 = 5'b00001;
|
||||
PCNTW: get_func5 = 5'b00010;
|
||||
|
||||
CRC32_B: get_func5 = 5'b10000;
|
||||
CRC32_H: get_func5 = 5'b10001;
|
||||
CRC32_W: get_func5 = 5'b10010;
|
||||
CRC32C_B: get_func5 = 5'b11000;
|
||||
CRC32C_H: get_func5 = 5'b11001;
|
||||
CRC32C_W: get_func5 = 5'b11010;
|
||||
CRC32_D: get_func5 = 5'b10011;
|
||||
CRC32C_D: get_func5 = 5'b11011;
|
||||
|
||||
CLZ: get_func5 = 5'b00000;
|
||||
CTZ: get_func5 = 5'b00001;
|
||||
PCNT: get_func5 = 5'b00010;
|
||||
BMATFLIP: get_func5 = 5'b00011;
|
||||
SEXT_B: get_func5 = 5'b00100;
|
||||
SEXT_H: get_func5 = 5'b00101;
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function bit [1:0] get_func2();
|
||||
case (instr_name) inside
|
||||
CMIX: get_func2 = 2'b11;
|
||||
CMOV: get_func2 = 2'b11;
|
||||
FSL: get_func2 = 2'b10;
|
||||
FSR: get_func2 = 2'b10;
|
||||
FSLW: get_func2 = 2'b10;
|
||||
FSRW: get_func2 = 2'b10;
|
||||
FSRIW: get_func2 = 2'b10;
|
||||
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)
|
||||
R_FORMAT: begin
|
||||
if ((category inside {LOGICAL}) && (group == RV32B)) begin
|
||||
if (instr_name inside {SEXT_B, SEXT_H}) begin
|
||||
binary =
|
||||
$sformatf("%8h", {get_func7(), get_func5(), rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV32B)) begin
|
||||
if (instr_name inside {CRC32_B, CRC32_H, CRC32_W, CRC32C_B, CRC32C_H, CRC32C_W, CLZ, CTZ,
|
||||
PCNT}) begin
|
||||
binary =
|
||||
$sformatf("%8h", {get_func7(), get_func5(), rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV64B)) begin
|
||||
if (instr_name inside {CLZW, CTZW, PCNTW, CRC32_D, CRC32C_D, BMATFLIP}) begin
|
||||
binary =
|
||||
$sformatf("%8h", {get_func7(), get_func5(), rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
I_FORMAT: begin
|
||||
if ((category inside {SHIFT, LOGICAL}) && (group == RV32B)) begin
|
||||
binary = $sformatf("%8h", {get_func5(), imm[6:0], rs1, get_func3(), rd, get_opcode()});
|
||||
end else if ((category inside {SHIFT, LOGICAL}) && (group == RV64B)) begin
|
||||
binary = $sformatf("%8h", {get_func7(), imm[4:0], rs1, get_func3(), rd, get_opcode()});
|
||||
if (instr_name == SLLIU_W)
|
||||
binary = $sformatf("%8h", {5'b0_0001, imm[6:0], rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
|
||||
if (instr_name inside {FSRI}) begin
|
||||
binary = $sformatf("%8h", {rs3, 1'b1, imm[5:0], rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV32B)) begin
|
||||
binary = $sformatf("%8h", {6'b00_0010, imm[5:0], rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
|
||||
if ((category inside {ARITHMETIC}) && (group == RV64B)) begin
|
||||
binary = $sformatf("%8h", {imm[11:0], rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
end
|
||||
|
||||
R4_FORMAT: begin
|
||||
binary = $sformatf("%8h", {rs3, get_func2(), rs2, rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
default: begin
|
||||
if (binary == "") binary = super.convert2bin(prefix);
|
||||
end
|
||||
endcase
|
||||
return {prefix, binary};
|
||||
endfunction
|
||||
|
||||
virtual function void do_copy(uvm_object rhs);
|
||||
riscv_b_instr rhs_;
|
||||
super.copy(rhs);
|
||||
assert($cast(rhs_, rhs));
|
||||
this.rs3 = rhs_.rs3;
|
||||
this.has_rs3 = rhs_.has_rs3;
|
||||
endfunction : do_copy
|
||||
|
||||
endclass
|
||||
|
||||
|
||||
|
|
@ -217,6 +217,7 @@ class riscv_compressed_instr extends riscv_instr;
|
|||
end
|
||||
CJ_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s", asm_str, get_imm());
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
|
||||
endcase
|
||||
end else begin
|
||||
// For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
|
||||
|
|
|
@ -138,6 +138,7 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
has_fs1 = 1'b0;
|
||||
has_fd = 1'b0;
|
||||
end
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -123,7 +123,9 @@ class riscv_instr extends uvm_object;
|
|||
!(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_inst.group inside {RV32F, RV64F, RV32D, RV64D})) &&
|
||||
!(!cfg.enable_b_extension &&
|
||||
(instr_inst.group inside {RV32B, RV64B}))) 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);
|
||||
|
@ -374,6 +376,8 @@ class riscv_instr extends uvm_object;
|
|||
end else begin
|
||||
asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
end
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported format %0s [%0s]",
|
||||
format.name(), instr_name.name()))
|
||||
endcase
|
||||
end else begin
|
||||
// For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
|
||||
|
@ -580,6 +584,7 @@ class riscv_instr extends uvm_object;
|
|||
else
|
||||
binary = $sformatf("%8h", {get_func7(), rs2, rs1, get_func3(), rd, get_opcode()});
|
||||
end
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported format %0s", format.name()))
|
||||
endcase
|
||||
return {prefix, binary};
|
||||
endfunction
|
||||
|
|
|
@ -103,6 +103,7 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
VV: asm_str = $sformatf("vmv.v.v %s,%s", vd.name(), vs1.name());
|
||||
VX: asm_str = $sformatf("vmv.v.x %s,%s", vd.name(), rs1.name());
|
||||
VI: asm_str = $sformatf("vmv.v.i %s,%s", vd.name(), imm_str);
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported va_variant %0s", va_variant), UVM_LOW)
|
||||
endcase
|
||||
end else if (instr_name == VFMV) begin
|
||||
asm_str = $sformatf("vfmv.v.f %s,%s", vd.name(), fs1.name());
|
||||
|
@ -156,6 +157,7 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
end
|
||||
end
|
||||
end
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
|
||||
endcase
|
||||
if(comment != "") begin
|
||||
asm_str = {asm_str, " #",comment};
|
||||
|
|
78
vendor/google_riscv-dv/src/isa/rv32b_instr.sv
vendored
Executable file
78
vendor/google_riscv-dv/src/isa/rv32b_instr.sv
vendored
Executable file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* Copyright 2019 Mellanox Technologies Ltd
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// LOGICAL instructions
|
||||
`DEFINE_B_INSTR(SEXT_B, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(SEXT_H, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(ANDN, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(ORN , R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(XNOR, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(GORC, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(GORCI, I_FORMAT, LOGICAL, RV32B, UIMM)
|
||||
`DEFINE_B_INSTR(CMIX, R4_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(CMOV, R4_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(PACK, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(PACKU, R_FORMAT, LOGICAL, RV32B)
|
||||
`DEFINE_B_INSTR(PACKH, R_FORMAT, LOGICAL, RV32B)
|
||||
// SHIFT intructions
|
||||
`DEFINE_B_INSTR(SLO, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(SRO, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(ROL, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(ROR, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(SBCLR, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(SBSET, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(SBINV, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(SBEXT, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(GREV, R_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(GREVI, I_FORMAT, SHIFT, RV32B , UIMM)
|
||||
`DEFINE_B_INSTR(SLOI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(SROI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(RORI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(SBCLRI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(SBSETI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(SBINVI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(SBEXTI , I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
`DEFINE_B_INSTR(FSL, R4_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(FSR, R4_FORMAT, SHIFT, RV32B)
|
||||
`DEFINE_B_INSTR(FSRI, I_FORMAT, SHIFT, RV32B ,UIMM)
|
||||
// ARITHMETIC intructions
|
||||
`DEFINE_B_INSTR(CLZ, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CTZ, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(PCNT, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32_B, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32_H, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32_W, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32C_B, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32C_H, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CRC32C_W, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CLMUL, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CLMULR, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(CLMULH, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(MIN, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(MAX, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(MINU, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(MAXU, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(SHFL, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(UNSHFL, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(BDEP, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(BEXT, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(BMATOR, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(BMATXOR, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(BFP, R_FORMAT, ARITHMETIC, RV32B)
|
||||
`DEFINE_B_INSTR(SHFLI, I_FORMAT, ARITHMETIC, RV32B, UIMM)
|
||||
`DEFINE_B_INSTR(UNSHFLI, I_FORMAT, ARITHMETIC, RV32B, UIMM)
|
||||
|
66
vendor/google_riscv-dv/src/isa/rv64b_instr.sv
vendored
Executable file
66
vendor/google_riscv-dv/src/isa/rv64b_instr.sv
vendored
Executable file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* Copyright 2019 Mellanox Technologies Ltd
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// ARITHMETIC intructions
|
||||
`DEFINE_B_INSTR(BMATFLIP, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CRC32_D, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CRC32C_D, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(ADDIWU, I_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(ADDWU, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(SUBWU, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(ADDU_W, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(SUBU_W, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CLZW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CTZW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(PCNTW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CLMULW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CLMULRW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(CLMULHW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(SHFLW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(UNSHFLW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(BDEPW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(BEXTW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
`DEFINE_B_INSTR(BFPW, R_FORMAT, ARITHMETIC, RV64B)
|
||||
|
||||
// SHIFT intructions
|
||||
`DEFINE_B_INSTR(SLLIU_W, I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(SLOW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SROW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(ROLW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(RORW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SBCLRW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SBSETW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SBINVW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SBEXTW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(GREVW, R_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(SLOIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(SROIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(RORIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(SBCLRIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(SBSETIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(SBINVIW , I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(GREVIW, I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(FSLW, R4_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(FSRW, R4_FORMAT, SHIFT, RV64B)
|
||||
`DEFINE_B_INSTR(FSRIW, I_FORMAT, SHIFT, RV64B, UIMM)
|
||||
|
||||
// LOGICAL instructions
|
||||
`DEFINE_B_INSTR(GORCW, R_FORMAT, LOGICAL, RV64B)
|
||||
`DEFINE_B_INSTR(GORCIW, I_FORMAT, LOGICAL, RV64B, UIMM)
|
||||
`DEFINE_B_INSTR(PACKW, R_FORMAT, LOGICAL, RV64B)
|
||||
`DEFINE_B_INSTR(PACKUW, R_FORMAT, LOGICAL, RV64B)
|
||||
|
|
@ -19,60 +19,72 @@ 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;
|
||||
rand int offset[];
|
||||
rand riscv_reg_t rs1_reg[];
|
||||
rand int num_of_rs1_reg;
|
||||
int unsigned data_page_id;
|
||||
int unsigned max_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 num_of_rs1_reg_c {
|
||||
num_of_rs1_reg == 1;
|
||||
}
|
||||
|
||||
constraint rs1_c {
|
||||
!(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
|
||||
solve num_of_rs1_reg before rs1_reg;
|
||||
rs1_reg.size() == num_of_rs1_reg;
|
||||
offset.size() == num_of_rs1_reg;
|
||||
foreach (rs1_reg[i]) {
|
||||
!(rs1_reg[i] inside {cfg.reserved_regs, reserved_rd, ZERO});
|
||||
}
|
||||
unique {rs1_reg};
|
||||
}
|
||||
|
||||
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;
|
||||
foreach (offset[i]) {
|
||||
offset[i] inside {[0 : max_offset - 1]};
|
||||
}
|
||||
}
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
endfunction
|
||||
constraint aligned_amo_c {
|
||||
foreach (offset[i]) {
|
||||
if (XLEN == 32) {
|
||||
offset[i] % 4 == 0;
|
||||
} else {
|
||||
offset[i] % 8 == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_amo_base_instr_stream)
|
||||
`uvm_object_new
|
||||
|
||||
function void pre_randomize();
|
||||
data_page = cfg.amo_region;
|
||||
max_data_page_id = data_page.size();
|
||||
data_page_id = $urandom_range(0, max_data_page_id - 1);
|
||||
max_offset = data_page[data_page_id].size_in_bytes;
|
||||
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;
|
||||
la_instr.imm_str = $sformatf("%0s+%0d", cfg.amo_region[id].name, base);
|
||||
instr_list.push_front(la_instr);
|
||||
// Use "la" instruction to initialize the offset regiseter
|
||||
virtual function void init_offset_reg();
|
||||
foreach (rs1_reg[i]) begin
|
||||
riscv_pseudo_instr la_instr;
|
||||
la_instr = riscv_pseudo_instr::type_id::create("la_instr");
|
||||
la_instr.pseudo_instr_name = LA;
|
||||
la_instr.rd = rs1_reg[i];
|
||||
la_instr.imm_str = $sformatf("%0s+%0d", cfg.amo_region[data_page_id].name, offset[i]);
|
||||
instr_list.push_front(la_instr);
|
||||
end
|
||||
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
|
||||
reserved_rd = {reserved_rd, rs1_reg};
|
||||
add_mixed_instr(num_mixed_instr);
|
||||
add_rs1_init_la_instr(rs1_reg, data_page_id);
|
||||
init_offset_reg();
|
||||
super.post_randomize();
|
||||
endfunction
|
||||
|
||||
|
@ -113,24 +125,24 @@ class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
|
|||
lr_instr = riscv_instr::get_rand_instr(.include_instr({allowed_lr_instr}));
|
||||
sc_instr = riscv_instr::get_rand_instr(.include_instr({allowed_sc_instr}));
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(lr_instr,
|
||||
rs1 == rs1_reg;
|
||||
rs1 == rs1_reg[0];
|
||||
if (reserved_rd.size() > 0) {
|
||||
!(rd inside {reserved_rd});
|
||||
}
|
||||
if (cfg.reserved_regs.size() > 0) {
|
||||
!(rd inside {cfg.reserved_regs});
|
||||
}
|
||||
rd != rs1_reg;
|
||||
rd != rs1_reg[0];
|
||||
)
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(sc_instr,
|
||||
rs1 == rs1_reg;
|
||||
rs1 == rs1_reg[0];
|
||||
if (reserved_rd.size() > 0) {
|
||||
!(rd inside {reserved_rd});
|
||||
}
|
||||
if (cfg.reserved_regs.size() > 0) {
|
||||
!(rd inside {cfg.reserved_regs});
|
||||
}
|
||||
rd != rs1_reg;
|
||||
rd != rs1_reg[0];
|
||||
)
|
||||
instr_list.push_back(lr_instr);
|
||||
instr_list.push_back(sc_instr);
|
||||
|
@ -144,8 +156,14 @@ class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
|
|||
|
||||
constraint reasonable_c {
|
||||
solve num_amo before num_mixed_instr;
|
||||
num_amo inside {[1:10]};
|
||||
num_mixed_instr inside {[0:2*num_amo]};
|
||||
num_amo inside {[1 : 10]};
|
||||
num_mixed_instr inside {[0 : num_amo]};
|
||||
}
|
||||
|
||||
constraint num_of_rs1_reg_c {
|
||||
solve num_amo before num_of_rs1_reg;
|
||||
num_of_rs1_reg inside {[1 : num_amo]};
|
||||
num_of_rs1_reg < 5;
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_amo_instr_stream)
|
||||
|
@ -162,8 +180,8 @@ class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
|
|||
if (cfg.reserved_regs.size() > 0) {
|
||||
!(rd inside {cfg.reserved_regs});
|
||||
}
|
||||
rs1 == rs1_reg;
|
||||
rd != rs1_reg;
|
||||
rs1 inside {rs1_reg};
|
||||
!(rd inside {rs1_reg});
|
||||
)
|
||||
instr_list.push_front(amo_instr[i]);
|
||||
end
|
||||
|
|
|
@ -106,7 +106,8 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
`DV_CHECK_RANDOMIZE_FATAL(main_program[hart])
|
||||
main_program[hart].gen_instr(.is_main_program(1), .no_branch(cfg.no_branch_jump));
|
||||
// Setup jump instruction among main program and sub programs
|
||||
gen_callstack(main_program[hart], sub_program[hart], sub_program_name, cfg.num_of_sub_program);
|
||||
gen_callstack(main_program[hart], sub_program[hart], sub_program_name,
|
||||
cfg.num_of_sub_program);
|
||||
`uvm_info(`gfn, "Generating callstack...done", UVM_LOW)
|
||||
main_program[hart].post_process_instr();
|
||||
`uvm_info(`gfn, "Post-processing main program...done", UVM_LOW)
|
||||
|
@ -128,8 +129,10 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// Program end
|
||||
gen_program_end(hart);
|
||||
if (!cfg.bare_program_mode) begin
|
||||
// Privileged mode switch routine
|
||||
gen_privileged_mode_switch_routine(hart);
|
||||
if (!riscv_instr_pkg::support_pmp) begin
|
||||
// Privileged mode switch routine
|
||||
gen_privileged_mode_switch_routine(hart);
|
||||
end
|
||||
// Generate debug rom section
|
||||
if (riscv_instr_pkg::support_debug_mode) begin
|
||||
gen_debug_rom(hart);
|
||||
|
@ -165,7 +168,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// Generate kernel program/data/stack sections
|
||||
//---------------------------------------------------------------------------------------
|
||||
virtual function void gen_kernel_sections(int hart);
|
||||
instr_stream.push_back(get_label("kernel_instr_start: .align 12", hart));
|
||||
if (SATP_MODE != BARE) begin
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
instr_stream.push_back(get_label("kernel_instr_start:", hart));
|
||||
instr_stream.push_back(".text");
|
||||
// Kernel programs
|
||||
if (cfg.virtual_addr_translation_on) begin
|
||||
|
@ -189,8 +197,13 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// User stack and data pages may not be accessible when executing trap handling programs in
|
||||
// machine/supervisor mode. Generate separate kernel data/stack sections to solve it.
|
||||
if (cfg.virtual_addr_translation_on) begin
|
||||
if (SATP_MODE != BARE) begin
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
// Kernel data pages
|
||||
instr_stream.push_back(get_label("kernel_data_start: .align 12", hart));
|
||||
instr_stream.push_back(get_label("kernel_data_start:", hart));
|
||||
if(!cfg.no_data_page) begin
|
||||
// Data section
|
||||
gen_data_page(hart, 1'b1);
|
||||
|
@ -347,8 +360,15 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
if (cfg.use_push_data_section) begin
|
||||
instr_stream.push_back($sformatf(".pushsection .%0suser_stack,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end else begin
|
||||
instr_stream.push_back($sformatf(".section .%0suser_stack,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end
|
||||
if (SATP_MODE != BARE) begin
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
instr_stream.push_back(".align 12");
|
||||
instr_stream.push_back(get_label("user_stack_start:", hart));
|
||||
instr_stream.push_back($sformatf(".rept %0d", cfg.stack_len - 1));
|
||||
instr_stream.push_back($sformatf(".%0dbyte 0x0", XLEN/8));
|
||||
|
@ -365,8 +385,15 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
if (cfg.use_push_data_section) begin
|
||||
instr_stream.push_back($sformatf(".pushsection .%0skernel_stack,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end else begin
|
||||
instr_stream.push_back($sformatf(".section .%0skernel_stack,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end
|
||||
if (SATP_MODE != BARE) begin
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
instr_stream.push_back(".align 12");
|
||||
instr_stream.push_back(get_label("kernel_stack_start:", hart));
|
||||
instr_stream.push_back($sformatf(".rept %0d", cfg.kernel_stack_len - 1));
|
||||
instr_stream.push_back($sformatf(".%0dbyte 0x0", XLEN/8));
|
||||
|
@ -414,6 +441,7 @@ 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;
|
||||
RV32B, RV64B : misa[MISA_EXT_B] = 1'b1;
|
||||
RV32F, RV64F, RV32FC : misa[MISA_EXT_F] = 1'b1;
|
||||
RV32D, RV64D, RV32DC : misa[MISA_EXT_D] = 1'b1;
|
||||
RV32V, RV64V : misa[MISA_EXT_V] = 1'b1;
|
||||
|
@ -591,6 +619,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
end
|
||||
// Setup mepc register, jump to init entry
|
||||
setup_epc(hart);
|
||||
// Move privileged mode support to the "safe" section of the program
|
||||
// if PMP is supported
|
||||
if (riscv_instr_pkg::support_pmp) begin
|
||||
// Privileged mode switch routine
|
||||
gen_privileged_mode_switch_routine(hart);
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function void gen_privileged_mode_switch_routine(int hart);
|
||||
|
@ -623,6 +657,8 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
.csr(USTATUS));
|
||||
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(UIE));
|
||||
end
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported privileged_mode %0s",
|
||||
riscv_instr_pkg::supported_privileged_mode[i]), UVM_LOW)
|
||||
endcase
|
||||
// Write M-mode CSRs to testbench by default, as these should be implemented
|
||||
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(MSTATUS));
|
||||
|
@ -636,7 +672,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
|
||||
// Setup EPC before entering target privileged mode
|
||||
virtual function void setup_epc(int hart);
|
||||
string instr[];
|
||||
string instr[$];
|
||||
string mode_name;
|
||||
instr = {$sformatf("la x%0d, %0sinit", cfg.gpr[0], hart_prefix(hart))};
|
||||
if(cfg.virtual_addr_translation_on) begin
|
||||
|
@ -648,10 +684,10 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
$sformatf("srli x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN - 12)};
|
||||
end
|
||||
mode_name = cfg.init_privileged_mode.name();
|
||||
instr = {instr,
|
||||
$sformatf("csrw mepc, x%0d", cfg.gpr[0]),
|
||||
$sformatf("j %0sinit_%0s", hart_prefix(hart), mode_name.tolower())
|
||||
};
|
||||
instr.push_back($sformatf("csrw mepc, x%0d", cfg.gpr[0]));
|
||||
if (!riscv_instr_pkg::support_pmp) begin
|
||||
instr.push_back($sformatf("j %0sinit_%0s", hart_prefix(hart), mode_name.tolower()));
|
||||
end
|
||||
gen_section(get_label("mepc_setup", hart), instr);
|
||||
endfunction
|
||||
|
||||
|
@ -723,6 +759,8 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
MACHINE_MODE: trap_vec_reg = MTVEC;
|
||||
SUPERVISOR_MODE: trap_vec_reg = STVEC;
|
||||
USER_MODE: trap_vec_reg = UTVEC;
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported privileged_mode %0s",
|
||||
riscv_instr_pkg::supported_privileged_mode[i]), UVM_LOW)
|
||||
endcase
|
||||
// Skip utvec init if trap delegation to u_mode is not supported
|
||||
if ((riscv_instr_pkg::supported_privileged_mode[i] == USER_MODE) &&
|
||||
|
@ -796,6 +834,8 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
gen_trap_handler_section(hart, "u", UCAUSE, UTVEC, UTVAL,
|
||||
UEPC, USCRATCH, USTATUS, UIE, UIP);
|
||||
end
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported privileged_mode %0s",
|
||||
riscv_instr_pkg::supported_privileged_mode[i]))
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
@ -834,7 +874,11 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
end
|
||||
// The trap handler will occupy one 4KB page, it will be allocated one entry in the page table
|
||||
// with a specific privileged mode.
|
||||
instr_stream.push_back(".align 12");
|
||||
if (SATP_MODE != BARE) begin
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
tvec_name = tvec.name();
|
||||
gen_section(get_label($sformatf("%0s_handler", tvec_name.tolower()), hart), instr);
|
||||
// Exception handler
|
||||
|
@ -1059,6 +1103,9 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
if (cfg.use_push_data_section) begin
|
||||
instr_stream.push_back($sformatf(".pushsection .%0spage_table,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end else begin
|
||||
instr_stream.push_back($sformatf(".section .%0spage_table,\"aw\",@progbits;",
|
||||
hart_prefix(hart)));
|
||||
end
|
||||
foreach(page_table_list.page_table[i]) begin
|
||||
page_table_list.page_table[i].gen_page_table_section(page_table_section);
|
||||
|
@ -1129,6 +1176,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
USTATUS: begin
|
||||
interrupt_handler_instr.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 1));
|
||||
end
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported status %0s", status))
|
||||
endcase
|
||||
interrupt_handler_instr.push_back($sformatf("1: csrwi 0x%0x,0", scratch));
|
||||
end
|
||||
|
@ -1150,8 +1198,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
interrupt_handler_instr = {interrupt_handler_instr,
|
||||
$sformatf("%0sret;", mode_prefix)
|
||||
};
|
||||
// The interrupt handler will use one 4KB page
|
||||
instr_stream.push_back(".align 12");
|
||||
if (SATP_MODE != BARE) begin
|
||||
// The interrupt handler will use one 4KB page
|
||||
instr_stream.push_back(".align 12");
|
||||
end else begin
|
||||
instr_stream.push_back(".align 2");
|
||||
end
|
||||
gen_section(get_label($sformatf("%0smode_intr_handler", mode_prefix), hart),
|
||||
interrupt_handler_instr);
|
||||
endfunction
|
||||
|
|
|
@ -75,12 +75,18 @@ class riscv_data_page_gen extends uvm_object;
|
|||
if (cfg.use_push_data_section) begin
|
||||
data_page_str.push_back($sformatf(".pushsection .%0s,\"aw\",@progbits;",
|
||||
mem_region_setting[i].name));
|
||||
end else begin
|
||||
data_page_str.push_back($sformatf(".section .%0s,\"aw\",@progbits;",
|
||||
mem_region_setting[i].name));
|
||||
end
|
||||
data_page_str.push_back($sformatf("%0s:", mem_region_setting[i].name));
|
||||
end else begin
|
||||
if (cfg.use_push_data_section) begin
|
||||
data_page_str.push_back($sformatf(".pushsection .%0s,\"aw\",@progbits;",
|
||||
{hart_prefix(hart_id), mem_region_setting[i].name}));
|
||||
end else begin
|
||||
data_page_str.push_back($sformatf(".section .%0s,\"aw\",@progbits;",
|
||||
{hart_prefix(hart_id), mem_region_setting[i].name}));
|
||||
end
|
||||
data_page_str.push_back($sformatf("%0s:",
|
||||
{hart_prefix(hart_id), mem_region_setting[i].name}));
|
||||
|
|
6
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
6
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
|
@ -98,3 +98,9 @@
|
|||
`define DEFINE_CUSTOM_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM) \
|
||||
class riscv_``instr_n``_instr extends riscv_custom_instr; \
|
||||
`INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
|
||||
|
||||
//B-extension instruction
|
||||
`define DEFINE_B_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM) \
|
||||
class riscv_``instr_n``_instr extends riscv_b_instr; \
|
||||
`INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
|
||||
|
||||
|
|
|
@ -165,6 +165,14 @@ class riscv_illegal_instr extends uvm_object;
|
|||
c_op != 2'b11;
|
||||
}
|
||||
|
||||
// Avoid generating illegal func3/func7 errors for opcode used by B-extension
|
||||
constraint b_extension_c {
|
||||
if (RV32B inside {supported_isa}) {
|
||||
if (exception inside {kIllegalFunc3, kIllegalFunc7}) {
|
||||
!(opcode inside {7'b0011011, 7'b0010011, 7'b0111011});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constraint illegal_compressed_op_c {
|
||||
if (exception == kIllegalCompressedOpcode) {
|
||||
|
|
|
@ -197,7 +197,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
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 [XLEN - 1 : 0] 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.
|
||||
|
@ -232,6 +232,8 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
bit enable_floating_point;
|
||||
// Vector extension support
|
||||
bit enable_vector_extension;
|
||||
// Bit manipulation extension support
|
||||
bit enable_b_extension;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command line options for instruction distribution control
|
||||
|
@ -396,7 +398,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
constraint addr_translaction_rnd_order_c {
|
||||
solve init_privileged_mode before virtual_addr_translation_on;
|
||||
}
|
||||
|
||||
|
||||
constraint addr_translaction_c {
|
||||
if ((init_privileged_mode != MACHINE_MODE) && (SATP_MODE != BARE)) {
|
||||
virtual_addr_translation_on == 1'b1;
|
||||
|
@ -474,6 +476,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
`uvm_field_int(max_directed_instr_stream_seq, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_floating_point, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_vector_extension, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_b_extension, UVM_DEFAULT)
|
||||
`uvm_field_int(use_push_data_section, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
|
@ -527,6 +530,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
get_bool_arg_value("+set_mstatus_tw=", set_mstatus_tw);
|
||||
get_bool_arg_value("+enable_floating_point=", enable_floating_point);
|
||||
get_bool_arg_value("+enable_vector_extension=", enable_vector_extension);
|
||||
get_bool_arg_value("+enable_b_extension=", enable_b_extension);
|
||||
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)
|
||||
|
@ -566,6 +570,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
vector_cfg = riscv_vector_cfg::type_id::create("vector_cfg");
|
||||
pmp_cfg = riscv_pmp_cfg::type_id::create("pmp_cfg");
|
||||
pmp_cfg.rand_mode(pmp_cfg.pmp_randomize);
|
||||
pmp_cfg.initialize(require_signature_addr);
|
||||
setup_instr_distribution();
|
||||
get_invalid_priv_lvl_csr();
|
||||
endfunction
|
||||
|
@ -642,7 +647,8 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
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
|
||||
if (riscv_instr_pkg::supported_isa[i] inside {RV64I, RV64M, RV64A, RV64F, RV64D, RV64C,
|
||||
RV64B}) begin
|
||||
support_64b = 1'b1;
|
||||
end else if (riscv_instr_pkg::supported_isa[i] inside {RV128I, RV128C}) begin
|
||||
support_128b = 1'b1;
|
||||
|
|
108
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
108
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
|
@ -147,6 +147,108 @@ package riscv_instr_pkg;
|
|||
CSRRWI,
|
||||
CSRRSI,
|
||||
CSRRCI,
|
||||
// RV32B instructions
|
||||
ANDN,
|
||||
ORN,
|
||||
XNOR,
|
||||
GORC,
|
||||
SLO,
|
||||
SRO,
|
||||
ROL,
|
||||
ROR,
|
||||
SBCLR,
|
||||
SBSET,
|
||||
SBINV,
|
||||
SBEXT,
|
||||
GREV,
|
||||
SLOI,
|
||||
SROI,
|
||||
RORI,
|
||||
SBCLRI,
|
||||
SBSETI,
|
||||
SBINVI,
|
||||
SBEXTI,
|
||||
GORCI,
|
||||
GREVI,
|
||||
CMIX,
|
||||
CMOV,
|
||||
FSL,
|
||||
FSR,
|
||||
FSRI,
|
||||
CLZ,
|
||||
CTZ,
|
||||
PCNT,
|
||||
SEXT_B,
|
||||
SEXT_H,
|
||||
CRC32_B,
|
||||
CRC32_H,
|
||||
CRC32_W,
|
||||
CRC32C_B,
|
||||
CRC32C_H,
|
||||
CRC32C_W,
|
||||
CLMUL,
|
||||
CLMULR,
|
||||
CLMULH,
|
||||
MIN,
|
||||
MAX,
|
||||
MINU,
|
||||
MAXU,
|
||||
SHFL,
|
||||
UNSHFL,
|
||||
BDEP,
|
||||
BEXT,
|
||||
PACK,
|
||||
PACKU,
|
||||
BMATOR,
|
||||
BMATXOR,
|
||||
PACKH,
|
||||
BFP,
|
||||
SHFLI,
|
||||
UNSHFLI,
|
||||
//RV64B instructions
|
||||
ADDIWU,
|
||||
SLLIU_W,
|
||||
ADDWU,
|
||||
SUBWU,
|
||||
BMATFLIP,
|
||||
CRC32_D,
|
||||
CRC32C_D,
|
||||
ADDU_W,
|
||||
SUBU_W,
|
||||
SLOW,
|
||||
SROW,
|
||||
ROLW,
|
||||
RORW,
|
||||
SBCLRW,
|
||||
SBSETW,
|
||||
SBINVW,
|
||||
SBEXTW,
|
||||
GORCW,
|
||||
GREVW,
|
||||
SLOIW,
|
||||
SROIW,
|
||||
RORIW,
|
||||
SBCLRIW,
|
||||
SBSETIW,
|
||||
SBINVIW,
|
||||
GORCIW,
|
||||
GREVIW,
|
||||
FSLW,
|
||||
FSRW,
|
||||
FSRIW,
|
||||
CLZW,
|
||||
CTZW,
|
||||
PCNTW,
|
||||
CLMULW,
|
||||
CLMULRW,
|
||||
CLMULHW,
|
||||
SHFLW,
|
||||
UNSHFLW,
|
||||
BDEPW,
|
||||
BEXTW,
|
||||
PACKW,
|
||||
PACKUW,
|
||||
BFPW,
|
||||
// RV32M instructions
|
||||
MUL,
|
||||
MULH,
|
||||
|
@ -1124,7 +1226,8 @@ package riscv_instr_pkg;
|
|||
endfunction
|
||||
|
||||
// Get a hex argument from command line
|
||||
function automatic void get_hex_arg_value(string cmdline_str, ref int val);
|
||||
function automatic void get_hex_arg_value(string cmdline_str,
|
||||
ref bit [XLEN - 1 : 0] val);
|
||||
string s;
|
||||
if(inst.get_arg_value(cmdline_str, s)) begin
|
||||
val = s.atohex();
|
||||
|
@ -1148,6 +1251,7 @@ package riscv_instr_pkg;
|
|||
`include "riscv_instr_gen_config.sv"
|
||||
`include "isa/riscv_instr.sv"
|
||||
`include "isa/riscv_amo_instr.sv"
|
||||
`include "isa/riscv_b_instr.sv"
|
||||
`include "isa/riscv_floating_point_instr.sv"
|
||||
`include "isa/riscv_vector_instr.sv"
|
||||
`include "isa/riscv_compressed_instr.sv"
|
||||
|
@ -1158,8 +1262,10 @@ package riscv_instr_pkg;
|
|||
`include "isa/rv32fc_instr.sv"
|
||||
`include "isa/rv32f_instr.sv"
|
||||
`include "isa/rv32i_instr.sv"
|
||||
`include "isa/rv32b_instr.sv"
|
||||
`include "isa/rv32m_instr.sv"
|
||||
`include "isa/rv64a_instr.sv"
|
||||
`include "isa/rv64b_instr.sv"
|
||||
`include "isa/rv64c_instr.sv"
|
||||
`include "isa/rv64d_instr.sv"
|
||||
`include "isa/rv64f_instr.sv"
|
||||
|
|
|
@ -305,6 +305,7 @@ class riscv_instr_sequence extends uvm_sequence;
|
|||
C_JALR : str = {prefix, $sformatf("c.jalr x%0d", ra)};
|
||||
C_JR : str = {prefix, $sformatf("c.jr x%0d", ra)};
|
||||
JALR : str = {prefix, $sformatf("jalr x%0d, x%0d, 0", ra, ra)};
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported jump_instr %0s", jump_instr[i]))
|
||||
endcase
|
||||
instr_string_list.push_back(str);
|
||||
endfunction
|
||||
|
|
|
@ -146,6 +146,7 @@ class riscv_page_table_entry#(satp_mode_t MODE = SV39) extends uvm_object;
|
|||
1 : return PPN0_WIDTH;
|
||||
2 : return PPN0_WIDTH + PPN1_WIDTH;
|
||||
3 : return PPN0_WIDTH + PPN1_WIDTH + PPN2_WIDTH;
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported page_level %0x", page_level))
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
|
33
vendor/google_riscv-dv/src/riscv_pmp_cfg.sv
vendored
33
vendor/google_riscv-dv/src/riscv_pmp_cfg.sv
vendored
|
@ -25,8 +25,11 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
// pmp CSR configurations
|
||||
rand pmp_cfg_reg_t pmp_cfg[];
|
||||
// PMP maximum address - used to set defaults
|
||||
// TODO(udinator) - make this address configurable?
|
||||
bit [XLEN - 1 : 0] pmp_max_address = {XLEN{1'b1}};
|
||||
// PMP "minimum" address - the address written to pmpaddr0
|
||||
// to create a "safe region", which contains important setup code,
|
||||
// and cannot throw a PMP fault
|
||||
bit [XLEN - 1 : 0] pmp_min_address = 0;
|
||||
|
||||
// used to parse addr_mode configuration from cmdline
|
||||
typedef uvm_enum_wrapper#(pmp_addr_mode_t) addr_mode_wrapper;
|
||||
|
@ -64,6 +67,7 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
get_bool_arg_value("+pmp_randomize=", pmp_randomize);
|
||||
get_int_arg_value("+pmp_granularity=", pmp_granularity);
|
||||
get_int_arg_value("+pmp_num_regions=", pmp_num_regions);
|
||||
get_hex_arg_value("+pmp_max_address=", pmp_max_address);
|
||||
pmp_cfg = new[pmp_num_regions];
|
||||
// As per privileged spec, the top 10 bits of a rv64 PMP address are all 0.
|
||||
if (XLEN == 64) begin
|
||||
|
@ -75,6 +79,21 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
end
|
||||
endfunction
|
||||
|
||||
function void initialize(bit require_signature_addr);
|
||||
// We want to set the "minimum" pmp address to just after the location of the <main>
|
||||
// section of the program to allow all initialization routines to not be interrupted
|
||||
// by PMP faults.
|
||||
// The location of <main> itself will change depending on whether the handshaking
|
||||
// mechanism is enabled or disabled, so we check if it is enabled and then
|
||||
// round up the address of <main>.
|
||||
pmp_min_address = (require_signature_addr) ? 'h80002910 : 'h80001580;
|
||||
|
||||
if (!pmp_randomize) begin
|
||||
set_defaults();
|
||||
setup_pmp();
|
||||
end
|
||||
endfunction
|
||||
|
||||
// This will only get called if pmp_randomize is set, in which case we apply command line
|
||||
// arguments after randomization
|
||||
function void post_randomize();
|
||||
|
@ -88,13 +107,16 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
pmp_cfg[i].x = 1'b1;
|
||||
pmp_cfg[i].w = 1'b1;
|
||||
pmp_cfg[i].r = 1'b1;
|
||||
pmp_cfg[i].addr = assign_default_addr(pmp_num_regions, i + 1);
|
||||
pmp_cfg[i].addr = (i == 0) ? pmp_min_address : assign_default_addr(pmp_num_regions, i);
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Helper function to break down
|
||||
function bit [XLEN - 1 : 0] assign_default_addr(int num_regions, int index);
|
||||
return pmp_max_address / num_regions * index;
|
||||
bit [XLEN - 1 : 0] total_addr_space, offset;
|
||||
total_addr_space = pmp_max_address - pmp_min_address;
|
||||
offset = total_addr_space / (num_regions - 1) * index;
|
||||
return pmp_min_address + offset;
|
||||
endfunction
|
||||
|
||||
function void setup_pmp();
|
||||
|
@ -163,6 +185,7 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
64: begin
|
||||
return {10'b0, shifted_addr[XLEN - 11 : 0]};
|
||||
end
|
||||
default: `uvm_fatal(`gfn, $sformatf("Unsupported XLEN %0s", XLEN))
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
@ -177,7 +200,7 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
// CSR, this function waits until it has reached this maximum to write to the physical CSR to
|
||||
// save some extraneous instructions from being performed.
|
||||
function void gen_pmp_instr(ref string instr[$], riscv_reg_t scratch_reg);
|
||||
int cfg_per_csr = XLEN / 4;
|
||||
int cfg_per_csr = XLEN / 8;
|
||||
bit [XLEN - 1 : 0] pmp_word;
|
||||
bit [XLEN - 1 : 0] cfg_bitmask;
|
||||
bit [7 : 0] cfg_byte;
|
||||
|
@ -195,7 +218,7 @@ class riscv_pmp_cfg extends uvm_object;
|
|||
pmp_word = pmp_word | cfg_bitmask;
|
||||
`uvm_info(`gfn, $sformatf("pmp_word: 0x%0x", pmp_word), UVM_DEBUG)
|
||||
cfg_bitmask = 0;
|
||||
`uvm_info(`gfn, $sformatf("pmp_addr: 0x%0x", pmp_cfg[i].addr), UVM_DEBUG)
|
||||
`uvm_info(`gfn, $sformatf("pmp_addr_%d: 0x%0x", i, pmp_cfg[i].addr), UVM_DEBUG)
|
||||
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg, pmp_cfg[i].addr));
|
||||
instr.push_back($sformatf("csrw 0x%0x, x%0d", base_pmp_addr + i, scratch_reg));
|
||||
// short circuit if end of list
|
||||
|
|
|
@ -72,10 +72,10 @@
|
|||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_lr_sc_instr_stream,10
|
||||
+directed_instr_1=riscv_amo_instr_stream,10
|
||||
+instr_cnt=2000
|
||||
+num_of_sub_program=2
|
||||
+directed_instr_0=riscv_lr_sc_instr_stream,50
|
||||
+directed_instr_1=riscv_amo_instr_stream,50
|
||||
rtl_test: core_base_test
|
||||
|
||||
|
||||
|
|
22
vendor/google_riscv-dv/target/rv32imcb/riscvOVPsim.ic
vendored
Normal file
22
vendor/google_riscv-dv/target/rv32imcb/riscvOVPsim.ic
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
# riscOVPsim configuration file converted from YAML
|
||||
--variant RV32I
|
||||
--override iscvOVPsim/cpu/add_Extensions=MCB
|
||||
--override riscvOVPsim/cpu/misa_MXL=1
|
||||
--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
|
||||
--override riscvOVPsim/cpu/defaultsemihost=F
|
||||
--override riscvOVPsim/cpu/wfi_is_nop=T
|
||||
--exitonsymbol _exit
|
118
vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv
vendored
Normal file
118
vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor feature configuration
|
||||
//-----------------------------------------------------------------------------
|
||||
// XLEN
|
||||
parameter int XLEN = 32;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = BARE;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[];
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C, RV32B};
|
||||
|
||||
// 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;
|
||||
|
||||
// Physical memory protection support
|
||||
bit support_pmp = 0;
|
||||
|
||||
// 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 = 0;
|
||||
|
||||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Implemented previlieged CSR list
|
||||
`ifdef DSIM
|
||||
privileged_reg_t implemented_csr[] = {
|
||||
`else
|
||||
parameter privileged_reg_t implemented_csr[] = {
|
||||
`endif
|
||||
// Machine mode mode CSR
|
||||
MVENDORID, // Vendor ID
|
||||
MARCHID, // Architecture ID
|
||||
MIMPID, // Implementation ID
|
||||
MHARTID, // Hardware thread ID
|
||||
MSTATUS, // Machine status
|
||||
MISA, // ISA and extensions
|
||||
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
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supported interrupt/exception setting, used for functional coverage
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
`ifdef DSIM
|
||||
interrupt_cause_t implemented_interrupt[] = {
|
||||
`else
|
||||
parameter interrupt_cause_t implemented_interrupt[] = {
|
||||
`endif
|
||||
M_SOFTWARE_INTR,
|
||||
M_TIMER_INTR,
|
||||
M_EXTERNAL_INTR
|
||||
};
|
||||
|
||||
`ifdef DSIM
|
||||
exception_cause_t implemented_exception[] = {
|
||||
`else
|
||||
parameter exception_cause_t implemented_exception[] = {
|
||||
`endif
|
||||
INSTRUCTION_ACCESS_FAULT,
|
||||
ILLEGAL_INSTRUCTION,
|
||||
BREAKPOINT,
|
||||
LOAD_ADDRESS_MISALIGNED,
|
||||
LOAD_ACCESS_FAULT,
|
||||
ECALL_MMODE
|
||||
};
|
66
vendor/google_riscv-dv/target/rv32imcb/testlist.yaml
vendored
Normal file
66
vendor/google_riscv-dv/target/rv32imcb/testlist.yaml
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
# 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
|
||||
# asm_tests : Path to directed, hand-coded assembly test file or directory
|
||||
# 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: <riscv_dv_root>/yaml/base_testlist.yaml
|
||||
|
||||
|
||||
- test: riscv_non_compressed_instr_test
|
||||
description: >
|
||||
Random instruction test without compressed instructions
|
||||
iterations: 1
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+disable_compressed_instr=1
|
||||
rtl_test: core_base_test
|
||||
|
||||
|
||||
- test: riscv_hint_instr_test
|
||||
description: >
|
||||
HINT instruction test, verify the processor can detect HINT instruction
|
||||
treat it as NOP. No illegal instruction exception is expected
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+hint_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_pmp_test
|
||||
description: >
|
||||
Provide some PMP configuration parameters, and setup PMP CSRs appropriately
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+pmp_randomize=0
|
||||
+pmp_num_regions=1
|
||||
+pmp_granularity=1
|
||||
+pmp_region_0=L:0,A:NAPOT,X:1,W:1,R:1,ADDR:FFFFFFFF
|
||||
rtl_test: core_base_test
|
|
@ -14,7 +14,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
VERIBLE_VERSION=03c7102ab8ed63037159f479ce17b3487401f082
|
||||
VERIBLE_VERSION=751d4d8e57741ab22806f91982f59c71ecf37d9d
|
||||
INSTALL_DIR=/tools/verible
|
||||
|
||||
# this requires the bazel build system and GCC7
|
||||
|
|
|
@ -5,6 +5,3 @@ riscv_instr_cover_group.sv
|
|||
riscv_instr_pkg.sv
|
||||
# tool does not support included file very well. Issue at github.com/google/verible/issues/178
|
||||
riscv_custom_instr_enum.sv
|
||||
# tool bug. Issue at github.com/google/verible/issues/172
|
||||
riscv_instr_stream.sv
|
||||
riscv_reg.sv
|
||||
|
|
2
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
2
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
|
@ -29,7 +29,7 @@
|
|||
cmd: >
|
||||
<out>/vcs_simv +vcs+lic+wait <sim_opts> +ntb_random_seed=<seed> <cov_opts>
|
||||
cov_opts: >
|
||||
-cm_dir <out>/test.vdb -cm_log /dev/null -cm_name test_<seed>
|
||||
-cm_dir <out>/test.vdb -cm_log /dev/null -cm_name test_<seed>_<test_id>
|
||||
|
||||
- tool: ius
|
||||
compile:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue