mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Update google_riscv-dv to google/riscv-dv@2e52518
Update code from upstream repository https://github.com/google/riscv- dv to revision 2e5251846efb5fa42882a2b6b571ef8693e8cd60 * Remove f strings for Python 3.5-compatibility (Philipp Wagner) * Fix start-end pair mismatch in asm file (aneels3) * Fix AMO instruction constraint issue (google/riscv-dv#682) (taoliug) * - Adds support for the coverage report visualization (pyucis-viewer) - Adds CSR, opcode, rv32i_misc, and mepc_alignment covergroups (Hodjat Asghari Esfeden) * fix Todo of directed_lib (aneels3) * Added avail_regs_c constraint (ShraddhaDevaiya) * Fix factory method implementation (aneels3) * Add directed instr (aneels3) * fix label issue (aneels3) * fix randomization issue (aneels3) * Fix typo (aneels3) * add riscv_pseudo_instr (aneels3) * add value_plusargs functionality (pvipsyash) * add riscv_utils and fix minor issues (aneels3) * modify for directed scenario (pvipsyash) * Fix a minor issue with the instruction PC (Hodjat Asghari Esfeden) Signed-off-by: Philipp Wagner <phw@lowrisc.org>
This commit is contained in:
parent
4c3f1e8a3b
commit
f53ee9b09f
17 changed files with 442 additions and 112 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: 17d79847e376a591cb3dcaae7601c98b0e70e8ac
|
||||
rev: 2e5251846efb5fa42882a2b6b571ef8693e8cd60
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ class riscv_cov_instr:
|
|||
def __init__(self):
|
||||
# Program counter (PC) of the instruction
|
||||
self.pc = vsc.bit_t(rcs.XLEN)
|
||||
rcs.XLEN) # Program counter (PC) of the instruction
|
||||
self.instr = None
|
||||
# self.gpr = None # destination operand of the instruction
|
||||
self.binary = vsc.bit_t(32) # Instruction binary
|
||||
|
|
|
@ -172,16 +172,15 @@ class riscv_instr:
|
|||
# allowed_categories = []
|
||||
|
||||
for items in include_category:
|
||||
allowed_instr.append(self.instr_category[items])
|
||||
|
||||
allowed_instr.extend(self.instr_category[items])
|
||||
for items in exclude_category:
|
||||
if(items in self.instr_category):
|
||||
disallowed_instr.append(self.instr_category[items])
|
||||
disallowed_instr.extend(self.instr_category[items])
|
||||
for items in include_group:
|
||||
allowed_instr.append(self.instr_group[items])
|
||||
allowed_instr.extend(self.instr_group[items])
|
||||
for items in exclude_group:
|
||||
if(items in self.instr_group):
|
||||
disallowed_instr.append(self.instr_group[items])
|
||||
disallowed_instr.extend(self.instr_group[items])
|
||||
|
||||
disallowed_instr.extend(exclude_instr)
|
||||
|
||||
|
|
|
@ -15,11 +15,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
import subprocess
|
||||
import logging
|
||||
import random
|
||||
import copy
|
||||
import sys
|
||||
from bitstring import BitArray
|
||||
from pygen_src.riscv_instr_sequence import riscv_instr_sequence
|
||||
from pygen_src.riscv_instr_pkg import pkg_ins, privileged_reg_t, privileged_mode_t, mtvec_mode_t
|
||||
from pygen_src.riscv_instr_gen_config import cfg
|
||||
from pygen_src.riscv_instr_gen_config import cfg, args, args_dict
|
||||
from pygen_src.target.rv32i import riscv_core_setting as rcs
|
||||
from pygen_src.riscv_instr_stream import riscv_rand_instr_stream
|
||||
from pygen_src.riscv_utils import factory
|
||||
'''
|
||||
RISC-V assembly program generator
|
||||
|
||||
|
@ -33,7 +37,7 @@ class riscv_asm_program_gen:
|
|||
|
||||
def __init__(self):
|
||||
self.instr_stream = []
|
||||
self.directed_instr_stream_ratio = []
|
||||
self.directed_instr_stream_ratio = {}
|
||||
self.hart = 0
|
||||
self.page_table_list = []
|
||||
self.main_program = []
|
||||
|
@ -77,12 +81,18 @@ class riscv_asm_program_gen:
|
|||
|
||||
# Generate main program
|
||||
gt_lbl_str = pkg_ins.get_label("main", hart)
|
||||
label_name = gt_lbl_str
|
||||
gt_lbl_str = riscv_instr_sequence()
|
||||
self.main_program.append(gt_lbl_str)
|
||||
self.main_program[hart].instr_cnt = cfg.main_program_instr_cnt
|
||||
self.main_program[hart].is_debug_program = 0
|
||||
self.main_program[hart].label_name = "main"
|
||||
self.main_program[hart].gen_instr(is_main_program = 1, no_branch = cfg.no_branch_jump)
|
||||
self.main_program[hart].label_name = label_name
|
||||
self.generate_directed_instr_stream(hart=hart,
|
||||
label=self.main_program[hart].label_name,
|
||||
original_instr_cnt=self.main_program[hart].instr_cnt,
|
||||
min_insert_cnt=1,
|
||||
instr_stream=self.main_program[hart].directed_instr)
|
||||
self.main_program[hart].gen_instr(is_main_program=1, no_branch=cfg.no_branch_jump)
|
||||
|
||||
self.main_program[hart].post_process_instr()
|
||||
self.main_program[hart].generate_instr_stream()
|
||||
|
@ -577,14 +587,60 @@ class riscv_asm_program_gen:
|
|||
pass
|
||||
|
||||
def add_directed_instr_stream(self, name, ratio):
|
||||
pass
|
||||
self.directed_instr_stream_ratio[name] = ratio
|
||||
logging.info("Adding directed instruction stream:%0s ratio:%0d/1000", name, ratio)
|
||||
|
||||
def get_directed_instr_stream(self):
|
||||
pass
|
||||
opts = []
|
||||
for i in range(cfg.max_directed_instr_stream_seq):
|
||||
arg = "directed_instr_{}".format(i)
|
||||
stream_name_opts = "stream_name_{}".format(i)
|
||||
stream_freq_opts = "stream_freq_{}".format(i)
|
||||
if(arg in args):
|
||||
val = args_dict[arg]
|
||||
opts = val.split(",")
|
||||
if(len(opts) != 2):
|
||||
logging.critical(
|
||||
"Incorrect directed instruction format : %0s, expect: name,ratio", val)
|
||||
else:
|
||||
self.add_directed_instr_stream(opts[0], int(opts[1]))
|
||||
elif(stream_name_opts in args and stream_freq_opts in args):
|
||||
stream_name = args_dict[stream_name_opts]
|
||||
stream_freq = args_dict[stream_freq_opts]
|
||||
self.add_directed_instr_stream(stream_name, stream_freq)
|
||||
|
||||
def generate_directed_instr_stream(self, hart = 0, label = "", original_instr_cnt = None,
|
||||
def generate_directed_instr_stream(self, hart = 0, label = "", original_instr_cnt = 0,
|
||||
min_insert_cnt = 0, kernel_mode = 0, instr_stream = []):
|
||||
pass
|
||||
instr_insert_cnt = 0
|
||||
idx = 0
|
||||
if(cfg.no_directed_instr):
|
||||
return
|
||||
for instr_stream_name in self.directed_instr_stream_ratio:
|
||||
instr_insert_cnt = int(original_instr_cnt *
|
||||
self.directed_instr_stream_ratio[instr_stream_name] // 1000)
|
||||
if(instr_insert_cnt <= min_insert_cnt):
|
||||
instr_insert_cnt = min_insert_cnt
|
||||
logging.info("Insert directed instr stream %0s %0d/%0d times",
|
||||
instr_stream_name, instr_insert_cnt, original_instr_cnt)
|
||||
for i in range(instr_insert_cnt):
|
||||
name = "{}_{}".format(instr_stream_name, i)
|
||||
object_h = factory(instr_stream_name)
|
||||
object_h.name = name
|
||||
if(object_h is None):
|
||||
logging.critical("Cannot create instr stream %0s", name)
|
||||
sys.exit(1)
|
||||
new_instr_stream = copy.copy(object_h)
|
||||
if(new_instr_stream):
|
||||
new_instr_stream.hart = hart
|
||||
new_instr_stream.label = "{}_{}".format(label, idx)
|
||||
new_instr_stream.kernel_mode = kernel_mode
|
||||
new_instr_stream.randomize()
|
||||
instr_stream.append(new_instr_stream)
|
||||
else:
|
||||
logging.critical("Cannot Create instr stream %0s", name)
|
||||
sys.exit(1)
|
||||
idx += 1
|
||||
random.shuffle(instr_stream)
|
||||
|
||||
def gen_debug_rom(self, hart):
|
||||
pass
|
||||
|
|
|
@ -34,3 +34,14 @@ def DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_
|
|||
"valid": riscv_instr.register(instr_n)
|
||||
})
|
||||
g[class_name] = NewClass
|
||||
|
||||
|
||||
'''
|
||||
TODO
|
||||
@vsc.constraint
|
||||
def add_pseudo_instr(self, instr_n, instr_format, instr_category, instr_group):
|
||||
with vsc.if_then(self.pseudo_instr_name == instr_n):
|
||||
self.format == instr_format.name
|
||||
self.category == instr_category.name
|
||||
self.group == instr_group.name
|
||||
'''
|
||||
|
|
98
vendor/google_riscv-dv/pygen/pygen_src/riscv_directed_instr_lib.py
vendored
Normal file
98
vendor/google_riscv-dv/pygen/pygen_src/riscv_directed_instr_lib.py
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
"""
|
||||
Copyright 2020 Google LLC
|
||||
Copyright 2020 PerfectVIPs Inc.
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
import vsc
|
||||
from enum import IntEnum, auto
|
||||
from pygen_src.riscv_instr_stream import riscv_rand_instr_stream
|
||||
from pygen_src.isa.riscv_instr import riscv_instr_ins
|
||||
from pygen_src.riscv_instr_gen_config import cfg
|
||||
from pygen_src.riscv_instr_pkg import riscv_reg_t, riscv_pseudo_instr_name_t
|
||||
from pygen_src.target.rv32i import riscv_core_setting as rcs
|
||||
from pygen_src.riscv_pseudo_instr import riscv_pseudo_instr
|
||||
|
||||
|
||||
class riscv_directed_instr_stream(riscv_rand_instr_stream):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.name = ""
|
||||
self.label = ""
|
||||
|
||||
def post_randomize(self):
|
||||
for i in range(len(self.instr_list)):
|
||||
self.instr_list[i].has_label = 0
|
||||
self.instr_list[i].atomic = 1
|
||||
self.instr_list[0].comment = "Start %0s" % (self.name)
|
||||
self.instr_list[-1].comment = "End %0s" % (self.name)
|
||||
if self.label != "":
|
||||
self.instr_list[0].label = self.label
|
||||
self.instr_list[0].has_label = 1
|
||||
|
||||
|
||||
class int_numeric_e(IntEnum):
|
||||
NormalValue = auto()
|
||||
Zero = auto()
|
||||
AllOne = auto()
|
||||
NegativeMax = auto()
|
||||
|
||||
|
||||
@vsc.randobj
|
||||
class riscv_int_numeric_corner_stream(riscv_directed_instr_stream):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.num_of_avail_regs = 10
|
||||
self.num_of_instr = vsc.rand_uint8_t()
|
||||
self.init_val = vsc.rand_list_t(vsc.rand_bit_t(rcs.XLEN - 1), sz = 10)
|
||||
self.init_val_type = vsc.rand_list_t(vsc.enum_t(int_numeric_e), sz =10)
|
||||
self.init_instr = []
|
||||
|
||||
@vsc.constraint
|
||||
def init_val_c(self):
|
||||
# TO DO
|
||||
# solve init_val_type before init_val;
|
||||
self.init_val_type.size == self.num_of_avail_regs
|
||||
self.init_val.size == self.num_of_avail_regs
|
||||
self.num_of_instr in vsc.rangelist(vsc.rng(15, 30))
|
||||
|
||||
@vsc.constraint
|
||||
def avail_regs_c(self):
|
||||
self.avail_regs.size == self.num_of_avail_regs
|
||||
vsc.unique(self.avail_regs)
|
||||
with vsc.foreach(self.avail_regs, idx = True) as i:
|
||||
self.avail_regs[i].not_inside(cfg.reserved_regs)
|
||||
self.avail_regs[i] != riscv_reg_t.ZERO
|
||||
|
||||
def pre_randomize(self):
|
||||
pass
|
||||
|
||||
def post_randomize(self):
|
||||
self.init_instr = [None] * self.num_of_avail_regs
|
||||
for i in range(len(self.init_val_type)):
|
||||
if self.init_val_type[i] == int_numeric_e.Zero:
|
||||
self.init_val[i] = 0
|
||||
elif self.init_val_type[i] == int_numeric_e.AllOne:
|
||||
self.init_val[i] = 1
|
||||
elif self.init_val_type[i] == int_numeric_e.NegativeMax:
|
||||
self.init_val[i] = 1 << (rcs.XLEN - 1)
|
||||
self.init_instr[i] = riscv_pseudo_instr()
|
||||
self.init_instr[i].rd = self.avail_regs[i]
|
||||
self.init_instr[i].pseudo_instr_name = riscv_pseudo_instr_name_t.LI
|
||||
self.init_instr[i].imm_str = "0x%0x" % (self.init_val[i])
|
||||
self.instr_list.append(self.init_instr[i])
|
||||
for i in range(self.num_of_instr):
|
||||
instr = riscv_instr_ins.get_rand_instr(
|
||||
include_category = ['ARITHMETIC'],
|
||||
exclude_group = ['RV32C', 'RV64C', 'RV32F', 'RV64F', 'RV32D', 'RV64D'])
|
||||
instr = self.randomize_gpr(instr)
|
||||
self.instr_list.append(instr)
|
||||
super().post_randomize()
|
|
@ -178,6 +178,7 @@ class riscv_instr_cover_group:
|
|||
|
||||
'''TODO: covergroup inheritance is broken at the moment. The workaround
|
||||
will be switched back to the inheritance approach once it gets fixed'''
|
||||
|
||||
# @vsc.covergroup
|
||||
# class lb_cg(load_instr_cg):
|
||||
# def __init__(self, instr):
|
||||
|
@ -1049,8 +1050,8 @@ class riscv_instr_cover_group:
|
|||
cp_t=vsc.enum_t(operand_sign_e))
|
||||
self.cp_branch_hit = vsc.coverpoint(lambda: instr.branch_hit,
|
||||
bins={
|
||||
"Non-taken": vsc.bin(0),
|
||||
"Taken" : vsc.bin(1),
|
||||
"Non-taken": vsc.bin(0)
|
||||
}
|
||||
)
|
||||
self.cp_sign_cross = vsc.cross([self.cp_rs1_sign,
|
||||
|
@ -1334,17 +1335,73 @@ class riscv_instr_cover_group:
|
|||
self.cp_align = vsc.cross([self.cp_imm_align, self.cp_rs1_align])
|
||||
self.cp_ras = vsc.cross([self.cp_rs1_link, self.cp_rd_link])
|
||||
|
||||
'''CSR instructions'''
|
||||
|
||||
@vsc.covergroup
|
||||
class csrrw_cg(object):
|
||||
def __init__(self, instr):
|
||||
super().__init__()
|
||||
|
||||
self.cp_rd = vsc.coverpoint(lambda: instr.rd,
|
||||
cp_t=vsc.enum_t(riscv_reg_t))
|
||||
self.cp_gpr_hazard = vsc.coverpoint(lambda: instr.gpr_hazard,
|
||||
cp_t=vsc.enum_t(hazard_e))
|
||||
self.cp_rs1 = vsc.coverpoint(lambda: instr.rs1,
|
||||
cp_t=vsc.enum_t(riscv_reg_t))
|
||||
|
||||
@vsc.covergroup
|
||||
class opcode_cg(object):
|
||||
def __init__(self, instr):
|
||||
super().__init__()
|
||||
|
||||
self.cp_opcode = vsc.coverpoint(lambda: instr.binary[7:2],
|
||||
bins={
|
||||
"a": vsc.bin_array([], [0, 31])
|
||||
}
|
||||
)
|
||||
|
||||
@vsc.covergroup
|
||||
class rv32i_misc_cg(object):
|
||||
def __init__(self, instr):
|
||||
super().__init__()
|
||||
|
||||
self.cp_misc = vsc.coverpoint(lambda: instr.instr,
|
||||
cp_t=vsc.enum_t(rv32i_misc_instrs))
|
||||
|
||||
@vsc.covergroup
|
||||
class mepc_alignment_cg(object):
|
||||
def __init__(self, instr):
|
||||
super().__init__()
|
||||
|
||||
self.cp_align = vsc.coverpoint(lambda: instr.rd_value[2:0],
|
||||
bins={
|
||||
"Zero": vsc.bin(0),
|
||||
"Two" : vsc.bin(2)
|
||||
}
|
||||
)
|
||||
|
||||
def sample(self, instr):
|
||||
self.instr_cnt += 1
|
||||
if self.instr_cnt > 1:
|
||||
instr.check_hazard_condition(self.pre_instr)
|
||||
# TODO: sampling based on the instruction binary
|
||||
# TODO: sampling for hint, compressed, and illegal_compressed insts
|
||||
if instr.binary[2:0] == 3:
|
||||
opcode_cg = self.opcode_cg(instr)
|
||||
opcode_cg.sample()
|
||||
try:
|
||||
cg = eval("self." + instr.instr.name.lower() + "_cg")(instr)
|
||||
cg.sample()
|
||||
except Exception:
|
||||
logging.info("Covergroup for instr {} is not supported yet".format(
|
||||
instr.instr.name))
|
||||
if instr.group.name == "RV32I":
|
||||
rv32i_misc_cg = self.rv32i_misc_cg(instr)
|
||||
rv32i_misc_cg.sample()
|
||||
if instr.category.name == "CSR":
|
||||
# MEPC
|
||||
if instr.csr == 833:
|
||||
mepc_alignment_cg = self.mepc_alignment_cg(instr)
|
||||
mepc_alignment_cg.sample()
|
||||
self.pre_instr = instr
|
||||
|
||||
def reset(self):
|
||||
|
|
|
@ -111,10 +111,22 @@ class riscv_instr_gen_config:
|
|||
self.num_of_harts = argv.num_of_harts
|
||||
self.fix_sp = argv.fix_sp
|
||||
self.use_push_data_section = argv.use_push_data_section
|
||||
self.boot_mode_opts = ""
|
||||
self.boot_mode_opts = argv.boot_mode_opts
|
||||
|
||||
if(self.boot_mode_opts):
|
||||
logging.info("Got boot mode option - %0s", self.boot_mode_opts)
|
||||
if(self.boot_mode_opts == "m"):
|
||||
self.init_privileged_mode = privileged_mode_t.MACHINE_MODE.name
|
||||
elif(self.boot_mode_opts == "s"):
|
||||
self.init_privileged_mode = privileged_mode_t.SUPERVISOR_MODE.name
|
||||
elif(self.boot_mode_opts == "u"):
|
||||
self.init_privileged_mode = privileged_mode_t.USER_MODE.name
|
||||
else:
|
||||
logging.error("Illegal boot mode option - %0s", self.boot_mode_opts)
|
||||
|
||||
self.enable_page_table_exception = argv.enable_page_table_exception
|
||||
self.no_directed_instr = argv.no_directed_instr
|
||||
self.asm_test_suffix = ""
|
||||
self.asm_test_suffix = argv.asm_test_suffix
|
||||
self.enable_interrupt = argv.enable_interrupt
|
||||
self.enable_nested_interrupt = argv.enable_nested_interrupt
|
||||
self.enable_timer_irq = argv.enable_timer_irq
|
||||
|
@ -153,11 +165,16 @@ class riscv_instr_gen_config:
|
|||
self.enable_floating_point = argv.enable_floating_point
|
||||
self.enable_vector_extension = argv.enable_vector_extension
|
||||
self.enable_b_extension = argv.enable_b_extension
|
||||
# Commenting out for now
|
||||
# self.enable_bitmanip_groups = ['ZBB', 'ZBS', 'ZBP', 'ZBE', 'ZBF',
|
||||
# 'ZBC', 'ZBR', 'ZBM', 'ZBT', 'ZB_TMP']
|
||||
self.enable_bitmanip_groups = argv.enable_bitmanip_groups
|
||||
self.dist_control_mode = 0
|
||||
self.category_dist = {}
|
||||
self.march_isa = argv.march_isa
|
||||
|
||||
if(len(self.march_isa) != 0):
|
||||
rcs.supported_isa = self.march_isa
|
||||
|
||||
if(rcs.supported_isa != 'RV32C'):
|
||||
self.disable_compressed_instr = 1
|
||||
|
||||
@vsc.constraint
|
||||
def gpr_c(self):
|
||||
|
@ -386,35 +403,35 @@ def parse_args():
|
|||
choices = [0, 1], type = int, default = 0)
|
||||
parse.add_argument('--enable_b_extension', help = 'enable_b_extension',
|
||||
choices = [0, 1], type = int, default = 0)
|
||||
|
||||
parse.add_argument('--enable_bitmanip_groups', help = 'enable_bitmanip_groups',
|
||||
default = ['ZBB', 'ZBS', 'ZBP', 'ZBE', 'ZBF',
|
||||
'ZBC', 'ZBR', 'ZBM', 'ZBT', 'ZB_TMP'], nargs = '*')
|
||||
parse.add_argument('--boot_mode_opts', help = 'boot_mode_opts', default = "")
|
||||
parse.add_argument('--asm_test_suffix', help = 'asm_test_suffix', default = "")
|
||||
parse.add_argument('--march_isa', help = 'march_isa', default = [],
|
||||
choices = [i.name for i in riscv_instr_group_t], nargs = '*')
|
||||
parse.add_argument('--directed_instr_0', help = 'directed_instr_0',
|
||||
default = "riscv_int_numeric_corner_stream,4")
|
||||
parse.add_argument('--stream_name_opts', help = 'stream_name_0',
|
||||
default = "riscv_load_store_rand_instr_stream")
|
||||
parse.add_argument('--stream_freq_opts', help = 'stream_freq_0', default = 4)
|
||||
# TODO
|
||||
'''
|
||||
cmdline_enum_processor #(b_ext_group_t)::get_array_values("+enable_bitmanip_groups=",
|
||||
enable_bitmanip_groups);
|
||||
if(inst.get_arg_value("+boot_mode=", boot_mode_opts)) begin
|
||||
`uvm_info(get_full_name(), $sformatf(
|
||||
"Got boot mode option - %0s", boot_mode_opts), UVM_LOW)
|
||||
case(boot_mode_opts)
|
||||
"m" : init_privileged_mode = MACHINE_MODE;
|
||||
"s" : init_privileged_mode = SUPERVISOR_MODE;
|
||||
"u" : init_privileged_mode = USER_MODE;
|
||||
default: `uvm_fatal(get_full_name(),
|
||||
$sformatf("Illegal boot mode option - %0s", boot_mode_opts))
|
||||
endcase
|
||||
init_privileged_mode.rand_mode(0);
|
||||
addr_translaction_rnd_order_c.constraint_mode(0);
|
||||
if ($value$plusargs("tvec_alignment=%0d", tvec_alignment)) begin
|
||||
tvec_alignment.rand_mode(0);
|
||||
end
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_pkg::supported_privileged_mode = %0d",
|
||||
riscv_instr_pkg::supported_privileged_mode.size()), UVM_LOW)
|
||||
void'(inst.get_arg_value("+asm_test_suffix=", asm_test_suffix));
|
||||
// Directed march list from the runtime options, ex. RV32I, RV32M etc.
|
||||
cmdline_enum_processor #(riscv_instr_group_t)::get_array_values("+march=", march_isa);
|
||||
if (march_isa.size != 0) riscv_instr_pkg::supported_isa = march_isa;
|
||||
'''
|
||||
|
||||
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();
|
||||
'''
|
||||
args = parse.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
args = parse_args()
|
||||
args_dict = vars(args)
|
||||
cfg = riscv_instr_gen_config(args)
|
||||
|
|
|
@ -24,7 +24,7 @@ class mem_region_t:
|
|||
xwr = auto()
|
||||
|
||||
|
||||
class satp_mode_t(Enum):
|
||||
class satp_mode_t(IntEnum):
|
||||
BARE = 0b0000
|
||||
SV32 = 0b0001
|
||||
SV39 = 0b1000
|
||||
|
@ -33,7 +33,7 @@ class satp_mode_t(Enum):
|
|||
SV64 = 0b1011
|
||||
|
||||
|
||||
class f_rounding_mode_t(Enum):
|
||||
class f_rounding_mode_t(IntEnum):
|
||||
RNE = 0b000
|
||||
RTZ = 0b001
|
||||
RDN = 0b010
|
||||
|
@ -41,26 +41,26 @@ class f_rounding_mode_t(Enum):
|
|||
RMM = 0b100
|
||||
|
||||
|
||||
class mtvec_mode_t(Enum):
|
||||
class mtvec_mode_t(IntEnum):
|
||||
DIRECT = 0b00
|
||||
VECTORED = 0b01
|
||||
|
||||
|
||||
class imm_t(Enum):
|
||||
class imm_t(IntEnum):
|
||||
IMM = 0
|
||||
UIMM = auto()
|
||||
NZUIMM = auto()
|
||||
NZIMM = auto()
|
||||
|
||||
|
||||
class privileged_mode_t(Enum):
|
||||
class privileged_mode_t(IntEnum):
|
||||
USER_MODE = 0b00
|
||||
SUPERVISOR_MODE = 0b01
|
||||
RESERVED_MODE = 0b10
|
||||
MACHINE_MODE = 0b11
|
||||
|
||||
|
||||
class riscv_instr_group_t(Enum):
|
||||
class riscv_instr_group_t(IntEnum):
|
||||
RV32I = 0
|
||||
RV64I = auto()
|
||||
RV32M = auto()
|
||||
|
@ -85,7 +85,7 @@ class riscv_instr_group_t(Enum):
|
|||
RV64X = auto()
|
||||
|
||||
|
||||
class riscv_instr_name_t(Enum):
|
||||
class riscv_instr_name_t(IntEnum):
|
||||
LUI = 0
|
||||
AUIPC = auto()
|
||||
JAL = auto()
|
||||
|
@ -595,7 +595,7 @@ class riscv_reg_t(IntEnum):
|
|||
T6 = auto()
|
||||
|
||||
|
||||
class riscv_fpr_t(Enum):
|
||||
class riscv_fpr_t(IntEnum):
|
||||
FT0 = 0
|
||||
FT1 = auto()
|
||||
FT2 = auto()
|
||||
|
@ -630,7 +630,7 @@ class riscv_fpr_t(Enum):
|
|||
FT11 = auto()
|
||||
|
||||
|
||||
class riscv_vreg_t(Enum):
|
||||
class riscv_vreg_t(IntEnum):
|
||||
V0 = 0
|
||||
V1 = auto()
|
||||
V2 = auto()
|
||||
|
@ -665,7 +665,7 @@ class riscv_vreg_t(Enum):
|
|||
V31 = auto()
|
||||
|
||||
|
||||
class riscv_instr_format_t(Enum):
|
||||
class riscv_instr_format_t(IntEnum):
|
||||
J_FORMAT = 0
|
||||
U_FORMAT = auto()
|
||||
I_FORMAT = auto()
|
||||
|
@ -689,7 +689,7 @@ class riscv_instr_format_t(Enum):
|
|||
VS_FORMAT = auto()
|
||||
|
||||
|
||||
class va_variant_t(Enum):
|
||||
class va_variant_t(IntEnum):
|
||||
VV = 0
|
||||
VI = auto()
|
||||
VX = auto()
|
||||
|
@ -705,7 +705,7 @@ class va_variant_t(Enum):
|
|||
VM = auto()
|
||||
|
||||
|
||||
class riscv_instr_category_t(Enum):
|
||||
class riscv_instr_category_t(IntEnum):
|
||||
LOAD = 0
|
||||
STORE = auto()
|
||||
SHIFT = auto()
|
||||
|
@ -727,7 +727,7 @@ class riscv_instr_category_t(Enum):
|
|||
# typedef bit[11:0] riscv_csr_t;
|
||||
|
||||
|
||||
class privileged_reg_t(Enum):
|
||||
class privileged_reg_t(IntEnum):
|
||||
USTATUS = 0x000
|
||||
UIE = 0x004
|
||||
UTVEC = 0x005
|
||||
|
@ -958,7 +958,7 @@ class privileged_reg_t(Enum):
|
|||
VLENB = 0xC22
|
||||
|
||||
|
||||
class privileged_reg_fld_t(Enum):
|
||||
class privileged_reg_fld_t(IntEnum):
|
||||
RSVD = 0
|
||||
MXL = auto()
|
||||
EXTENSION = auto()
|
||||
|
@ -967,30 +967,30 @@ class privileged_reg_fld_t(Enum):
|
|||
PPN = auto()
|
||||
|
||||
|
||||
class privileged_level_t(Enum):
|
||||
class privileged_level_t(IntEnum):
|
||||
M_LEVEL = 0b11
|
||||
S_LEVEL = 0b01
|
||||
U_LEVEL = 0b00
|
||||
|
||||
|
||||
class reg_field_access_t(Enum):
|
||||
class reg_field_access_t(IntEnum):
|
||||
WPRI = 0
|
||||
WLRL = auto()
|
||||
WARL = auto()
|
||||
|
||||
|
||||
class riscv_pseudo_instr_name_t(Enum):
|
||||
class riscv_pseudo_instr_name_t(IntEnum):
|
||||
LI = 0
|
||||
LA = auto()
|
||||
|
||||
|
||||
class data_pattern_t(Enum):
|
||||
class data_pattern_t(IntEnum):
|
||||
RAND_DATA = 0
|
||||
ALL_ZERO = auto()
|
||||
INCR_VAL = auto()
|
||||
|
||||
|
||||
class pte_permission_t(Enum):
|
||||
class pte_permission_t(IntEnum):
|
||||
NEXT_LEVEL_PAGE = 0b000
|
||||
READ_ONLY_PAGE = 0b001
|
||||
READ_WRITE_PAGE = 0b011
|
||||
|
@ -999,7 +999,7 @@ class pte_permission_t(Enum):
|
|||
R_W_EXECUTE_PAGE = 0b111
|
||||
|
||||
|
||||
class interrupt_cause_t(Enum):
|
||||
class interrupt_cause_t(IntEnum):
|
||||
U_SOFTWARE_INTR = 0x0
|
||||
S_SOFTWARE_INTR = 0x1
|
||||
M_SOFTWARE_INTR = 0x3
|
||||
|
@ -1011,7 +1011,7 @@ class interrupt_cause_t(Enum):
|
|||
M_EXTERNAL_INTR = 0xB
|
||||
|
||||
|
||||
class exception_cause_t(Enum):
|
||||
class exception_cause_t(IntEnum):
|
||||
INSTRUCTION_ADDRESS_MISALIGNED = 0x0
|
||||
INSTRUCTION_ACCESS_FAULT = 0x1
|
||||
ILLEGAL_INSTRUCTION = 0x2
|
||||
|
@ -1028,7 +1028,7 @@ class exception_cause_t(Enum):
|
|||
STORE_AMO_PAGE_FAULT = 0xF
|
||||
|
||||
|
||||
class misa_ext_t(Enum):
|
||||
class misa_ext_t(IntEnum):
|
||||
MISA_EXT_A = 0
|
||||
MISA_EXT_B = auto()
|
||||
MISA_EXT_C = auto()
|
||||
|
@ -1071,6 +1071,15 @@ class branch_hazard_e(IntEnum):
|
|||
NO_HAZARD = 0
|
||||
RAW_HAZARD = auto()
|
||||
|
||||
|
||||
# RV32I_MISC covergroup instructions
|
||||
class rv32i_misc_instrs(IntEnum):
|
||||
FENCE = 0
|
||||
FENCE_I = auto()
|
||||
EBREAK = auto()
|
||||
ECALL = auto()
|
||||
MRET = auto()
|
||||
|
||||
# Ignore RAW_HAZARD for store lsu hazard
|
||||
class store_lsu_hazard_e(IntEnum):
|
||||
NO_HAZARD = 0
|
||||
|
|
|
@ -16,7 +16,7 @@ import random
|
|||
from collections import defaultdict
|
||||
from pygen_src.riscv_instr_stream import riscv_rand_instr_stream
|
||||
from pygen_src.riscv_instr_gen_config import cfg
|
||||
from pygen_src.riscv_instr_pkg import pkg_ins
|
||||
from pygen_src.riscv_instr_pkg import pkg_ins, riscv_instr_category_t
|
||||
|
||||
|
||||
class riscv_instr_sequence:
|
||||
|
@ -117,7 +117,7 @@ class riscv_instr_sequence:
|
|||
self.branch_idx[i] = random.randint(1, cfg.max_branch_step)
|
||||
|
||||
while(j < len(self.instr_stream.instr_list)):
|
||||
if((self.instr_stream.instr_list[j].category.name == "BRANCH") and
|
||||
if((self.instr_stream.instr_list[j].category == riscv_instr_category_t.BRANCH) and
|
||||
(not self.instr_stream.instr_list[j].branch_assigned) and
|
||||
(not self.instr_stream.instr_list[j].is_illegal_instr)):
|
||||
'''
|
||||
|
|
|
@ -13,12 +13,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
import random
|
||||
import logging
|
||||
import sys
|
||||
import vsc
|
||||
from pygen_src.riscv_instr_pkg import riscv_instr_name_t,\
|
||||
riscv_instr_category_t, riscv_reg_t
|
||||
from pygen_src.isa.riscv_instr import riscv_instr, riscv_instr_ins
|
||||
from pygen_src.riscv_instr_gen_config import cfg
|
||||
|
||||
|
||||
@vsc.randobj
|
||||
class riscv_instr_stream:
|
||||
'''
|
||||
Base class for RISC-V instruction stream
|
||||
|
@ -30,9 +32,9 @@ class riscv_instr_stream:
|
|||
def __init__(self):
|
||||
self.instr_list = []
|
||||
self.instr_cnt = 0
|
||||
self.label = " "
|
||||
self.label = ""
|
||||
# User can specify a small group of available registers to generate various hazard condition
|
||||
self.avail_regs = []
|
||||
self.avail_regs = vsc.randsz_list_t(vsc.enum_t(riscv_reg_t))
|
||||
# Some additional reserved registers that should not be used as rd register
|
||||
# by this instruction stream
|
||||
self.reserved_rd = []
|
||||
|
@ -112,7 +114,7 @@ class riscv_instr_stream:
|
|||
if idx == 0:
|
||||
self.instr_list = new_instr + self.instr_list[idx:current_instr_cnt - 1]
|
||||
else:
|
||||
self.instr_list = self.instr_list[0:idx - 1] + new_instr + \
|
||||
self.instr_list = self.instr_list[0:idx] + new_instr + \
|
||||
self.instr_list[idx:current_instr_cnt - 1]
|
||||
|
||||
def mix_instr_stream(self, new_instr, contained = 0):
|
||||
|
|
48
vendor/google_riscv-dv/pygen/pygen_src/riscv_pseudo_instr.py
vendored
Normal file
48
vendor/google_riscv-dv/pygen/pygen_src/riscv_pseudo_instr.py
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
"""
|
||||
Copyright 2020 Google LLC
|
||||
Copyright 2020 PerfectVIPs Inc.
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
import vsc
|
||||
from pygen_src.isa.riscv_instr import riscv_instr
|
||||
from pygen_src.riscv_instr_pkg import (riscv_pseudo_instr_name_t, riscv_instr_format_t,
|
||||
riscv_instr_category_t, riscv_instr_group_t, pkg_ins)
|
||||
# from pygen_src.riscv_defines import add_pseudo_instr
|
||||
|
||||
|
||||
# Psuedo instructions are used to simplify assembly program writing
|
||||
@vsc.randobj
|
||||
class riscv_pseudo_instr(riscv_instr):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.process_load_store = 0
|
||||
self.format = riscv_instr_format_t.I_FORMAT
|
||||
self.pseudo_instr_name = vsc.rand_enum_t(riscv_pseudo_instr_name_t)
|
||||
|
||||
'''
|
||||
TODO
|
||||
add_pseudo_instr(self, riscv_pseudo_instr_name_t.LI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I)
|
||||
add_pseudo_instr(self, riscv_pseudo_instr_name_t.LA, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I)
|
||||
'''
|
||||
|
||||
def convert2asm(self, prefix = ""):
|
||||
asm_str = pkg_ins.format_string(self.get_instr_name(), pkg_ins.MAX_INSTR_STR_LEN)
|
||||
asm_str = "{}{}, {}".format(asm_str, self.rd.name, self.get_imm())
|
||||
|
||||
if(self.comment != ""):
|
||||
asm_str = "{} #{}".format(asm_str, self.comment)
|
||||
return asm_str.lower()
|
||||
|
||||
def get_instr_name(self):
|
||||
return self.pseudo_instr_name.name
|
30
vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py
vendored
Normal file
30
vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
"""
|
||||
Copyright 2020 Google LLC
|
||||
Copyright 2020 PerfectVIPs Inc.
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
import sys
|
||||
import logging
|
||||
from pygen_src.riscv_directed_instr_lib import (riscv_directed_instr_stream,
|
||||
riscv_int_numeric_corner_stream)
|
||||
|
||||
|
||||
def factory(obj_of):
|
||||
objs = {
|
||||
"riscv_directed_instr_stream": riscv_directed_instr_stream,
|
||||
"riscv_int_numeric_corner_stream": riscv_int_numeric_corner_stream
|
||||
}
|
||||
|
||||
try:
|
||||
return objs[obj_of]()
|
||||
except KeyError:
|
||||
logging.critical("Cannot Create object of %s", obj_of)
|
||||
sys.exit(1)
|
|
@ -22,10 +22,12 @@ from pygen_src.riscv_asm_program_gen import riscv_asm_program_gen # NOQA
|
|||
class riscv_instr_base_test:
|
||||
def __init__(self):
|
||||
pass
|
||||
asm = riscv_asm_program_gen()
|
||||
|
||||
for _ in range(cfg.num_of_tests):
|
||||
cfg.randomize()
|
||||
asm = riscv_asm_program_gen()
|
||||
riscv_instr_ins.create_instr_list(cfg)
|
||||
test_name = "riscv_asm_test_{}.S".format(_)
|
||||
test_name = "riscv_arithmetic_basic_test_{}.S".format(_)
|
||||
asm.get_directed_instr_stream()
|
||||
asm.gen_program()
|
||||
asm.gen_test_file(test_name)
|
||||
|
|
|
@ -116,6 +116,8 @@ class riscv_instr_cov_test:
|
|||
file.write(tabulate(table, headers, tablefmt="grid",
|
||||
numalign="center", stralign="center"))
|
||||
file.close()
|
||||
# Write in xml format to be read by pyucis-viewer (visualization)
|
||||
vsc.write_coverage_db("cov_db.xml")
|
||||
|
||||
def post_process_trace(self):
|
||||
pass
|
||||
|
|
76
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
76
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
|
@ -109,9 +109,9 @@ def get_rs1_val(iteration, xlen):
|
|||
3) A randomly generated number
|
||||
"""
|
||||
if iteration == 0:
|
||||
return bitarray(hex=f"0x{'a5'*int(xlen/8)}")
|
||||
return bitarray(hex="0x{}".format('a5'*int(xlen/8)))
|
||||
elif iteration == 1:
|
||||
return bitarray(hex=f"0x{'5a'*int(xlen/8)}")
|
||||
return bitarray(hex="0x{}".format('5a'*int(xlen/8)))
|
||||
elif iteration == 2:
|
||||
val = bitarray(uint=0, length=xlen)
|
||||
# Must randomize all 32 bits, due to randomization library limitations
|
||||
|
@ -193,7 +193,7 @@ def predict_csr_val(csr_op, rs1_val, csr_val, csr_write_mask, csr_read_mask):
|
|||
elif csr_op == 'csrrci':
|
||||
zero.append(rs1_val[-5:])
|
||||
csr_write((~zero) & prediction, csr_val, csr_write_mask)
|
||||
return f"0x{prediction.hex}"
|
||||
return "0x{}".format(prediction.hex)
|
||||
|
||||
|
||||
def gen_setup(test_file):
|
||||
|
@ -203,12 +203,12 @@ def gen_setup(test_file):
|
|||
Args:
|
||||
test_file: the file containing the generated assembly code.
|
||||
"""
|
||||
test_file.write(f".macro init\n")
|
||||
test_file.write(f".endm\n")
|
||||
test_file.write(f".section .text.init\n")
|
||||
test_file.write(f".globl _start\n")
|
||||
test_file.write(f".option norvc\n")
|
||||
test_file.write(f"_start:\n")
|
||||
test_file.write(".macro init\n")
|
||||
test_file.write(".endm\n")
|
||||
test_file.write(".section .text.init\n")
|
||||
test_file.write(".globl _start\n")
|
||||
test_file.write(".option norvc\n")
|
||||
test_file.write("_start:\n")
|
||||
|
||||
|
||||
def gen_csr_test_fail(test_file, end_addr):
|
||||
|
@ -221,13 +221,13 @@ def gen_csr_test_fail(test_file, end_addr):
|
|||
test_file: the file containing the generated assembly test code.
|
||||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_fail:\n")
|
||||
test_file.write(f"\tli x1, {TEST_FAIL}\n")
|
||||
test_file.write(f"\tslli x1, x1, 8\n")
|
||||
test_file.write(f"\taddi x1, x1, {TEST_RESULT}\n")
|
||||
test_file.write(f"\tli x2, 0x{end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_fail\n")
|
||||
test_file.write("csr_fail:\n")
|
||||
test_file.write("\tli x1, {}\n".format(TEST_FAIL))
|
||||
test_file.write("\tslli x1, x1, 8\n")
|
||||
test_file.write("\taddi x1, x1, {}\n".format(TEST_RESULT))
|
||||
test_file.write("\tli x2, 0x{}\n".format(end_addr))
|
||||
test_file.write("\tsw x1, 0(x2)\n")
|
||||
test_file.write("\tj csr_fail\n")
|
||||
|
||||
|
||||
def gen_csr_test_pass(test_file, end_addr):
|
||||
|
@ -240,13 +240,13 @@ def gen_csr_test_pass(test_file, end_addr):
|
|||
test_file: the file containing the generated assembly test code.
|
||||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_pass:\n")
|
||||
test_file.write(f"\tli x1, {TEST_PASS}\n")
|
||||
test_file.write(f"\tslli x1, x1, 8\n")
|
||||
test_file.write(f"\taddi x1, x1, {TEST_RESULT}\n")
|
||||
test_file.write(f"\tli x2, 0x{end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_pass\n")
|
||||
test_file.write("csr_pass:\n")
|
||||
test_file.write("\tli x1, {}\n".format(TEST_PASS))
|
||||
test_file.write("\tslli x1, x1, 8\n")
|
||||
test_file.write("\taddi x1, x1, {}\n".format(TEST_RESULT))
|
||||
test_file.write("\tli x2, 0x{}\n".format(end_addr))
|
||||
test_file.write("\tsw x1, 0(x2)\n")
|
||||
test_file.write("\tj csr_pass\n")
|
||||
|
||||
|
||||
def gen_csr_instr(original_csr_map, csr_instructions, xlen,
|
||||
|
@ -271,13 +271,13 @@ def gen_csr_instr(original_csr_map, csr_instructions, xlen,
|
|||
# pick two GPRs at random to act as source and destination registers
|
||||
# for CSR operations
|
||||
csr_map = copy.deepcopy(original_csr_map)
|
||||
source_reg, dest_reg = [f"x{i}" for i in random.sample(range(1, 16), 2)]
|
||||
source_reg, dest_reg = ["x{}".format(i) for i in random.sample(range(1, 16), 2)]
|
||||
csr_list = list(csr_map.keys())
|
||||
with open(f"{out}/riscv_csr_test_{i}.S", "w") as csr_test_file:
|
||||
with open("{}/riscv_csr_test_{}.S".format(out, i), "w") as csr_test_file:
|
||||
gen_setup(csr_test_file)
|
||||
for csr in csr_list:
|
||||
csr_address, csr_val, csr_write_mask, csr_read_mask = csr_map.get(csr)
|
||||
csr_test_file.write(f"\t# {csr}\n")
|
||||
csr_test_file.write("\t# {}\n".format(csr))
|
||||
for op in csr_instructions:
|
||||
for i in range(3):
|
||||
# hex string
|
||||
|
@ -286,17 +286,17 @@ def gen_csr_instr(original_csr_map, csr_instructions, xlen,
|
|||
first_li = ""
|
||||
if op[-1] == "i":
|
||||
imm = rand_rs1_val[-5:]
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr_address}, 0b{imm.bin}\n"
|
||||
csr_inst = "\t{} {}, {}, 0b{}\n".format(op, dest_reg, csr_address, imm.bin)
|
||||
imm_val = bitarray(uint=0, length=xlen-5)
|
||||
imm_val.append(imm)
|
||||
predict_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val(op, imm_val, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
predict_li = ("\tli {}, "
|
||||
"{}\n".format(source_reg, predict_csr_val(op, imm_val, csr_val, csr_write_mask, csr_read_mask)))
|
||||
else:
|
||||
first_li = f"\tli {source_reg}, 0x{rand_rs1_val.hex}\n"
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr_address}, {source_reg}\n"
|
||||
predict_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val(op, rand_rs1_val, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
branch_check = f"\tbne {source_reg}, {dest_reg}, csr_fail\n"
|
||||
first_li = "\tli {}, 0x{}\n".format(source_reg, rand_rs1_val.hex)
|
||||
csr_inst = "\t{} {}, {}, {}\n".format(op, dest_reg, csr_address, source_reg)
|
||||
predict_li = ("\tli {}, "
|
||||
"{}\n".format(source_reg, predict_csr_val(op, rand_rs1_val, csr_val, csr_write_mask, csr_read_mask)))
|
||||
branch_check = "\tbne {}, {}, csr_fail\n".format(source_reg, dest_reg)
|
||||
csr_test_file.write(first_li)
|
||||
csr_test_file.write(csr_inst)
|
||||
csr_test_file.write(predict_li)
|
||||
|
@ -306,11 +306,11 @@ def gen_csr_instr(original_csr_map, csr_instructions, xlen,
|
|||
been written to the CSR has not been tested.
|
||||
"""
|
||||
if csr == csr_list[-1] and op == csr_instructions[-1] and i == 2:
|
||||
final_csr_read = f"\tcsrr {dest_reg}, {csr_address}\n"
|
||||
final_csr_read = "\tcsrr {}, {}\n".format(dest_reg, csr_address)
|
||||
csrrs_read_mask = bitarray(uint=0, length=xlen)
|
||||
final_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val('csrrs', csrrs_read_mask, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
final_branch_check = f"\tbne {source_reg}, {dest_reg}, csr_fail\n"
|
||||
final_li = ("\tli {}, "
|
||||
"{}\n".format(source_reg, predict_csr_val('csrrs', csrrs_read_mask, csr_val, csr_write_mask, csr_read_mask)))
|
||||
final_branch_check = "\tbne {}, {}, csr_fail\n".format(source_reg, dest_reg)
|
||||
csr_test_file.write(final_csr_read)
|
||||
csr_test_file.write(final_li)
|
||||
csr_test_file.write(final_branch_check)
|
||||
|
|
|
@ -20,7 +20,7 @@ class riscv_amo_instr extends riscv_instr;
|
|||
rand bit rl;
|
||||
|
||||
constraint aq_rl_c {
|
||||
aq && rl == 0;
|
||||
(aq && rl) == 0;
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_amo_instr)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue