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@6cf6b4f
Update code from upstream repository https://github.com/google/riscv- dv to revision 6cf6b4f389272d8ff5e2b397af43ac6c0dfba2e2 * Update init value for floating point reg (google/riscv-dv#615) (weicaiyang) * temporarily comment out 4 vector instructions to re-enable coverage flow (google/riscv-dv#616) (udinator) * Fix vector load/store instruction encoding (google/riscv-dv#614) (taoliug) * Add user_init.s to allow custom initialization routine (google/riscv-dv#613) (taoliug) * Fix vector extension config register initialization (google/riscv- dv#610) (taoliug) * Add floating point coverage part2 (google/riscv-dv#600) (weicaiyang) * Add MAX LMUL configure (google/riscv-dv#609) (taoliug) * Fix vector unit strided load/store instruction stream name (google/riscv-dv#608) (taoliug) * Update pygen source files (google/riscv-dv#602) (ANIL SHARMA) * Add vector strided load/store test (google/riscv-dv#601) (taoliug) * make <main> 4-byte aligned when enabling PMP (google/riscv-dv#596) (udinator) * Fix ius compilation issue (google/riscv-dv#599) (taoliug) * Integrate Andes's vector extension work to upstream (google/riscv- dv#598) (taoliug) * Fix kernal setcion PTE setting issue (google/riscv-dv#594) (taoliug) * Add flake8 check for pygen (google/riscv-dv#589) (Hai Hoang Dang) * Fix MPRV setting issue, it's causing problem for exception handling with virtual address translation on (google/riscv-dv#593) (taoliug) * Fix VSETVL generation issue (google/riscv-dv#591) (taoliug) * Fix jump instruction stream label issue (google/riscv-dv#590) (taoliug) * Add pygen_src files (aneels3) Signed-off-by: Udi <udij@google.com>
This commit is contained in:
parent
b302b6da92
commit
e8a71c8ac8
37 changed files with 2914 additions and 344 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: 1ad73cc43f8f84d93d49040f8b2928e74efdd854
|
||||
rev: 6cf6b4f389272d8ff5e2b397af43ac6c0dfba2e2
|
||||
}
|
||||
}
|
||||
|
|
10
vendor/google_riscv-dv/.flake8
vendored
Normal file
10
vendor/google_riscv-dv/.flake8
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
[flake8]
|
||||
|
||||
# Maximum line length
|
||||
max-line-length = 100
|
||||
|
||||
ignore =
|
||||
# Ignore unexpected spaces around keyword / parameter equals
|
||||
E251,
|
||||
# Do not complain about line breaks after operators
|
||||
W504
|
3
vendor/google_riscv-dv/.travis.yml
vendored
3
vendor/google_riscv-dv/.travis.yml
vendored
|
@ -2,8 +2,6 @@ language: python
|
|||
dist: xenial
|
||||
matrix:
|
||||
include:
|
||||
- python: 3.5
|
||||
env: TOX_ENV=py35
|
||||
- python: 3.6
|
||||
env: TOX_ENV=py36
|
||||
- python: 3.7
|
||||
|
@ -15,3 +13,4 @@ install:
|
|||
script:
|
||||
- sphinx-build -E -W -b linkcheck docs/source build
|
||||
- pip uninstall -y riscv-dv
|
||||
- flake8 --show-source pygen/pygen_src/ --config=.flake8
|
||||
|
|
408
vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py
vendored
Normal file
408
vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py
vendored
Normal file
|
@ -0,0 +1,408 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
from pygen_src.riscv_instr_gen_config import riscv_instr_gen_config
|
||||
from pygen_src.riscv_instr_pkg import riscv_instr_group_t
|
||||
from pygen_src.isa import rv32i_instr # NOQA
|
||||
import random
|
||||
from bitstring import BitArray
|
||||
import logging
|
||||
from copy import copy
|
||||
import sys
|
||||
|
||||
|
||||
class riscv_instr:
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
instr_registry = {}
|
||||
|
||||
def __init__(self):
|
||||
self.instr_names = []
|
||||
self.instr_group = defaultdict(list)
|
||||
self.instr_category = defaultdict(list)
|
||||
self.basic_instr = []
|
||||
self.instr_template = {}
|
||||
|
||||
self.exclude_reg = []
|
||||
self.include_reg = []
|
||||
|
||||
self.group = None
|
||||
self.format = None
|
||||
self.category = None
|
||||
self.instr_name = None
|
||||
self.imm_type = None
|
||||
self.imm_len = 0
|
||||
|
||||
self.csr = None
|
||||
self.rs2 = None
|
||||
self.rs1 = None
|
||||
self.rd = None
|
||||
self.imm = BitArray(hex="0x00000000")
|
||||
|
||||
self.imm_mask = BitArray(hex="0xffffffff")
|
||||
self.is_branch_target = None
|
||||
self.has_label = 1
|
||||
self.atomic = 0
|
||||
self.branch_assigned = None
|
||||
self.process_load_store = 1
|
||||
self.is_compressed = None
|
||||
self.is_illegal_instr = None
|
||||
self.is_hint_instr = None
|
||||
self.is_floating_point = None
|
||||
self.imm_str = None
|
||||
self.comment = None
|
||||
self.label = None
|
||||
self.is_local_numeric_label = None
|
||||
self.idx = -1
|
||||
self.has_rs1 = 1
|
||||
self.has_rs2 = 1
|
||||
self.has_rd = 1
|
||||
self.has_imm = 1
|
||||
|
||||
# Fields Added for debugging These fields are actually from a different files.
|
||||
self.unsupported_instr = []
|
||||
self.XLEN = 32
|
||||
self.supported_isa = [riscv_instr_group_t.RV32I]
|
||||
self.implemented_csr = []
|
||||
|
||||
@classmethod
|
||||
def register(cls, instr_name):
|
||||
logging.info("Registering %s", instr_name.name)
|
||||
cls.instr_registry[instr_name.name] = 1
|
||||
if(instr_name is None):
|
||||
print("\n")
|
||||
return 1
|
||||
|
||||
def create_instr_list(self, cfg):
|
||||
self.instr_names.clear()
|
||||
self.instr_group.clear()
|
||||
self.instr_category.clear()
|
||||
for instr_name, values in self.instr_registry.items():
|
||||
if(instr_name in self.unsupported_instr):
|
||||
continue
|
||||
instr_inst = self.create_instr(instr_name)
|
||||
self.instr_template[instr_name] = instr_inst
|
||||
|
||||
if (not instr_inst.is_supported(cfg)):
|
||||
continue
|
||||
if ((self.XLEN != 32) and (instr_name == "C_JAL")):
|
||||
continue
|
||||
if (("SP" in cfg.reserved_regs) and (instr_name == "C_ADDI16SP")):
|
||||
continue
|
||||
if (cfg.enable_sfence and instr_name == "SFENCE_VMA"):
|
||||
continue
|
||||
if (instr_name in ["FENCE", "FENCE_I", "SFENCE_VMA"]):
|
||||
continue
|
||||
if (instr_inst.group in self.supported_isa and
|
||||
not(cfg.disable_compressed_instr and
|
||||
instr_inst.group in ["RV32C", "RV64C", "RV32DC", "RV32FC", "RV128C"]) and
|
||||
not(not(cfg.enable_floating_point) and instr_inst.group in
|
||||
["RV32F", "RV64F", "RV32D", "RV64D"])):
|
||||
self.instr_category[instr_inst.category.name].append(instr_name)
|
||||
self.instr_group[instr_inst.group.name].append(instr_name)
|
||||
self.instr_names.append(instr_name)
|
||||
|
||||
self.build_basic_instruction_list(cfg)
|
||||
self.create_csr_filter(cfg)
|
||||
|
||||
def create_instr(self, instr_name):
|
||||
"""TODO This method is specific to RV32I instruction only.
|
||||
It must be scaled to all instruction extensions."""
|
||||
try:
|
||||
instr_inst = eval("rv32i_instr.riscv_" + instr_name + "_instr()")
|
||||
except Exception:
|
||||
logging.critical("Failed to create instr: %0s", instr_name)
|
||||
sys.exit(1)
|
||||
return instr_inst
|
||||
|
||||
def is_supported(self, cfg):
|
||||
return 1
|
||||
|
||||
def build_basic_instruction_list(self, cfg):
|
||||
self.basic_instr = (self.instr_category["SHIFT"] + self.instr_category["ARITHMETIC"] +
|
||||
self.instr_category["LOGICAL"] + self.instr_category["COMPARE"])
|
||||
if(cfg.no_ebreak == 0):
|
||||
self.basic_instr.append("EBREAK")
|
||||
for items in self.supported_isa:
|
||||
if("RV32C" in self.supported_isa and not(cfg.disable_compressed_instr)):
|
||||
self.basic_instr.append("C_EBREAK")
|
||||
break
|
||||
if(cfg.no_dret == 0):
|
||||
self.basic_instr.append("DRET")
|
||||
if(cfg.no_fence == 0):
|
||||
self.basic_instr.append(self.instr_category["SYNCH"])
|
||||
if(cfg.no_csr_instr == 0 and cfg.init_privileged_mode == "MACHINE_MODE"):
|
||||
self.basic_instr.append(self.instr_category["CSR"])
|
||||
if(cfg.no_wfi == 0):
|
||||
self.basic_instr.append("WFI")
|
||||
|
||||
def create_csr_filter(self, cfg):
|
||||
self.include_reg.clear()
|
||||
self.exclude_reg.clear()
|
||||
|
||||
if(cfg.enable_illegal_csr_instruction):
|
||||
self.exclude_reg = self.implemented_csr
|
||||
elif(cfg.enable_access_invalid_csr_level):
|
||||
self.include_reg = cfg.invalid_priv_mode_csrs
|
||||
else:
|
||||
if(cfg.init_privileged_mode == "MACHINE_MODE"): # Machine Mode
|
||||
self.include_reg.append("MSCRATCH")
|
||||
elif(cfg.init_privileged_mode == "SUPERVISOR_MODE"): # Supervisor Mode
|
||||
self.include_reg.append("SSCRATCH")
|
||||
else: # User Mode
|
||||
self.include_reg.append("USCRATCH")
|
||||
|
||||
def get_rand_instr(self, include_instr=[], exclude_instr=[],
|
||||
include_category=[], exclude_category=[],
|
||||
include_group=[], exclude_group=[]):
|
||||
idx = BitArray(uint = 0, length = 32)
|
||||
name = ""
|
||||
allowed_instr = []
|
||||
disallowed_instr = []
|
||||
# allowed_categories = []
|
||||
|
||||
for items in include_category:
|
||||
allowed_instr.append(self.instr_category[items])
|
||||
|
||||
for items in exclude_category:
|
||||
if(items in self.instr_category):
|
||||
disallowed_instr.append(self.instr_category[items])
|
||||
for items in include_group:
|
||||
allowed_instr.append(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(exclude_instr)
|
||||
|
||||
if(len(disallowed_instr) == 0):
|
||||
if(len(include_instr) > 0):
|
||||
idx = random.randrange(0, len(include_instr) - 1)
|
||||
name = include_instr[idx]
|
||||
elif(len(allowed_instr > 0)):
|
||||
idx = random.randrange(0, len(allowed_instr) - 1)
|
||||
name = allowed_instr[idx]
|
||||
else:
|
||||
idx = random.randrange(0, len(self.instr_names) - 1)
|
||||
name = self.instr_names[idx]
|
||||
else:
|
||||
# TODO
|
||||
instr_names_set = set(self.instr_names)
|
||||
disallowed_instr_set = set(disallowed_instr)
|
||||
allowed_instr_set = set(allowed_instr)
|
||||
include_instr_set = set(include_instr)
|
||||
excluded_instr_names_list = list(instr_names_set - disallowed_instr_set)
|
||||
excluded_allowed_instr_list = list(allowed_instr_set - disallowed_instr_set)
|
||||
include_instr_list = list(include_instr_set - disallowed_instr_set)
|
||||
|
||||
name = random.choice(excluded_instr_names_list)
|
||||
if(len(include_instr) > 0):
|
||||
name = random.choice(include_instr_list)
|
||||
if(len(allowed_instr) > 0):
|
||||
name = random.choice(excluded_allowed_instr_list)
|
||||
if(name is None):
|
||||
logging.critical("%s Cannot generate random instruction", riscv_instr.__name__)
|
||||
sys.exit(1)
|
||||
|
||||
instr_h = copy(self.instr_template[name])
|
||||
return instr_h
|
||||
|
||||
def get_load_store_instr(self, load_store_instr):
|
||||
instr_h = riscv_instr()
|
||||
if(len(load_store_instr) == 0):
|
||||
load_store_instr = self.instr_category["LOAD"] + \
|
||||
self.instr_category["STORE"]
|
||||
self.idx = random.randrange(0, len(load_store_instr) - 1)
|
||||
name = load_store_instr[self.idx]
|
||||
instr_h = copy(self.instr_template[name])
|
||||
return instr_h
|
||||
|
||||
def get_instr(self, name):
|
||||
if (not self.instr_template.get(name)):
|
||||
logging.critical("Cannot get instr %s", name)
|
||||
instr_h = copy(self.instr_template[name])
|
||||
return instr_h
|
||||
|
||||
def set_rand_mode(self):
|
||||
# rand_mode setting for Instruction Format
|
||||
if(self.format.name == "R_FORMAT"):
|
||||
self.has_imm = 0
|
||||
if(self.format.name == "I_FORMAT"):
|
||||
self.has_rs2 = 0
|
||||
if(self.format.name in ["S_FORMAT", "B_FORMAT"]):
|
||||
self.has_rd = 0
|
||||
if(self.format.name in ["U_FORMAT", "J_FORMAT"]):
|
||||
self.has_rs1 = 0
|
||||
self.has_rs2 = 0
|
||||
|
||||
# rand_mode setting for Instruction Category
|
||||
if(self.category.name == "CSR"):
|
||||
self.has_rs2 = 0
|
||||
if(self.format.name == "I_FORMAT"):
|
||||
self.has_rs1 = 0
|
||||
|
||||
def pre_randomize(self):
|
||||
pass # TODO
|
||||
|
||||
def set_imm_len(self):
|
||||
if(self.format.name in ["U_FORMAT", "J_FORMAT"]):
|
||||
self.imm_len = 20
|
||||
elif(self.format.name in ["I_FORMAT", "S_FORMAT", "B_FORMAT"]):
|
||||
if(self.imm_type.name == "UIMM"):
|
||||
self.imm_len = 5
|
||||
else:
|
||||
self.imm_len = 11
|
||||
self.imm_mask = self.imm_mask << self.imm_len
|
||||
|
||||
def extend_imm(self):
|
||||
sign = 0
|
||||
self.imm = self.imm << (32 - self.imm_len)
|
||||
# sign = imm[31]
|
||||
sign = self.imm.bin[0:1:1]
|
||||
self.imm = self.imm >> (32 - self.imm_len)
|
||||
# Signed extension
|
||||
if((sign and not(self.format == "U_FORMAT")) or (self.imm_type in ["UIMM", "NZUIMM"])):
|
||||
self.imm = self.imm_mask | self.imm
|
||||
|
||||
def post_randomize(self):
|
||||
self.extend_imm()
|
||||
self.update_imm_str()
|
||||
|
||||
def convert2asm(self):
|
||||
pass
|
||||
|
||||
def get_opcode(self):
|
||||
if(self.instr_name.name == "LUI"):
|
||||
return (BitArray(uint = 55, length = 7).bin)
|
||||
elif(self.instr_name.name == "AUIPC"):
|
||||
return (BitArray(uint = 23, length = 7).bin)
|
||||
elif(self.instr_name.name == "JAL"):
|
||||
return (BitArray(uint = 23, length = 7).bin)
|
||||
elif(self.instr_name.name == "JALR"):
|
||||
return (BitArray(uint = 111, length = 7).bin)
|
||||
elif(self.instr_name.name in ["BEQ", "BNE", "BLT", "BGE", "BLTU", "BGEU"]):
|
||||
return (BitArray(uint = 103, length = 7).bin)
|
||||
elif(self.instr_name.name in ["LB", "LH", "LW", "LBU", "LHU", "LWU", "LD"]):
|
||||
return (BitArray(uint = 99, length = 7).bin)
|
||||
elif(self.instr_name.name in ["SB", "SH", "SW", "SD"]):
|
||||
return (BitArray(uint = 35, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ADDI", "SLTI", "SLTIU", "XORI", "ORI", "ANDI",
|
||||
"SLLI", "SRLI", "SRAI", "NOP"]):
|
||||
return (BitArray(uint = 19, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ADD", "SUB", "SLL", "SLT", "SLTU", "XOR", "SRL",
|
||||
"SRA", "OR", "AND", "MUL", "MULH", "MULHSU", "MULHU",
|
||||
"DIV", "DIVU", "REM", "REMU"]):
|
||||
return (BitArray(uint = 51, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ADDIW", "SLLIW", "SRLIW", "SRAIW"]):
|
||||
return (BitArray(uint = 27, length = 7).bin)
|
||||
elif(self.instr_name.name in ["MULH", "MULHSU", "MULHU", "DIV", "DIVU", "REM", "REMU"]):
|
||||
return (BitArray(uint = 51, length = 7).bin)
|
||||
elif(self.instr_name.name in ["FENCE", "FENCE_I"]):
|
||||
return (BitArray(uint = 15, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ECALL", "EBREAK", "CSRRW", "CSRRS", "CSRRC", "CSRRWI",
|
||||
"CSRRSI", "CSRRCI"]):
|
||||
return (BitArray(uint = 115, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ADDW", "SUBW", "SLLW", "SRLW", "SRAW", "MULW", "DIVW",
|
||||
"DIVUW", "REMW", "REMUW"]):
|
||||
return (BitArray(uint = 59, length = 7).bin)
|
||||
elif(self.instr_name.name in ["ECALL", "EBREAK", "URET", "SRET", "MRET", "DRET", "WFI",
|
||||
"SFENCE_VMA"]):
|
||||
return (BitArray(uint = 115, length = 7).bin)
|
||||
else:
|
||||
logging.critical("Unsupported instruction %0s", self.instr_name.name)
|
||||
sys.exit(1)
|
||||
|
||||
def get_func3(self):
|
||||
if(self.instr_name.name in ["JALR", "BEQ", "LB", "SB", "ADDI", "NOP", "ADD", "SUB",
|
||||
"FENCE", "ECALL", "EBREAK", "ADDIW", "ADDW", "SUBW", "MUL",
|
||||
"MULW", "ECALL", "EBREAK", "URET", "SRET", "MRET", "DRET",
|
||||
"WFI", "SFENCE_VMA"]):
|
||||
return (BitArray(uint = 0, length = 3).bin)
|
||||
elif(self.instr_name.name in ["BNE", "LH", "SH", "SLLI", "SLL", "FENCE_I", "CSRRW", "SLLIW",
|
||||
"SLLW", "MULH"]):
|
||||
return (BitArray(uint = 1, length = 3).bin)
|
||||
elif(self.instr_name.name in ["LW", "SW", "SLTI", "SLT", "CSRRS", "MULHS"]):
|
||||
return (BitArray(uint = 2, length = 3).bin)
|
||||
elif(self.instr_name.name in ["SLTIU", "SLTU", "CSRRC", "LD", "SD", "MULHU"]):
|
||||
return (BitArray(uint = 3, length = 3).bin)
|
||||
elif(self.instr_name.name in ["BLT", "LBU", "XORI", "XOR", "DIV", "DIVW"]):
|
||||
return (BitArray(uint = 4, length = 3).bin)
|
||||
elif(self.instr_name.name in ["BGE", "LHU", "SRLI", "SRAI", "SRL", "SRA", "CSRRWI", "SRLIW",
|
||||
"SRAIW", "SRLW",
|
||||
"SRAW", "DIVU", "DIVUW"]):
|
||||
return (BitArray(uint = 5, length = 3).bin)
|
||||
elif(self.instr_name.name in ["BLTU", "ORI", "OR", "CSRRSI", "LWU", "REM", "REMW"]):
|
||||
return (BitArray(uint = 6, length = 3).bin)
|
||||
elif(self.instr_name.name in ["BGEU", "ANDI", "AND", "CSRRCI", "REMU", "REMUW"]):
|
||||
return (BitArray(uint = 7, length = 3).bin)
|
||||
else:
|
||||
logging.critical("Unsupported instruction %0s", self.instr_name.name)
|
||||
sys.exit(1)
|
||||
|
||||
def get_func7(self):
|
||||
if(self.instr_name.name in ["SLLI", "SRLI", "ADD", "SLL", "SLT", "SLTU", "XOR",
|
||||
"SRL", "OR", "AND", "FENCE", "FENCE_I", "SLLIW",
|
||||
"SRLIW", "ADDW", "SLLW", "SRLW", "ECALL", "EBREAK", "URET"]):
|
||||
return (BitArray(uint = 0, length = 7).bin)
|
||||
elif(self.instr_name.name in ["SUB", "SRA", "SRAIW", "SUBW", "SRAW"]):
|
||||
return (BitArray(uint = 32, length = 7).bin)
|
||||
elif(self.instr_name.name in ["MUL", "MULH", "MULHSU", "MULHU", "DIV", "DIVU", "REM",
|
||||
"REMU", "MULW", "DIVW", "DIVUW", "REMW", "REMUW"]):
|
||||
return (BitArray(uint = 1, length = 7).bin)
|
||||
elif(self.instr_name.name in ["SRET", "WFI"]):
|
||||
return (BitArray(uint = 8, length = 7).bin)
|
||||
elif(self.instr_name.name == "MRET"):
|
||||
return (BitArray(uint = 24, length = 7).bin)
|
||||
elif(self.instr_name.name == "DRET"):
|
||||
return (BitArray(uint = 61, length = 7).bin)
|
||||
elif(self.instr_name.name == "SFENCE_VMA"):
|
||||
return (BitArray(uint = 9, length = 7).bin)
|
||||
else:
|
||||
logging.critical("Unsupported instruction %0s", self.instr_name.name)
|
||||
sys.exit(1)
|
||||
|
||||
def convert2bin(self):
|
||||
pass # TODO
|
||||
|
||||
def get_instr_name(self):
|
||||
get_instr_name = self.instr_name.name
|
||||
for i in get_instr_name:
|
||||
if(i == "_"):
|
||||
get_instr_name = get_instr_name.replace(i, ".")
|
||||
return get_instr_name
|
||||
|
||||
def get_c_gpr(self, gpr):
|
||||
return self.gpr
|
||||
|
||||
def get_imm(self):
|
||||
return self.imm_str
|
||||
|
||||
def clear_unused_label(self):
|
||||
if(self.has_label and not(self.is_branch_target) and self.is_local_numeric_label):
|
||||
self.has_label = 0
|
||||
|
||||
def do_copy(self):
|
||||
pass # TODO
|
||||
|
||||
def update_imm_str(self):
|
||||
self.imm_str = str(self.imm)
|
||||
|
||||
|
||||
riscv_instr_ins = riscv_instr()
|
||||
cfg = riscv_instr_gen_config()
|
141
vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py
vendored
Normal file
141
vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
from pygen_src.riscv_defines import DEFINE_INSTR
|
||||
from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t,
|
||||
riscv_instr_category_t, riscv_instr_group_t, imm_t)
|
||||
|
||||
|
||||
# LOAD instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.LB, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.LH, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.LW, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.LBU, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.LHU, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
|
||||
# STORE instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.SB, riscv_instr_format_t.S_FORMAT,
|
||||
riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SH, riscv_instr_format_t.S_FORMAT,
|
||||
riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SW, riscv_instr_format_t.S_FORMAT,
|
||||
riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
|
||||
# SHIFT intructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLL, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLLI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SRL, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SRLI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SRA, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SRAI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
|
||||
# ARITHMETIC intructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.ADD, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.ADDI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.NOP, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SUB, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.LUI, riscv_instr_format_t.U_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.AUIPC, riscv_instr_format_t.U_FORMAT,
|
||||
riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
# LOGICAL instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.XOR, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.XORI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.OR, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.ORI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.AND, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.ANDI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
|
||||
# COMPARE instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLT, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLTI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLTU, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SLTIU, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
|
||||
# BRANCH instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.BEQ, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.BNE, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.BLT, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.BGE, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.BLTU, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.BGEU, riscv_instr_format_t.B_FORMAT,
|
||||
riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
# JUMP instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.JAL, riscv_instr_format_t.J_FORMAT,
|
||||
riscv_instr_category_t.JUMP, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.JALR, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.JUMP, riscv_instr_group_t.RV32I, g=globals())
|
||||
# SYNCH instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.FENCE, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.FENCE_I, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SFENCE_VMA, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
|
||||
# SYSTEM instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.ECALL, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.EBREAK, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.URET, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.SRET, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.MRET, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.DRET, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.WFI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.INTERRUPT, riscv_instr_group_t.RV32I, g=globals())
|
||||
# CSR instructions
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRW, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRS, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRC, riscv_instr_format_t.R_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRWI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRSI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
||||
DEFINE_INSTR(riscv_instr_name_t.CSRRCI, riscv_instr_format_t.I_FORMAT,
|
||||
riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
|
39
vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py
vendored
Normal file
39
vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
from pygen_src.riscv_instr_pkg import imm_t
|
||||
from pygen_src.isa.riscv_instr import riscv_instr
|
||||
|
||||
|
||||
def DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_t.IMM, g=globals()):
|
||||
class_name = f"riscv_{instr_n.name}_instr"
|
||||
|
||||
def __init__(self):
|
||||
riscv_instr.__init__(self)
|
||||
self.instr_name = instr_n
|
||||
self.format = instr_format
|
||||
self.category = instr_category
|
||||
self.group = instr_group
|
||||
self.imm_type = imm_tp
|
||||
|
||||
self.set_imm_len()
|
||||
self.set_rand_mode()
|
||||
NewClass = type(class_name, (riscv_instr,), {
|
||||
"__init__": __init__,
|
||||
"valid": riscv_instr.register(instr_n)
|
||||
})
|
||||
g[class_name] = NewClass
|
34
vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py
vendored
Normal file
34
vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class riscv_instr_gen_config:
|
||||
def __init__(self):
|
||||
self.enable_floating_point = 1
|
||||
self.disable_compressed_instr = 1
|
||||
self.num_of_test = 3
|
||||
self.no_fence = 1
|
||||
self.enable_sfence = 0
|
||||
self.reserved_regs = []
|
||||
self.enable_illegal_csr_instruction = 0
|
||||
self.enable_access_invalid_csr_level = 0
|
||||
self.invalid_priv_mode_csrs = []
|
||||
self.init_privileged_mode = "MACHINE_MODE"
|
||||
self.no_ebreak = 1
|
||||
self.no_dret = 1
|
||||
self.no_csr_instr = 1
|
||||
self.no_wfi = 1
|
602
vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py
vendored
Normal file
602
vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py
vendored
Normal file
|
@ -0,0 +1,602 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
from enum import Enum, auto
|
||||
|
||||
|
||||
class riscv_instr_name_t(Enum):
|
||||
# RV32I instructions
|
||||
LUI = 0
|
||||
AUIPC = auto()
|
||||
JAL = auto()
|
||||
JALR = auto()
|
||||
BEQ = auto()
|
||||
BNE = auto()
|
||||
BLT = auto()
|
||||
BGE = auto()
|
||||
BLTU = auto()
|
||||
BGEU = auto()
|
||||
LB = auto()
|
||||
LH = auto()
|
||||
LW = auto()
|
||||
LBU = auto()
|
||||
LHU = auto()
|
||||
SB = auto()
|
||||
SH = auto()
|
||||
SW = auto()
|
||||
ADDI = auto()
|
||||
SLTI = auto()
|
||||
SLTIU = auto()
|
||||
XORI = auto()
|
||||
ORI = auto()
|
||||
ANDI = auto()
|
||||
SLLI = auto()
|
||||
SRLI = auto()
|
||||
SRAI = auto()
|
||||
ADD = auto()
|
||||
SUB = auto()
|
||||
SLL = auto()
|
||||
SLT = auto()
|
||||
SLTU = auto()
|
||||
XOR = auto()
|
||||
SRL = auto()
|
||||
SRA = auto()
|
||||
OR = auto()
|
||||
AND = auto()
|
||||
NOP = auto()
|
||||
FENCE = auto()
|
||||
FENCE_I = auto()
|
||||
ECALL = auto()
|
||||
EBREAK = auto()
|
||||
CSRRW = auto()
|
||||
CSRRS = auto()
|
||||
CSRRC = auto()
|
||||
CSRRWI = auto()
|
||||
CSRRSI = auto()
|
||||
CSRRCI = auto()
|
||||
# RV32B instructions
|
||||
ANDN = auto()
|
||||
ORN = auto()
|
||||
XNOR = auto()
|
||||
GORC = auto()
|
||||
SLO = auto()
|
||||
SRO = auto()
|
||||
ROL = auto()
|
||||
ROR = auto()
|
||||
SBCLR = auto()
|
||||
SBSET = auto()
|
||||
SBINV = auto()
|
||||
SBEXT = auto()
|
||||
GREV = auto()
|
||||
SLOI = auto()
|
||||
SROI = auto()
|
||||
RORI = auto()
|
||||
SBCLRI = auto()
|
||||
SBSETI = auto()
|
||||
SBINVI = auto()
|
||||
SBEXTI = auto()
|
||||
GORCI = auto()
|
||||
GREVI = auto()
|
||||
CMIX = auto()
|
||||
CMOV = auto()
|
||||
FSL = auto()
|
||||
FSR = auto()
|
||||
FSRI = auto()
|
||||
CLZ = auto()
|
||||
CTZ = auto()
|
||||
PCNT = auto()
|
||||
SEXT_B = auto()
|
||||
SEXT_H = auto()
|
||||
CRC32_B = auto()
|
||||
CRC32_H = auto()
|
||||
CRC32_W = auto()
|
||||
CRC32C_B = auto()
|
||||
CRC32C_H = auto()
|
||||
CRC32C_W = auto()
|
||||
CLMUL = auto()
|
||||
CLMULR = auto()
|
||||
CLMULH = auto()
|
||||
MIN = auto()
|
||||
MAX = auto()
|
||||
MINU = auto()
|
||||
MAXU = auto()
|
||||
SHFL = auto()
|
||||
UNSHFL = auto()
|
||||
BDEP = auto()
|
||||
BEXT = auto()
|
||||
PACK = auto()
|
||||
PACKU = auto()
|
||||
BMATOR = auto()
|
||||
BMATXOR = auto()
|
||||
PACKH = auto()
|
||||
BFP = auto()
|
||||
SHFLI = auto()
|
||||
UNSHFLI = auto()
|
||||
# RV64B instructions
|
||||
ADDIWU = auto()
|
||||
SLLIU_W = auto()
|
||||
ADDWU = auto()
|
||||
SUBWU = auto()
|
||||
BMATFLIP = auto()
|
||||
CRC32_D = auto()
|
||||
CRC32C_D = auto()
|
||||
ADDU_W = auto()
|
||||
SUBU_W = auto()
|
||||
SLOW = auto()
|
||||
SROW = auto()
|
||||
ROLW = auto()
|
||||
RORW = auto()
|
||||
SBCLRW = auto()
|
||||
SBSETW = auto()
|
||||
SBINVW = auto()
|
||||
SBEXTW = auto()
|
||||
GORCW = auto()
|
||||
GREVW = auto()
|
||||
SLOIW = auto()
|
||||
SROIW = auto()
|
||||
RORIW = auto()
|
||||
SBCLRIW = auto()
|
||||
SBSETIW = auto()
|
||||
SBINVIW = auto()
|
||||
GORCIW = auto()
|
||||
GREVIW = auto()
|
||||
FSLW = auto()
|
||||
FSRW = auto()
|
||||
FSRIW = auto()
|
||||
CLZW = auto()
|
||||
CTZW = auto()
|
||||
PCNTW = auto()
|
||||
CLMULW = auto()
|
||||
CLMULRW = auto()
|
||||
CLMULHW = auto()
|
||||
SHFLW = auto()
|
||||
UNSHFLW = auto()
|
||||
BDEPW = auto()
|
||||
BEXTW = auto()
|
||||
PACKW = auto()
|
||||
PACKUW = auto()
|
||||
BFPW = auto()
|
||||
# RV32M instructions
|
||||
MUL = auto()
|
||||
MULH = auto()
|
||||
MULHSU = auto()
|
||||
MULHU = auto()
|
||||
DIV = auto()
|
||||
DIVU = auto()
|
||||
REM = auto()
|
||||
REMU = auto()
|
||||
# RV64M instructions
|
||||
MULW = auto()
|
||||
DIVW = auto()
|
||||
DIVUW = auto()
|
||||
REMW = auto()
|
||||
REMUW = auto()
|
||||
# RV32F instructions
|
||||
FLW = auto()
|
||||
FSW = auto()
|
||||
FMADD_S = auto()
|
||||
FMSUB_S = auto()
|
||||
FNMSUB_S = auto()
|
||||
FNMADD_S = auto()
|
||||
FADD_S = auto()
|
||||
FSUB_S = auto()
|
||||
FMUL_S = auto()
|
||||
FDIV_S = auto()
|
||||
FSQRT_S = auto()
|
||||
FSGNJ_S = auto()
|
||||
FSGNJN_S = auto()
|
||||
FSGNJX_S = auto()
|
||||
FMIN_S = auto()
|
||||
FMAX_S = auto()
|
||||
FCVT_W_S = auto()
|
||||
FCVT_WU_S = auto()
|
||||
FMV_X_W = auto()
|
||||
FEQ_S = auto()
|
||||
FLT_S = auto()
|
||||
FLE_S = auto()
|
||||
FCLASS_S = auto()
|
||||
FCVT_S_W = auto()
|
||||
FCVT_S_WU = auto()
|
||||
FMV_W_X = auto()
|
||||
# RV64F instruction
|
||||
FCVT_L_S = auto()
|
||||
FCVT_LU_S = auto()
|
||||
FCVT_S_L = auto()
|
||||
FCVT_S_LU = auto()
|
||||
# RV32D instructions
|
||||
FLD = auto()
|
||||
FSD = auto()
|
||||
FMADD_D = auto()
|
||||
FMSUB_D = auto()
|
||||
FNMSUB_D = auto()
|
||||
FNMADD_D = auto()
|
||||
FADD_D = auto()
|
||||
FSUB_D = auto()
|
||||
FMUL_D = auto()
|
||||
FDIV_D = auto()
|
||||
FSQRT_D = auto()
|
||||
FSGNJ_D = auto()
|
||||
FSGNJN_D = auto()
|
||||
FSGNJX_D = auto()
|
||||
FMIN_D = auto()
|
||||
FMAX_D = auto()
|
||||
FCVT_S_D = auto()
|
||||
FCVT_D_S = auto()
|
||||
FEQ_D = auto()
|
||||
FLT_D = auto()
|
||||
FLE_D = auto()
|
||||
FCLASS_D = auto()
|
||||
FCVT_W_D = auto()
|
||||
FCVT_WU_D = auto()
|
||||
FCVT_D_W = auto()
|
||||
FCVT_D_WU = auto()
|
||||
# RV64D
|
||||
FCVT_L_D = auto()
|
||||
FCVT_LU_D = auto()
|
||||
FMV_X_D = auto()
|
||||
FCVT_D_L = auto()
|
||||
FCVT_D_LU = auto()
|
||||
FMV_D_X = auto()
|
||||
# RV64I
|
||||
LWU = auto()
|
||||
LD = auto()
|
||||
SD = auto()
|
||||
ADDIW = auto()
|
||||
SLLIW = auto()
|
||||
SRLIW = auto()
|
||||
SRAIW = auto()
|
||||
ADDW = auto()
|
||||
SUBW = auto()
|
||||
SLLW = auto()
|
||||
SRLW = auto()
|
||||
SRAW = auto()
|
||||
# RV32C
|
||||
C_LW = auto()
|
||||
C_SW = auto()
|
||||
C_LWSP = auto()
|
||||
C_SWSP = auto()
|
||||
C_ADDI4SPN = auto()
|
||||
C_ADDI = auto()
|
||||
C_LI = auto()
|
||||
C_ADDI16SP = auto()
|
||||
C_LUI = auto()
|
||||
C_SRLI = auto()
|
||||
C_SRAI = auto()
|
||||
C_ANDI = auto()
|
||||
C_SUB = auto()
|
||||
C_XOR = auto()
|
||||
C_OR = auto()
|
||||
C_AND = auto()
|
||||
C_BEQZ = auto()
|
||||
C_BNEZ = auto()
|
||||
C_SLLI = auto()
|
||||
C_MV = auto()
|
||||
C_EBREAK = auto()
|
||||
C_ADD = auto()
|
||||
C_NOP = auto()
|
||||
C_J = auto()
|
||||
C_JAL = auto()
|
||||
C_JR = auto()
|
||||
C_JALR = auto()
|
||||
# RV64C
|
||||
C_ADDIW = auto()
|
||||
C_SUBW = auto()
|
||||
C_ADDW = auto()
|
||||
C_LD = auto()
|
||||
C_SD = auto()
|
||||
C_LDSP = auto()
|
||||
C_SDSP = auto()
|
||||
# RV128C
|
||||
C_SRLI64 = auto()
|
||||
C_SRAI64 = auto()
|
||||
C_SLLI64 = auto()
|
||||
C_LQ = auto()
|
||||
C_SQ = auto()
|
||||
C_LQSP = auto()
|
||||
C_SQSP = auto()
|
||||
# RV32FC
|
||||
C_FLW = auto()
|
||||
C_FSW = auto()
|
||||
C_FLWSP = auto()
|
||||
C_FSWSP = auto()
|
||||
# RV32DC
|
||||
C_FLD = auto()
|
||||
C_FSD = auto()
|
||||
C_FLDSP = auto()
|
||||
C_FSDSP = auto()
|
||||
# RV32A
|
||||
LR_W = auto()
|
||||
SC_W = auto()
|
||||
AMOSWAP_W = auto()
|
||||
AMOADD_W = auto()
|
||||
AMOAND_W = auto()
|
||||
AMOOR_W = auto()
|
||||
AMOXOR_W = auto()
|
||||
AMOMIN_W = auto()
|
||||
AMOMAX_W = auto()
|
||||
AMOMINU_W = auto()
|
||||
AMOMAXU_W = auto()
|
||||
# RV64A
|
||||
LR_D = auto()
|
||||
SC_D = auto()
|
||||
AMOSWAP_D = auto()
|
||||
AMOADD_D = auto()
|
||||
AMOAND_D = auto()
|
||||
AMOOR_D = auto()
|
||||
AMOXOR_D = auto()
|
||||
AMOMIN_D = auto()
|
||||
AMOMAX_D = auto()
|
||||
AMOMINU_D = auto()
|
||||
AMOMAXU_D = auto()
|
||||
# Vector instructions
|
||||
VSETVL = auto()
|
||||
VSETVLI = auto()
|
||||
VADD = auto()
|
||||
VSUB = auto()
|
||||
VRSUB = auto()
|
||||
VWADDU = auto()
|
||||
VWSUBU = auto()
|
||||
VWADD = auto()
|
||||
VWSUB = auto()
|
||||
VADC = auto()
|
||||
VMADC = auto()
|
||||
VSBC = auto()
|
||||
VMSBC = auto()
|
||||
VAND = auto()
|
||||
VOR = auto()
|
||||
VXOR = auto()
|
||||
VSLL = auto()
|
||||
VSRL = auto()
|
||||
VSRA = auto()
|
||||
VNSRL = auto()
|
||||
VNSRA = auto()
|
||||
VMSEQ = auto()
|
||||
VMSNE = auto()
|
||||
VMSLTU = auto()
|
||||
VMSLT = auto()
|
||||
VMSLEU = auto()
|
||||
VMSLE = auto()
|
||||
VMSGTU = auto()
|
||||
VMSGT = auto()
|
||||
VMINU = auto()
|
||||
VMIN = auto()
|
||||
VMAXU = auto()
|
||||
VMAX = auto()
|
||||
VMUL = auto()
|
||||
VMULH = auto()
|
||||
VMULHU = auto()
|
||||
VMULHSU = auto()
|
||||
VDIVU = auto()
|
||||
VDIV = auto()
|
||||
VREMU = auto()
|
||||
VREM = auto()
|
||||
VWMUL = auto()
|
||||
VWMULU = auto()
|
||||
VWMULSU = auto()
|
||||
VMACC = auto()
|
||||
VNMSAC = auto()
|
||||
VMADD = auto()
|
||||
VNMSUB = auto()
|
||||
VWMACCU = auto()
|
||||
VWMACC = auto()
|
||||
VWMACCSU = auto()
|
||||
VWMACCUS = auto()
|
||||
'''
|
||||
VQMACCU = auto()
|
||||
VQMACC = auto()
|
||||
VQMACCSU = auto()
|
||||
VQMACCUS = auto()
|
||||
'''
|
||||
VMERGE = auto()
|
||||
VMV = auto()
|
||||
VSADDU = auto()
|
||||
VSADD = auto()
|
||||
VSSUBU = auto()
|
||||
VSSUB = auto()
|
||||
VAADDU = auto()
|
||||
VAADD = auto()
|
||||
VASUBU = auto()
|
||||
VASUB = auto()
|
||||
VSSRL = auto()
|
||||
VSSRA = auto()
|
||||
VNCLIPU = auto()
|
||||
VNCLIP = auto()
|
||||
VFADD = auto()
|
||||
VFSUB = auto()
|
||||
VFRSUB = auto()
|
||||
VFMUL = auto()
|
||||
VFDIV = auto()
|
||||
VFRDIV = auto()
|
||||
VFWMUL = auto()
|
||||
VFMACC = auto()
|
||||
VFNMACC = auto()
|
||||
VFMSAC = auto()
|
||||
VFNMSAC = auto()
|
||||
VFMADD = auto()
|
||||
VFNMADD = auto()
|
||||
VFMSUB = auto()
|
||||
VFNMSUB = auto()
|
||||
VFWMACC = auto()
|
||||
VFWNMACC = auto()
|
||||
VFWMSAC = auto()
|
||||
VFWNMSAC = auto()
|
||||
VFSQRT_V = auto()
|
||||
VFMIN = auto()
|
||||
VFMAX = auto()
|
||||
VFSGNJ = auto()
|
||||
VFSGNJN = auto()
|
||||
VFSGNJX = auto()
|
||||
VMFEQ = auto()
|
||||
VMFNE = auto()
|
||||
VMFLT = auto()
|
||||
VMFLE = auto()
|
||||
VMFGT = auto()
|
||||
VMFGE = auto()
|
||||
VFCLASS_V = auto()
|
||||
VFMERGE = auto()
|
||||
VFMV = auto()
|
||||
VFCVT_XU_F_V = auto()
|
||||
VFCVT_X_F_V = auto()
|
||||
VFCVT_F_XU_V = auto()
|
||||
VFCVT_F_X_V = auto()
|
||||
VFWCVT_XU_F_V = auto()
|
||||
VFWCVT_X_F_V = auto()
|
||||
VFWCVT_F_XU_V = auto()
|
||||
VFWCVT_F_X_V = auto()
|
||||
VFWCVT_F_F_V = auto()
|
||||
VFNCVT_XU_F_W = auto()
|
||||
VFNCVT_X_F_W = auto()
|
||||
VFNCVT_F_XU_W = auto()
|
||||
VFNCVT_F_X_W = auto()
|
||||
VFNCVT_F_F_W = auto()
|
||||
VFNCVT_ROD_F_F_W = auto()
|
||||
# Vector reduction instruction
|
||||
VREDSUM_VS = auto()
|
||||
VREDMAXU_VS = auto()
|
||||
VREDMAX_VS = auto()
|
||||
VREDMINU_VS = auto()
|
||||
VREDMIN_VS = auto()
|
||||
VREDAND_VS = auto()
|
||||
VREDOR_VS = auto()
|
||||
VREDXOR_VS = auto()
|
||||
VWREDSUMU_VS = auto()
|
||||
VWREDSUM_VS = auto()
|
||||
VFREDOSUM_VS = auto()
|
||||
VFREDSUM_VS = auto()
|
||||
VFREDMAX_VS = auto()
|
||||
VFWREDOSUM_VS = auto()
|
||||
VFWREDSUM_VS = auto()
|
||||
# Vector mask instruction
|
||||
VMAND_MM = auto()
|
||||
VMNAND_MM = auto()
|
||||
VMANDNOT_MM = auto()
|
||||
VMXOR_MM = auto()
|
||||
VMOR_MM = auto()
|
||||
VMNOR_MM = auto()
|
||||
VMORNOT_MM = auto()
|
||||
VMXNOR_MM = auto()
|
||||
VPOPC_M = auto()
|
||||
VFIRST_M = auto()
|
||||
VMSBF_M = auto()
|
||||
VMSIF_M = auto()
|
||||
VMSOF_M = auto()
|
||||
VIOTA_M = auto()
|
||||
VID_V = auto()
|
||||
# Vector permutation instruction
|
||||
VMV_X_S = auto()
|
||||
VMV_S_X = auto()
|
||||
VFMV_F_S = auto()
|
||||
VFMV_S_F = auto()
|
||||
VSLIDEUP = auto()
|
||||
VSLIDEDOWN = auto()
|
||||
VSLIDE1UP = auto()
|
||||
VSLIDE1DOWN = auto()
|
||||
VRGATHER = auto()
|
||||
VCOMPRESS = auto()
|
||||
VMV1R_V = auto()
|
||||
VMV2R_V = auto()
|
||||
VMV4R_V = auto()
|
||||
VMV8R_V = auto()
|
||||
# Supervisor instruction
|
||||
DRET = auto()
|
||||
MRET = auto()
|
||||
URET = auto()
|
||||
SRET = auto()
|
||||
WFI = auto()
|
||||
SFENCE_VMA = auto()
|
||||
# Custom instructions
|
||||
# import riscv_custom_instr_enum #TODO: Right now it's not working as expected fix it
|
||||
# You can add other instructions here
|
||||
INVALID_INSTR = auto()
|
||||
|
||||
|
||||
class riscv_instr_format_t(Enum):
|
||||
J_FORMAT = 0
|
||||
U_FORMAT = auto()
|
||||
I_FORMAT = auto()
|
||||
B_FORMAT = auto()
|
||||
R_FORMAT = auto()
|
||||
S_FORMAT = auto()
|
||||
R4_FORMAT = auto()
|
||||
# Compressed instruction format
|
||||
CI_FORMAT = auto()
|
||||
CB_FORMAT = auto()
|
||||
CJ_FORMAT = auto()
|
||||
CR_FORMAT = auto()
|
||||
CA_FORMAT = auto()
|
||||
CL_FORMAT = auto()
|
||||
CS_FORMAT = auto()
|
||||
CSS_FORMAT = auto()
|
||||
CIW_FORMAT = auto()
|
||||
# Vector instruction format
|
||||
VSET_FORMAT = auto()
|
||||
VA_FORMAT = auto()
|
||||
VS2_FORMAT = auto() # op vd,vs2
|
||||
VL_FORMAT = auto()
|
||||
VS_FORMAT = auto()
|
||||
|
||||
|
||||
class riscv_instr_category_t(Enum):
|
||||
LOAD = 0
|
||||
STORE = auto()
|
||||
SHIFT = auto()
|
||||
ARITHMETIC = auto()
|
||||
LOGICAL = auto()
|
||||
COMPARE = auto()
|
||||
BRANCH = auto()
|
||||
JUMP = auto()
|
||||
SYNCH = auto()
|
||||
SYSTEM = auto()
|
||||
COUNTER = auto()
|
||||
CSR = auto()
|
||||
CHANGELEVEL = auto()
|
||||
TRAP = auto()
|
||||
INTERRUPT = auto()
|
||||
# `VECTOR_INCLUDE("riscv_instr_pkg_inc_riscv_instr_category_t.sv") TODO: Fix this
|
||||
AMO = auto() # (last one)
|
||||
|
||||
|
||||
class riscv_instr_group_t(Enum):
|
||||
RV32I = 0
|
||||
RV64I = auto()
|
||||
RV32M = auto()
|
||||
RV64M = auto()
|
||||
RV32A = auto()
|
||||
RV64A = auto()
|
||||
RV32F = auto()
|
||||
RV32FC = auto()
|
||||
RV64F = auto()
|
||||
RV32D = auto()
|
||||
RV32DC = auto()
|
||||
RV64D = auto()
|
||||
RV32C = auto()
|
||||
RV64C = auto()
|
||||
RV128I = auto()
|
||||
RV128C = auto()
|
||||
RV32V = auto()
|
||||
RV32B = auto()
|
||||
RV64V = auto()
|
||||
RV64B = auto()
|
||||
RV32X = auto()
|
||||
RV64X = auto()
|
||||
|
||||
|
||||
class imm_t(Enum):
|
||||
IMM = 0 # Signed immediate
|
||||
UIMM = auto() # Unsigned immediate
|
||||
NZUIMM = auto() # Non-zero unsigned immediate
|
||||
NZIMM = auto() # Non-zero signed immediate
|
29
vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py
vendored
Normal file
29
vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
"""
|
||||
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.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Regression script for RISC-V random instruction generator
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.path.append("../../")
|
||||
from pygen_src.isa.rv32i_instr import * # NOQA
|
||||
from pygen_src.isa.riscv_instr import cfg, riscv_instr_ins # NOQA
|
||||
|
||||
|
||||
class riscv_instr_base_test:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
for _ in range(cfg.num_of_test):
|
||||
riscv_instr_ins.create_instr_list(cfg)
|
1
vendor/google_riscv-dv/requirements.txt
vendored
1
vendor/google_riscv-dv/requirements.txt
vendored
|
@ -6,3 +6,4 @@ sphinxcontrib-log-cabinet
|
|||
sphinx-issues
|
||||
sphinx_rtd_theme
|
||||
rst2pdf
|
||||
flake8
|
||||
|
|
|
@ -37,7 +37,7 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
if (category == LOAD) begin
|
||||
asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name());
|
||||
end else if (instr_name inside {FMV_X_W, FMV_X_D, FCVT_W_S, FCVT_WU_S,
|
||||
FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D, FCVT_LU_S,
|
||||
FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D,
|
||||
FCVT_W_D, FCVT_WU_D}) begin
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
|
||||
end else if (instr_name inside {FMV_W_X, FMV_D_X, FCVT_S_W, FCVT_S_WU,
|
||||
|
@ -158,7 +158,9 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
end
|
||||
case(format)
|
||||
I_FORMAT: begin
|
||||
`DV_CHECK_FATAL(operands.size() == 2)
|
||||
// TODO ovpsim has an extra operand rte as below
|
||||
// fcvt.d.s fs1,fs4,rte
|
||||
//`DV_CHECK_FATAL(operands.size() == 2)
|
||||
if (has_fs1) begin
|
||||
fs1 = get_fpr(operands[1]);
|
||||
fs1_value = get_gpr_state(operands[1]);
|
||||
|
@ -177,6 +179,13 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
get_val(operands[1], imm);
|
||||
end
|
||||
R_FORMAT: begin
|
||||
// convert Pseudoinstructions for ovpsim
|
||||
// fmv.s rd, rs -> fsgnj.s rd, rs, rs
|
||||
if (operands.size() == 2 && instr_name inside {FSGNJ_S, FSGNJX_S, FSGNJN_S, FSGNJ_D,
|
||||
FSGNJX_D, FSGNJN_D}) begin
|
||||
operands.push_back(operands[$]);
|
||||
end
|
||||
|
||||
if (has_fs2 || category == CSR) begin
|
||||
`DV_CHECK_FATAL(operands.size() == 3)
|
||||
end else begin
|
||||
|
@ -205,7 +214,6 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
endfunction : update_src_regs
|
||||
|
||||
virtual function void update_dst_regs(string reg_name, string val_str);
|
||||
$display("update_dst_regs %0s", reg_name);
|
||||
get_val(val_str, gpr_state[reg_name], .hex(1));
|
||||
if (has_fd) begin
|
||||
fd = get_fpr(reg_name);
|
||||
|
@ -218,9 +226,59 @@ class riscv_floating_point_instr extends riscv_instr;
|
|||
|
||||
virtual function riscv_fpr_t get_fpr(input string str);
|
||||
str = str.toupper();
|
||||
if (!fpr_enum::from_name(str, get_fpr)) begin
|
||||
if (!uvm_enum_wrapper#(riscv_fpr_t)::from_name(str, get_fpr)) begin
|
||||
`uvm_fatal(`gfn, $sformatf("Cannot convert %0s to FPR", str))
|
||||
end
|
||||
endfunction : get_fpr
|
||||
|
||||
virtual function void pre_sample();
|
||||
super.pre_sample();
|
||||
|
||||
// for single precision sign bit is bit 31, upper 32 bits are all 1s
|
||||
// for double precision, it's 63
|
||||
if (group inside {RV32F, RV64F}) begin
|
||||
fs1_sign = get_fp_operand_sign(fs1_value, 31);
|
||||
fs2_sign = get_fp_operand_sign(fs2_value, 31);
|
||||
fs3_sign = get_fp_operand_sign(fs2_value, 31);
|
||||
fd_sign = get_fp_operand_sign(fd_value, 31);
|
||||
end else if (instr_name == FCVT_S_D) begin
|
||||
fs1_sign = get_fp_operand_sign(fs1_value, 63);
|
||||
fd_sign = get_fp_operand_sign(fd_value, 31);
|
||||
end else if (instr_name == FCVT_D_S) begin
|
||||
fs1_sign = get_fp_operand_sign(fs1_value, 31);
|
||||
fd_sign = get_fp_operand_sign(fd_value, 63);
|
||||
end else begin
|
||||
fs1_sign = get_fp_operand_sign(fs1_value, 63);
|
||||
fs2_sign = get_fp_operand_sign(fs2_value, 63);
|
||||
fs3_sign = get_fp_operand_sign(fs2_value, 63);
|
||||
fd_sign = get_fp_operand_sign(fd_value, 63);
|
||||
end
|
||||
endfunction : pre_sample
|
||||
|
||||
virtual function operand_sign_e get_fp_operand_sign(bit [XLEN-1:0] value, int idx);
|
||||
if (value[idx]) begin
|
||||
return NEGATIVE;
|
||||
end else begin
|
||||
return POSITIVE;
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function void check_hazard_condition(riscv_instr pre_instr);
|
||||
riscv_floating_point_instr pre_fp_instr;
|
||||
super.check_hazard_condition(pre_instr);
|
||||
if ($cast(pre_fp_instr, pre_instr) && pre_fp_instr.has_fd) begin
|
||||
if ((has_fs1 && (fs1 == pre_fp_instr.fd)) || (has_fs2 && (fs2 == pre_fp_instr.fd))
|
||||
|| (has_fs3 && (fs3 == pre_fp_instr.fd))) begin
|
||||
gpr_hazard = RAW_HAZARD;
|
||||
end else if (has_fd && (fd == pre_fp_instr.fd)) begin
|
||||
gpr_hazard = WAW_HAZARD;
|
||||
end else if (has_fd && ((pre_fp_instr.has_fs1 && (pre_fp_instr.fs1 == fd)) ||
|
||||
(pre_fp_instr.has_fs2 && (pre_fp_instr.fs2 == fd)) ||
|
||||
(pre_fp_instr.has_fs3 && (pre_fp_instr.fs3 == fd)))) begin
|
||||
gpr_hazard = WAR_HAZARD;
|
||||
end else begin
|
||||
gpr_hazard = NO_HAZARD;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
endclass
|
||||
|
|
|
@ -32,6 +32,8 @@ class riscv_instr extends uvm_object;
|
|||
static privileged_reg_t exclude_reg[];
|
||||
static privileged_reg_t include_reg[];
|
||||
|
||||
riscv_instr_gen_config m_cfg;
|
||||
|
||||
// Instruction attributes
|
||||
riscv_instr_group_t group;
|
||||
riscv_instr_format_t format;
|
||||
|
@ -124,7 +126,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}))
|
||||
(instr_inst.group inside {RV32F, RV64F, RV32D, RV64D})) &&
|
||||
!(!cfg.enable_vector_extension &&
|
||||
(instr_inst.group inside {RVV}))
|
||||
) begin
|
||||
instr_category[instr_inst.category].push_back(instr_name);
|
||||
instr_group[instr_inst.group].push_back(instr_name);
|
||||
|
|
|
@ -260,10 +260,6 @@
|
|||
gpr_hazard.name(), lsu_hazard.name()), UVM_FULL)
|
||||
endfunction
|
||||
|
||||
virtual function void sample_cov();
|
||||
pre_sample();
|
||||
endfunction
|
||||
|
||||
virtual function void update_src_regs(string operands[$]);
|
||||
privileged_reg_t preg;
|
||||
case(format)
|
||||
|
|
278
vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
vendored
278
vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
vendored
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,6 +15,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// Base class for RISC-V vector exenstion ISA, implmented based on spec v0.8
|
||||
class riscv_vector_instr extends riscv_floating_point_instr;
|
||||
|
||||
rand riscv_vreg_t vs1;
|
||||
|
@ -21,14 +24,17 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
rand riscv_vreg_t vs3;
|
||||
rand riscv_vreg_t vd;
|
||||
rand va_variant_t va_variant;
|
||||
rand bit vm;
|
||||
rand bit wd;
|
||||
bit has_vd = 1'b1;
|
||||
bit has_vs1 = 1'b1;
|
||||
bit has_vs2 = 1'b1;
|
||||
bit has_vs3 = 1'b1;
|
||||
bit has_vm = 1'b0;
|
||||
bit has_va_variant;
|
||||
bit is_widen_instr;
|
||||
bit is_widening_instr;
|
||||
bit is_narrowing_instr;
|
||||
bit is_quad_widening_instr;
|
||||
bit is_convert_instr;
|
||||
va_variant_t allowed_va_variants[$];
|
||||
|
||||
|
@ -38,34 +44,132 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Handle different LMUL setting
|
||||
// The destination vector register group cannot overlap a source vector
|
||||
// register group of a different element width
|
||||
constraint widen_instr_c {
|
||||
int'(vd) % 2 == 0;
|
||||
if (has_vs1) {
|
||||
vs1 != vd;
|
||||
vs1 != vd + 1;
|
||||
}
|
||||
if (has_vs2) {
|
||||
vs2 != vd;
|
||||
vs2 != vd + 1;
|
||||
// Section 3.3.2: Vector Register Grouping (vlmul)
|
||||
// Instructions specifying a vector operand with an odd-numbered vector register will raisean
|
||||
// illegal instruction exception.
|
||||
// TODO: Exclude the instruction that ignore VLMUL
|
||||
constraint operand_group_c {
|
||||
if (m_cfg.vector_cfg.vtype.vlmul > 0) {
|
||||
vd % m_cfg.vector_cfg.vtype.vlmul == 0;
|
||||
vs1 % m_cfg.vector_cfg.vtype.vlmul == 0;
|
||||
vs2 % m_cfg.vector_cfg.vtype.vlmul == 0;
|
||||
vs3 % m_cfg.vector_cfg.vtype.vlmul == 0;
|
||||
}
|
||||
}
|
||||
|
||||
// rs2 is double-width source register
|
||||
// The destination vector register group cannot overlap the rst source
|
||||
// vector register group (specied by vs2)
|
||||
// Section 11.2: Widening Vector Arithmetic Instructions
|
||||
constraint widening_instr_c {
|
||||
if (is_widening_instr) {
|
||||
// The destination vector register group results are arranged as if both
|
||||
// SEW and LMUL were at twice their current settings.
|
||||
vd % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
|
||||
// The destination vector register group cannot overlap a source vector
|
||||
// register group of a different element width (including the mask register if masked)
|
||||
!(vs1 inside {[vd : vd + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
|
||||
!(vs2 inside {[vd : vd + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
|
||||
(vm == 0) -> (vd != 0);
|
||||
// Double-width result, first source double-width, second source single-width
|
||||
if (va_variant inside {WV, WX}) {
|
||||
vs2 % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Section 11.3: Narrowing Vector Arithmetic Instructions
|
||||
constraint narrowing_instr_c {
|
||||
if (has_vs2) {
|
||||
int'(vs2) % 2 == 0;
|
||||
vd != vs2;
|
||||
vd != vs2 + 1;
|
||||
if (is_narrowing_instr) {
|
||||
// The source and destination vector register numbers must be aligned
|
||||
// appropriately for the vector registergroup size
|
||||
vs2 % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
|
||||
// The destination vector register group cannot overlap the rst source
|
||||
// vector register group (specied by vs2)
|
||||
!(vd inside {[vs2 : vs2 + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
|
||||
// The destination vector register group cannot overlap the mask register
|
||||
// if used, unless LMUL=1 (implemented in vmask_overlap_c)
|
||||
}
|
||||
}
|
||||
|
||||
// 12.3. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
|
||||
constraint add_sub_with_carry_c {
|
||||
if (m_cfg.vector_cfg.vtype.vlmul > 1) {
|
||||
// For vadc and vsbc, an illegal instruction exception is raised if the
|
||||
// destination vector register is v0 and LMUL> 1
|
||||
if (instr_name inside {VADC, VSBC}) {
|
||||
vd != 0;
|
||||
}
|
||||
// For vmadc and vmsbc, an illegal instruction exception is raised if the
|
||||
// destination vector register overlaps asource vector register group and LMUL > 1
|
||||
if (instr_name inside {VMADC, VMSBC}) {
|
||||
vd != vs2;
|
||||
vd != vs1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 12.7. Vector Integer Comparison Instructions
|
||||
// For all comparison instructions, an illegal instruction exception is raised if the
|
||||
// destination vector register overlaps a source vector register group and LMUL > 1
|
||||
constraint compare_instr_c {
|
||||
if (category == COMPARE) {
|
||||
vd != vs2;
|
||||
vd != vs1;
|
||||
}
|
||||
}
|
||||
|
||||
// 16.8. Vector Iota Instruction
|
||||
// An illegal instruction exception is raised if the destination vector register group
|
||||
// overlaps the source vector mask register. If the instruction is masked, an illegal
|
||||
// instruction exception is issued if the destination vector register group overlaps v0.
|
||||
constraint vector_itoa_c {
|
||||
if (instr_name == VIOTA_M) {
|
||||
vd != vs2;
|
||||
(vm == 0) -> (vd != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 16.9. Vector Element Index Instruction
|
||||
// The vs2 eld of the instruction must be set to v0, otherwise the encoding is reserved
|
||||
constraint vector_element_index_c {
|
||||
if (instr_name == VID_V) {
|
||||
vs2 == 0;
|
||||
// TODO; Check if this constraint is needed
|
||||
vd != vs2;
|
||||
}
|
||||
}
|
||||
|
||||
// Section 17.3 Vector Slide Instructions
|
||||
// The destination vector register group for vslideup cannot overlap the vector register
|
||||
// group of the source vector register group or the mask register
|
||||
constraint vector_slide_c {
|
||||
if (instr_name inside {VSLIDEUP, VSLIDE1UP, VSLIDEDOWN, VSLIDE1DOWN}) {
|
||||
vd != vs2;
|
||||
vd != vs1;
|
||||
(vm == 0) -> (vd != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Section 17.4: Vector Register Gather Instruction
|
||||
// For any vrgather instruction, the destination vector register group cannot overlap
|
||||
// with the source vector register group
|
||||
constraint vector_gather_c {
|
||||
if (instr_name == VRGATHER) {
|
||||
vd != vs2;
|
||||
vd != vs1;
|
||||
(vm == 0) -> (vd != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Section 17.5: Vector compress instruction
|
||||
// The destination vector register group cannot overlap the source vector register
|
||||
// group or the source vector mask register
|
||||
constraint vector_compress_c {
|
||||
if (instr_name == VCOMPRESS) {
|
||||
vd != vs2;
|
||||
vd != vs1;
|
||||
(vm == 0) -> (vd != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// The source and destination vector register numbers must be aligned
|
||||
// appropriately for the vector registergroup size
|
||||
constraint vmv_alignment_c {
|
||||
if (instr_name == VMV2R_V) {
|
||||
int'(vs2) % 2 == 0;
|
||||
|
@ -81,9 +185,86 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
}
|
||||
}
|
||||
|
||||
/////////////////// Vector mask constraint ///////////////////
|
||||
|
||||
// Section 5.3
|
||||
// The destination vector register group for a masked vector instruction can only overlap
|
||||
// the source mask register (v0) when LMUL=1
|
||||
constraint vmask_overlap_c {
|
||||
(vm == 0) && (m_cfg.vector_cfg.vtype.vlmul > 1) -> (vd != 0);
|
||||
}
|
||||
|
||||
constraint vector_mask_enable_c {
|
||||
// Below instruction is always masked
|
||||
if (instr_name inside {VMERGE, VFMERGE, VADC, VSBC}) {
|
||||
vm == 1'b0;
|
||||
}
|
||||
}
|
||||
|
||||
constraint vector_mask_disable_c {
|
||||
// (vm=0) is reserved for below ops
|
||||
if (instr_name inside {VMV, VFMV, VCOMPRESS, VFMV_F_S, VFMV_S_F, VMV_X_S, VMV_S_X,
|
||||
VMV1R_V, VMV2R_V, VMV4R_V, VMV8R_V}) {
|
||||
vm == 1'b1;
|
||||
}
|
||||
}
|
||||
|
||||
// 16.1. Vector Mask-Register Logical Instructions
|
||||
// No vector mask for these instructions
|
||||
constraint vector_mask_instr_c {
|
||||
if (instr_name inside {[VMAND_MM : VMXNOR_MM]}) {
|
||||
vm == 1'b1;
|
||||
}
|
||||
}
|
||||
|
||||
constraint disable_floating_point_varaint_c {
|
||||
if (!m_cfg.vector_cfg.vec_fp) {
|
||||
va_variant != VF;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Check why this is needed?
|
||||
constraint vector_load_store_mask_overlap_c {
|
||||
if (category == STORE) {
|
||||
(vm == 0) -> (vs3 != 0);
|
||||
}
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_vector_instr)
|
||||
`uvm_object_new
|
||||
|
||||
// Filter unsupported instructions based on configuration
|
||||
virtual function bit is_supported(riscv_instr_gen_config cfg);
|
||||
string name = instr_name.name();
|
||||
// 19.2.2. Vector Add with Carry/Subtract with Borrow Reserved under EDIV>1
|
||||
if ((cfg.vector_cfg.vtype.vediv > 1) &&
|
||||
(instr_name inside {VADC, VSBC, VMADC, VMSBC})) begin
|
||||
return 1'b0;
|
||||
end
|
||||
// Disable widening/narrowing instruction when LMUL == 8
|
||||
if ((!cfg.vector_cfg.vec_narrowing_widening) &&
|
||||
(is_widening_instr || is_narrowing_instr)) begin
|
||||
return 1'b0;
|
||||
end
|
||||
if (!cfg.vector_cfg.vec_quad_widening && is_quad_widening_instr) begin
|
||||
return 1'b0;
|
||||
end
|
||||
// TODO: Clean up this list, it's causing gcc compile error now
|
||||
if (instr_name inside {VWMACCSU, VMERGE, VFMERGE, VMADC, VMSBC}) begin
|
||||
return 1'b0;
|
||||
end
|
||||
// The standard vector floating-point instructions treat 16-bit, 32-bit, 64-bit,
|
||||
// and 128-bit elements as IEEE-754/2008-compatible values. If the current SEW does
|
||||
// not correspond to a supported IEEE floating-pointtype, an illegal instruction
|
||||
// exception is raised
|
||||
if (!cfg.vector_cfg.vec_fp) begin
|
||||
if ((name.substr(0, 1) == "VF") || (name.substr(0, 2) == "VMF")) begin
|
||||
return 1'b0;
|
||||
end
|
||||
end
|
||||
return 1'b1;
|
||||
endfunction
|
||||
|
||||
// Convert the instruction to assembly code
|
||||
virtual function string convert2asm(string prefix = "");
|
||||
string asm_str;
|
||||
|
@ -148,17 +329,32 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
end
|
||||
endcase
|
||||
end
|
||||
if (instr_name inside {VMADC, VADC, VSBC, VMSBC, VMERGE, VFMERGE}) begin
|
||||
if (va_variant inside {VVM, VIM, VXM, VFM}) begin
|
||||
asm_str = {asm_str, ",v0"};
|
||||
end
|
||||
end else begin
|
||||
//asm_str = {asm_str, ",v0.t"};
|
||||
end
|
||||
end
|
||||
end
|
||||
default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
|
||||
VL_FORMAT: begin
|
||||
asm_str = $sformatf("%0s %s,(%s)", get_instr_name(), vd.name(), rs1.name());
|
||||
end
|
||||
VS_FORMAT: begin
|
||||
asm_str = $sformatf("%0s %s,(%s)", get_instr_name(), vs3.name(), rs1.name());
|
||||
end
|
||||
VLS_FORMAT: begin
|
||||
asm_str = $sformatf("%0s %0s,(%0s),%0s", get_instr_name(), vd.name(), rs1.name(), rs2.name());
|
||||
end
|
||||
VSS_FORMAT: begin
|
||||
asm_str = $sformatf("%0s %0s,(%0s),%0s", get_instr_name(), vs3.name(), rs1.name(), rs2.name());
|
||||
end
|
||||
VLV_FORMAT: begin
|
||||
asm_str = $sformatf("%0s,%0s,(%0s),%0s", get_instr_name(), vd.name(), rs1.name(), vs2.name());
|
||||
end
|
||||
VSV_FORMAT: begin
|
||||
asm_str = $sformatf("%0s,%0s,(%0s),%0s", get_instr_name(), vs3.name(), rs1.name(), vs2.name());
|
||||
end
|
||||
default: begin
|
||||
`uvm_fatal(`gfn, $sformatf("Unsupported format %0s", format.name()))
|
||||
end
|
||||
endcase
|
||||
// Add vector mask
|
||||
asm_str = {asm_str, vec_vm_str()};
|
||||
if(comment != "") begin
|
||||
asm_str = {asm_str, " #",comment};
|
||||
end
|
||||
|
@ -183,10 +379,14 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
has_fs3 = 0;
|
||||
has_fd = 0;
|
||||
has_imm = 0;
|
||||
if (name.substr(0, 1) == "VW") begin
|
||||
is_widen_instr = 1'b1;
|
||||
if ((name.substr(0, 1) == "VW") || (name.substr(0, 2) == "VFW")) begin
|
||||
is_widening_instr = 1'b1;
|
||||
end
|
||||
if (name.substr(0, 1) == "VN") begin
|
||||
if (name.substr(0, 2) == "VQW") begin
|
||||
is_quad_widening_instr = 1'b1;
|
||||
is_widening_instr = 1'b1;
|
||||
end
|
||||
if ((name.substr(0, 1) == "VN") || (name.substr(0, 2) == "VFN")) begin
|
||||
is_narrowing_instr = 1'b1;
|
||||
end
|
||||
if (uvm_is_match("*CVT*", name)) begin
|
||||
|
@ -204,4 +404,16 @@ class riscv_vector_instr extends riscv_floating_point_instr;
|
|||
end
|
||||
endfunction : set_rand_mode
|
||||
|
||||
virtual function string vec_vm_str();
|
||||
if (vm) begin
|
||||
return "";
|
||||
end else begin
|
||||
if (instr_name inside {VMERGE, VFMERGE, VADC, VSBC, VMADC, VMSBC}) begin
|
||||
return ",v0";
|
||||
end else begin
|
||||
return ",v0.t";
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass : riscv_vector_instr
|
||||
|
|
381
vendor/google_riscv-dv/src/isa/rv32v_instr.sv
vendored
381
vendor/google_riscv-dv/src/isa/rv32v_instr.sv
vendored
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,185 +16,237 @@
|
|||
*/
|
||||
|
||||
// Vector CSR access instruction
|
||||
`DEFINE_INSTR(VSETVLI, VSET_FORMAT, CSR, RV32V)
|
||||
`DEFINE_INSTR(VSETVL, VSET_FORMAT, CSR, RV32V)
|
||||
`DEFINE_INSTR(VSETVLI, VSET_FORMAT, CSR, RVV)
|
||||
`DEFINE_INSTR(VSETVL, VSET_FORMAT, CSR, RVV)
|
||||
|
||||
// Vector integer arithmetic instruction
|
||||
`DEFINE_VA_INSTR(VADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VRSUB, VA_FORMAT, ARITHMETIC, RV32V, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VWADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWSUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VADC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM})
|
||||
`DEFINE_VA_INSTR(VMADC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM, VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSBC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM})
|
||||
`DEFINE_VA_INSTR(VMSBC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VV, VX})
|
||||
`DEFINE_VA_INSTR(VAND, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VOR, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VXOR, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSLL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSRL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSRA, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VNSRL, VA_FORMAT, SHIFT, RV32V, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VNSRA, VA_FORMAT, SHIFT, RV32V, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VMSEQ, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSNE, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSLTU, VA_FORMAT, COMPARE, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMSLT, VA_FORMAT, COMPARE, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMSLEU, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSLE, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSGTU, VA_FORMAT, COMPARE, RV32V, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSGT, VA_FORMAT, COMPARE, RV32V, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VMINU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMIN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMAXU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMAX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULH, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULHU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULHSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VDIVU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VDIV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VREMU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VREM, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMULU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMULSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VNMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCUS, VA_FORMAT, ARITHMETIC, RV32V, {VX})
|
||||
/*
|
||||
`DEFINE_VA_INSTR(VQMACCU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACCSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACCUS, VA_FORMAT, ARITHMETIC, RV32V, {VX})
|
||||
`DEFINE_VA_INSTR(VADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VRSUB, VA_FORMAT, ARITHMETIC, RVV, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VWADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWSUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VWSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
|
||||
`DEFINE_VA_INSTR(VADC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM})
|
||||
`DEFINE_VA_INSTR(VMADC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM, VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSBC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM})
|
||||
`DEFINE_VA_INSTR(VMSBC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VV, VX})
|
||||
`DEFINE_VA_INSTR(VAND, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VOR, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VXOR, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSLL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSRL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSRA, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VNSRL, VA_FORMAT, SHIFT, RVV, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VNSRA, VA_FORMAT, SHIFT, RVV, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VMSEQ, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSNE, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSLTU, VA_FORMAT, COMPARE, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMSLT, VA_FORMAT, COMPARE, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMSLEU, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSLE, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSGTU, VA_FORMAT, COMPARE, RVV, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VMSGT, VA_FORMAT, COMPARE, RVV, {VX, VI})
|
||||
`DEFINE_VA_INSTR(VMINU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMIN, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMAXU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMAX, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULH, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULHU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMULHSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VDIVU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VDIV, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VREMU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VREM, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMULU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMULSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VNMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VWMACCUS, VA_FORMAT, ARITHMETIC, RVV, {VX})
|
||||
/* Quad widening is not yet supported
|
||||
`DEFINE_VA_INSTR(VQMACCU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACCSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VQMACCUS, VA_FORMAT, ARITHMETIC, RVV, {VX})
|
||||
*/
|
||||
`DEFINE_VA_INSTR(VMERGE, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM})
|
||||
`DEFINE_VA_INSTR(VMV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VMERGE, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM})
|
||||
`DEFINE_VA_INSTR(VMV, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
|
||||
// Vector Fixed-Point Arithmetic Instructions
|
||||
`DEFINE_VA_INSTR(VSADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSSUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VSSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VAADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VAADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VASUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VASUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VSSRL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSSRA, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VNCLIPU, VA_FORMAT, ARITHMETIC, RV32V, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VNCLIP, VA_FORMAT, ARITHMETIC, RV32V, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VSADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSSUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VSSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VAADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VAADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VASUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VASUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
|
||||
`DEFINE_VA_INSTR(VSSRL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VSSRA, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
|
||||
`DEFINE_VA_INSTR(VNCLIPU, VA_FORMAT, ARITHMETIC, RVV, {WV, WX, WI})
|
||||
`DEFINE_VA_INSTR(VNCLIP, VA_FORMAT, ARITHMETIC, RVV, {WV, WX, WI})
|
||||
|
||||
// Vector Floating-Point Instructions
|
||||
`DEFINE_VA_INSTR(VFADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFRSUB, VA_FORMAT, ARITHMETIC, RV32V, {VF})
|
||||
`DEFINE_VA_INSTR(VFMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFDIV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFRDIV, VA_FORMAT, ARITHMETIC, RV32V, {VF})
|
||||
`DEFINE_VA_INSTR(VFWMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWNMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSQRT_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFMIN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMAX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJ, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFEQ, VA_FORMAT, COMPARE, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFNE, VA_FORMAT, COMPARE, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFLT, VA_FORMAT, COMPARE, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFLE, VA_FORMAT, COMPARE, RV32V, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFGT, VA_FORMAT, COMPARE, RV32V, {VF})
|
||||
`DEFINE_VA_INSTR(VMFGE, VA_FORMAT, COMPARE, RV32V, {VF})
|
||||
`DEFINE_VA_INSTR(VFCLASS_V,VS2_FORMAT, COMPARE, RV32V)
|
||||
`DEFINE_VA_INSTR(VFMERGE, VA_FORMAT, ARITHMETIC, RV32V, {VFM})
|
||||
`DEFINE_VA_INSTR(VFMV, VA_FORMAT, ARITHMETIC, RV32V, {VF})
|
||||
`DEFINE_VA_INSTR(VFADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFRSUB, VA_FORMAT, ARITHMETIC, RVV, {VF})
|
||||
`DEFINE_VA_INSTR(VFMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFDIV, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFRDIV, VA_FORMAT, ARITHMETIC, RVV, {VF})
|
||||
`DEFINE_VA_INSTR(VFWMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFNMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWNMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFWNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSQRT_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFMIN, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFMAX, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJ, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJN, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VFSGNJX, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFEQ, VA_FORMAT, COMPARE, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFNE, VA_FORMAT, COMPARE, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFLT, VA_FORMAT, COMPARE, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFLE, VA_FORMAT, COMPARE, RVV, {VV, VF})
|
||||
`DEFINE_VA_INSTR(VMFGT, VA_FORMAT, COMPARE, RVV, {VF})
|
||||
`DEFINE_VA_INSTR(VMFGE, VA_FORMAT, COMPARE, RVV, {VF})
|
||||
`DEFINE_VA_INSTR(VFCLASS_V,VS2_FORMAT, COMPARE, RVV)
|
||||
`DEFINE_VA_INSTR(VFMERGE, VA_FORMAT, ARITHMETIC, RVV, {VFM})
|
||||
`DEFINE_VA_INSTR(VFMV, VA_FORMAT, ARITHMETIC, RVV, {VF})
|
||||
|
||||
// Vector conversion instructions
|
||||
`DEFINE_VA_INSTR(VFCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_XU_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_X_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_XU_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_X_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFNCVT_ROD_F_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWCVT_F_F_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_XU_F_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_X_F_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_XU_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_X_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_F_F_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFNCVT_ROD_F_F_W, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
// Vector reduction instruction
|
||||
`DEFINE_VA_INSTR(VREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDMAXU_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDMAX_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDMINU_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDMIN_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDAND_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDOR_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDXOR_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VWREDSUMU_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VWREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFREDOSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFREDMAX_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWREDOSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFWREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDMAXU_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDMAX_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDMINU_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDMIN_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDAND_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDOR_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VREDXOR_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VWREDSUMU_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VWREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFREDOSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFREDMAX_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWREDOSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFWREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
// Vector mask instruction
|
||||
`DEFINE_VA_INSTR(VMAND_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMNAND_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMANDNOT_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMXOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMNOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMORNOT_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMXNOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMAND_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMNAND_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMANDNOT_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMXOR_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMOR_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMNOR_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMORNOT_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMXNOR_MM, VA_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
`DEFINE_VA_INSTR(VPOPC_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFIRST_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMSBF_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMSIF_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMSOF_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VIOTA_M, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VID_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VPOPC_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFIRST_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMSBF_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMSIF_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMSOF_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VIOTA_M, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VID_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
// Vector permutation instruction
|
||||
`DEFINE_VA_INSTR(VMV_X_S, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV_S_X, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFMV_F_S, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VFMV_S_F, VA_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV_X_S, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMV_S_X, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFMV_F_S, VA_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VFMV_S_F, VA_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
`DEFINE_VA_INSTR(VSLIDEUP, VA_FORMAT, ARITHMETIC, RV32V, {VI,VX})
|
||||
`DEFINE_VA_INSTR(VSLIDEDOWN, VA_FORMAT, ARITHMETIC, RV32V, {VI,VX})
|
||||
`DEFINE_VA_INSTR(VSLIDE1UP, VA_FORMAT, ARITHMETIC, RV32V, {VX})
|
||||
`DEFINE_VA_INSTR(VSLIDE1DOWN, VA_FORMAT, ARITHMETIC, RV32V, {VX})
|
||||
`DEFINE_VA_INSTR(VRGATHER, VA_FORMAT, ARITHMETIC, RV32V, {VV,VX,VI})
|
||||
`DEFINE_VA_INSTR(VCOMPRESS, VA_FORMAT, ARITHMETIC, RV32V, {VM})
|
||||
`DEFINE_VA_INSTR(VSLIDEUP, VA_FORMAT, ARITHMETIC, RVV, {VI,VX})
|
||||
`DEFINE_VA_INSTR(VSLIDEDOWN, VA_FORMAT, ARITHMETIC, RVV, {VI,VX})
|
||||
`DEFINE_VA_INSTR(VSLIDE1UP, VA_FORMAT, ARITHMETIC, RVV, {VX})
|
||||
`DEFINE_VA_INSTR(VSLIDE1DOWN, VA_FORMAT, ARITHMETIC, RVV, {VX})
|
||||
`DEFINE_VA_INSTR(VRGATHER, VA_FORMAT, ARITHMETIC, RVV, {VV,VX,VI})
|
||||
`DEFINE_VA_INSTR(VCOMPRESS, VA_FORMAT, ARITHMETIC, RVV, {VM})
|
||||
|
||||
`DEFINE_VA_INSTR(VMV1R_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV2R_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV4R_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV8R_V, VS2_FORMAT, ARITHMETIC, RV32V)
|
||||
`DEFINE_VA_INSTR(VMV1R_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMV2R_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMV4R_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
`DEFINE_VA_INSTR(VMV8R_V, VS2_FORMAT, ARITHMETIC, RVV)
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Section 7. Vector Loads and Stores
|
||||
// -------------------------------------------------------------------------
|
||||
// Section 7.4 - Vector Unit-Stride Instructions
|
||||
`DEFINE_VA_INSTR(VLE_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSE_V, VS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VLB_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSB_V, VS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VLH_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSH_V, VS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VLW_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSW_V, VS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VLBU_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLHU_V, VS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLWU_V, VL_FORMAT, LOAD, RVV)
|
||||
// Section 7.5 - Vector Strided Instructions
|
||||
`DEFINE_VA_INSTR(VLSB_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSH_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSW_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSBU_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSHU_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSWU_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLSE_V, VLS_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSSB_V, VSS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSSH_V, VSS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSSW_V, VSS_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSSE_V, VSS_FORMAT, STORE, RVV)
|
||||
// Section 7.6 - Vector Indexed Instructions
|
||||
`DEFINE_VA_INSTR(VLXB_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXH_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXW_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXBU_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXHU_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXWU_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLXE_V, VLV_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VSXB_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSXH_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSXW_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSXE_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSUXB_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSUXH_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSUXW_V, VSV_FORMAT, STORE, RVV)
|
||||
`DEFINE_VA_INSTR(VSUXE_V, VSV_FORMAT, STORE, RVV)
|
||||
// Section 7.7 - Vector Unit-Stride Fault-Only-First Loads
|
||||
`DEFINE_VA_INSTR(VLBFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLHFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLWFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLBUFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLHUFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLWUFF_V, VL_FORMAT, LOAD, RVV)
|
||||
`DEFINE_VA_INSTR(VLEFF_V, VL_FORMAT, LOAD, RVV)
|
||||
|
|
181
vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
vendored
181
vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
vendored
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -78,7 +79,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
gen_init_section(hart);
|
||||
// If PMP is supported, we want to generate the associated trap handlers and the test_done
|
||||
// section at the start of the program so we can allow access through the pmpcfg0 CSR
|
||||
if (support_pmp && !cfg.bare_program_mode) begin
|
||||
if (riscv_instr_pkg::support_pmp && !cfg.bare_program_mode) begin
|
||||
gen_trap_handlers(hart);
|
||||
// Ecall handler
|
||||
gen_ecall_handler(hart);
|
||||
|
@ -119,7 +120,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
instr_stream = {instr_stream, $sformatf("%sj test_done", indent)};
|
||||
// Test done section
|
||||
// If PMP isn't supported, generate this in the normal location
|
||||
if (hart == 0 & !support_pmp) begin
|
||||
if (hart == 0 & !riscv_instr_pkg::support_pmp) begin
|
||||
gen_test_done();
|
||||
end
|
||||
// Shuffle the sub programs and insert to the instruction stream
|
||||
|
@ -320,7 +321,8 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
if (cfg.disable_compressed_instr) begin
|
||||
instr_stream.push_back(".option norvc;");
|
||||
end
|
||||
str = {"csrr x5, mhartid"};
|
||||
str.push_back(".include \"user_init.s\"");
|
||||
str.push_back("csrr x5, mhartid");
|
||||
for (int hart = 0; hart < cfg.num_of_harts; hart++) begin
|
||||
str = {str, $sformatf("li x6, %0d", hart),
|
||||
$sformatf("beq x5, x6, %0df", hart)};
|
||||
|
@ -411,19 +413,19 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
string str;
|
||||
str = format_string(get_label("init:", hart), LABEL_STR_LEN);
|
||||
instr_stream.push_back(str);
|
||||
if (cfg.enable_floating_point) begin
|
||||
init_floating_point_gpr();
|
||||
end
|
||||
init_gpr();
|
||||
// Init stack pointer to point to the end of the user stack
|
||||
str = {indent, $sformatf("la x%0d, %0suser_stack_end", cfg.sp, hart_prefix(hart))};
|
||||
instr_stream.push_back(str);
|
||||
if (cfg.enable_floating_point) begin
|
||||
init_floating_point_gpr();
|
||||
end
|
||||
if (cfg.enable_vector_extension) begin
|
||||
init_vector_engine();
|
||||
randomize_vec_gpr_and_csr();
|
||||
end
|
||||
core_is_initialized();
|
||||
gen_dummy_csr_write(); // TODO add a way to disable xStatus read
|
||||
if (support_pmp) begin
|
||||
if (riscv_instr_pkg::support_pmp) begin
|
||||
str = {indent, "j main"};
|
||||
instr_stream.push_back(str);
|
||||
end
|
||||
|
@ -446,7 +448,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
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;
|
||||
RVV : misa[MISA_EXT_V] = 1'b1;
|
||||
RV32X, RV64X : misa[MISA_EXT_X] = 1'b1;
|
||||
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported",
|
||||
supported_isa[i].name()))
|
||||
|
@ -515,7 +517,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
string str;
|
||||
bit [DATA_WIDTH-1:0] reg_val;
|
||||
// Init general purpose registers with random values
|
||||
for(int i = 0; i < 32; i++) begin
|
||||
for(int i = 0; i < NUM_GPR; i++) begin
|
||||
if (i inside {cfg.sp, cfg.tp}) continue;
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(reg_val,
|
||||
reg_val dist {
|
||||
|
@ -530,38 +532,132 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
end
|
||||
endfunction
|
||||
|
||||
// Initialize vector general purpose registers
|
||||
virtual function void init_vec_gpr();
|
||||
int SEW;
|
||||
int LMUL;
|
||||
int EDIV = 1;
|
||||
int len = (ELEN <= XLEN) ? ELEN : XLEN;
|
||||
int num_elements = VLEN / len;
|
||||
if (!(RVV inside {supported_isa})) return;
|
||||
LMUL = 1;
|
||||
SEW = (ELEN <= XLEN) ? ELEN : XLEN;
|
||||
instr_stream.push_back($sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl));
|
||||
// vec registers will be loaded from a scalar GPR, one element at a time
|
||||
instr_stream.push_back($sformatf("%svsetvli x%0d, x%0d, e%0d, m%0d, d%0d",
|
||||
indent, cfg.gpr[0], cfg.gpr[1], SEW, LMUL, EDIV));
|
||||
instr_stream.push_back("vec_reg_init:");
|
||||
for (int v = 1; v < NUM_VEC_GPR; v++) begin
|
||||
for (int e = 0; e < num_elements; e++) begin
|
||||
if (e > 0) instr_stream.push_back($sformatf("%0svmv.v.v v0, v%0d", indent, v));
|
||||
instr_stream.push_back($sformatf("%0sli x%0d, 0x%0x",
|
||||
indent, cfg.gpr[0], $urandom_range(0, 2 ** SEW - 1)));
|
||||
instr_stream.push_back($sformatf("%0svslide1up.vx v%0d, v0, t0", indent, v));
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Initialize floating point general purpose registers
|
||||
virtual function void init_floating_point_gpr();
|
||||
int int_gpr;
|
||||
string str;
|
||||
// TODO: Initialize floating point GPR with more interesting numbers
|
||||
for(int i = 0; i < 32; i++) begin
|
||||
int_gpr = $urandom_range(0, 31);
|
||||
// Use a random integer GPR to initialize floating point GPR
|
||||
if (RV64F inside {supported_isa}) begin
|
||||
str = $sformatf("%0sfcvt.d.l f%0d, x%0d", indent, i, int_gpr);
|
||||
end else begin
|
||||
str = $sformatf("%0sfcvt.s.w f%0d, x%0d", indent, i, int_gpr);
|
||||
end
|
||||
instr_stream.push_back(str);
|
||||
for(int i = 0; i < NUM_FLOAT_GPR; i++) begin
|
||||
randcase
|
||||
1: init_floating_point_gpr_with_spf(i);
|
||||
RV64D inside {supported_isa}: init_floating_point_gpr_with_dpf(i);
|
||||
endcase
|
||||
end
|
||||
// Initialize rounding mode of FCSR
|
||||
str = $sformatf("%0sfsrmi %0d", indent, cfg.fcsr_rm);
|
||||
instr_stream.push_back(str);
|
||||
endfunction
|
||||
|
||||
// Initialize vector registers
|
||||
virtual function void init_vector_engine();
|
||||
string str[$];
|
||||
// Initialize vtype, vl
|
||||
str = {str, $sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl),
|
||||
$sformatf("vsetvli x%0d, x%0d, e%0d",
|
||||
cfg.gpr[0], cfg.gpr[1], 8 * (2 ** cfg.vector_cfg.vtype.vsew))};
|
||||
for(int i = 0; i < 32; i++) begin
|
||||
// Use integer register to initialize vector register
|
||||
str = {str, $sformatf("vmv.v.x v%0d, x%0d", i, i)};
|
||||
// get instructions initialize floating_point_gpr with single precision floating value
|
||||
virtual function void init_floating_point_gpr_with_spf(int int_floating_gpr);
|
||||
string str;
|
||||
bit [31:0] imm = get_rand_spf_value();
|
||||
int int_gpr = $urandom_range(0, NUM_GPR - 1);
|
||||
|
||||
str = $sformatf("%0sli x%0d, %0d", indent, int_gpr, imm);
|
||||
instr_stream.push_back(str);
|
||||
str = $sformatf("%0sfmv.w.x f%0d, x%0d", indent, int_floating_gpr, int_gpr);
|
||||
instr_stream.push_back(str);
|
||||
endfunction
|
||||
|
||||
// get instructions initialize floating_point_gpr with double precision floating value
|
||||
virtual function void init_floating_point_gpr_with_dpf(int int_floating_gpr);
|
||||
string str;
|
||||
bit [63:0] imm = get_rand_dpf_value();
|
||||
int int_gpr1 = $urandom_range(1, NUM_GPR - 1);
|
||||
int int_gpr2 = $urandom_range(1, NUM_GPR - 1);
|
||||
|
||||
str = $sformatf("%0sli x%0d, %0d", indent, int_gpr1, imm[63:32]);
|
||||
instr_stream.push_back(str);
|
||||
// shift to upper 32bits
|
||||
repeat (2) begin
|
||||
str = $sformatf("%0sslli x%0d, x%0d, 16", indent, int_gpr1, int_gpr1);
|
||||
instr_stream.push_back(str);
|
||||
end
|
||||
instr_stream = {instr_stream, str};
|
||||
str = $sformatf("%0sli x%0d, %0d", indent, int_gpr2, imm[31:0]);
|
||||
instr_stream.push_back(str);
|
||||
str = $sformatf("%0sor x%0d, x%0d, x%0d", indent, int_gpr2, int_gpr2, int_gpr1);
|
||||
instr_stream.push_back(str);
|
||||
str = $sformatf("%0sfmv.d.x f%0d, x%0d", indent, int_floating_gpr, int_gpr2);
|
||||
instr_stream.push_back(str);
|
||||
endfunction
|
||||
|
||||
// get a random single precision floating value
|
||||
virtual function bit [XLEN-1:0] get_rand_spf_value();
|
||||
bit [31:0] value;
|
||||
|
||||
randcase
|
||||
// infinity
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {32'h7f80_0000, 32'hff80_0000};)
|
||||
// largest
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {32'h7f7f_ffff, 32'hff7f_ffff};)
|
||||
// zero
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {32'h0000_0000, 32'h8000_0000};)
|
||||
// NaN
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {32'h7f80_0001, 32'h7fc0_0000};)
|
||||
// normal
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value[30:SINGLE_PRECISION_FRACTION_BITS] > 0;)
|
||||
// subnormal
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value[30:SINGLE_PRECISION_FRACTION_BITS] == 0;)
|
||||
endcase
|
||||
return value;
|
||||
endfunction
|
||||
|
||||
// get a random double precision floating value
|
||||
virtual function bit [XLEN-1:0] get_rand_dpf_value();
|
||||
bit [63:0] value;
|
||||
|
||||
randcase
|
||||
// infinity
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {64'h7ff0_0000_0000_0000, 64'hfff0_0000_0000_0000};)
|
||||
// largest
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {64'h7fef_ffff_ffff_ffff, 64'hffef_ffff_ffff_ffff};)
|
||||
// zero
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {64'h0000_0000_0000_0000, 64'h8000_0000_0000_0000};)
|
||||
// NaN
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value inside {64'h7ff0_0000_0000_0001, 64'h7ff8_0000_0000_0000};)
|
||||
// normal
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value[62:DOUBLE_PRECISION_FRACTION_BITS] > 0;)
|
||||
// subnormal
|
||||
1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
|
||||
value[62:DOUBLE_PRECISION_FRACTION_BITS] == 0;)
|
||||
endcase
|
||||
return value;
|
||||
endfunction
|
||||
|
||||
// Generate "test_done" section, test is finished by an ECALL instruction
|
||||
|
@ -795,7 +891,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
virtual function void gen_all_trap_handler(int hart);
|
||||
string instr[$];
|
||||
// If PMP isn't supported, generate the relevant trap handler sections as per usual
|
||||
if (!support_pmp) begin
|
||||
if (!riscv_instr_pkg::support_pmp) begin
|
||||
gen_trap_handlers(hart);
|
||||
// Ecall handler
|
||||
gen_ecall_handler(hart);
|
||||
|
@ -1450,4 +1546,25 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
instr_stream = {instr_stream, debug_rom.instr_stream};
|
||||
endfunction
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Vector extension generation
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
virtual function void randomize_vec_gpr_and_csr();
|
||||
if (!(RVV inside {supported_isa})) return;
|
||||
instr_stream.push_back({indent, $sformatf("li x%0d, %0d", cfg.gpr[0], cfg.vector_cfg.vxsat)});
|
||||
instr_stream.push_back({indent, $sformatf("csrw vxsat, x%0d", cfg.gpr[0])});
|
||||
instr_stream.push_back({indent, $sformatf("li x%0d, %0d", cfg.gpr[0], cfg.vector_cfg.vxrm)});
|
||||
instr_stream.push_back({indent, $sformatf("csrw vxrm, x%0d", cfg.gpr[0])});
|
||||
init_vec_gpr(); // GPR init uses a temporary SEW/LMUL setting before the final value set below.
|
||||
instr_stream.push_back($sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl));
|
||||
instr_stream.push_back($sformatf("%svsetvli x%0d, x%0d, e%0d, m%0d, d%0d",
|
||||
indent,
|
||||
cfg.gpr[0],
|
||||
cfg.gpr[1],
|
||||
cfg.vector_cfg.vtype.vsew,
|
||||
cfg.vector_cfg.vtype.vlmul,
|
||||
cfg.vector_cfg.vtype.vediv));
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
|
@ -192,9 +192,9 @@ class riscv_jump_instr extends riscv_directed_instr_stream;
|
|||
instr_list[i].atomic = 1'b1;
|
||||
end
|
||||
jump.has_label = 1'b1;
|
||||
jump.label = "1";
|
||||
jump.label = $sformatf("%0s_j%0d", label, idx);
|
||||
jump.comment = $sformatf("jump %0s -> %0s", label, target_program_label);
|
||||
branch.imm_str = "1f";
|
||||
branch.imm_str = jump.label;
|
||||
branch.comment = "branch to jump instr";
|
||||
branch.branch_assigned = 1'b1;
|
||||
endfunction
|
||||
|
|
|
@ -228,17 +228,62 @@
|
|||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
|
||||
// TODO, will handle special value later
|
||||
// single-precision floating point special values coverpoint
|
||||
`define FP_SPECIAL_VALUES_CP(VAR, NAME) \
|
||||
cp_fp_special_values_on_``NAME`` : coverpoint VAR { \
|
||||
// single/double precision floating point special values coverpoint
|
||||
`define FP_SPECIAL_VALUES_CP(VAR, NAME, PRECISION = S) \
|
||||
cp_sfp_special_values_on_``NAME`` : coverpoint VAR[31:0] { \
|
||||
option.weight = (`"PRECISION`" == "S"); \
|
||||
type_option.weight = (`"PRECISION`" == "S"); \
|
||||
bins infinity[] = {32'h7f80_0000, 32'hff80_0000}; \
|
||||
bins largest[] = {32'h7f7f_ffff, 32'hff7f_ffff}; \
|
||||
bins zeros[] = {32'h0000_0000, 32'h1000_0000}; \
|
||||
bins NaN[] = {32'h7fc0_0000, 32'h7f80_0000}; \
|
||||
bins zeros[] = {32'h0000_0000, 32'h8000_0000}; \
|
||||
bins NaN[] = {32'h7f80_0001, 32'h7fc0_0000}; \
|
||||
} \
|
||||
cp_sfp_subnormal_on_``NAME`` : coverpoint VAR[30:SINGLE_PRECISION_FRACTION_BITS] == 0 { \
|
||||
option.weight = (`"PRECISION`" == "S"); \
|
||||
type_option.weight = (`"PRECISION`" == "S"); \
|
||||
} \
|
||||
cp_dfp_special_values_on_``NAME`` : coverpoint VAR { \
|
||||
option.weight = (`"PRECISION`" == "D"); \
|
||||
type_option.weight = (`"PRECISION`" == "D"); \
|
||||
bins infinity[] = {64'h7ff0_0000_0000_0000, 64'hfff0_0000_0000_0000}; \
|
||||
bins largest[] = {64'h7fef_ffff_ffff_ffff, 64'hffef_ffff_ffff_ffff}; \
|
||||
bins zeros[] = {64'h0000_0000_0000_0000, 64'h8000_0000_0000_0000}; \
|
||||
bins NaN[] = {64'h7ff0_0000_0000_0001, 64'h7ff8_0000_0000_0000}; \
|
||||
} \
|
||||
cp_dfp_subnormal_on_``NAME`` : coverpoint VAR[62:DOUBLE_PRECISION_FRACTION_BITS-1] == 0 { \
|
||||
option.weight = (`"PRECISION`" == "D"); \
|
||||
type_option.weight = (`"PRECISION`" == "D"); \
|
||||
}
|
||||
|
||||
`define FP_R_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`define FP_LOAD_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
`DV(ignore_bins zero = {ZERO};) \
|
||||
} \
|
||||
cp_fd : coverpoint instr.fd; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
`DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
})
|
||||
|
||||
`define FP_STORE_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
`DV(ignore_bins zero = {ZERO};) \
|
||||
} \
|
||||
cp_fs2 : coverpoint instr.fs2; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}) \
|
||||
`DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
|
||||
})
|
||||
|
||||
`define FP_R_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_fs2 : coverpoint instr.fs2; \
|
||||
|
@ -246,9 +291,12 @@
|
|||
cp_fs1_sign : coverpoint instr.fs1_sign; \
|
||||
cp_fs2_sign : coverpoint instr.fs2_sign; \
|
||||
cp_fd_sign : coverpoint instr.fd_sign; \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
`define FP_R4_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`define FP_R4_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_fs2 : coverpoint instr.fs2; \
|
||||
|
@ -259,14 +307,74 @@
|
|||
cp_fs3_sign : coverpoint instr.fs3_sign; \
|
||||
cp_fd_sign : coverpoint instr.fd_sign; \
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fs3_sign, cp_fd_sign; \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs3_value, fs3_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
`define FSQRT_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`define FSQRT_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_fd : coverpoint instr.fd; \
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign; \
|
||||
cp_fd_sign : coverpoint instr.fd_sign; \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
// FCVT integer to floating
|
||||
`define FP_I2F_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S, SIGN_TYP = SIGN) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_rs1 : coverpoint instr.rs1; \
|
||||
cp_fd : coverpoint instr.fd; \
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign { \
|
||||
option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
} \
|
||||
cp_fd_sign : coverpoint instr.fd_sign { \
|
||||
option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
} \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
// FCVT floating to integer
|
||||
`define FP_F2I_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S, SIGN_TYP = SIGN) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign; \
|
||||
cp_rd_sign : coverpoint instr.rd_sign { \
|
||||
option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
|
||||
} \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
// floating compare instructions
|
||||
`define FP_CMP_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_fs2 : coverpoint instr.fs2; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign; \
|
||||
cp_fs2_sign : coverpoint instr.fs2_sign; \
|
||||
`CP_VALUE_RANGE(compare_result, instr.rd_value, 0, 1) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
`define FCLASS_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
|
||||
cp_fs1 : coverpoint instr.fs1; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign; \
|
||||
cp_rd_value : coverpoint instr.rd_value { \
|
||||
bins values[] = {0, 'b1, 'b10, 'b100, 'b1000, 'b1_0000, 'b10_0000, \
|
||||
'b100_0000, 'b1000_0000, 'b1_0000_0000, 'b10_0000_0000}; \
|
||||
illegal_bins others = default; \
|
||||
} \
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
|
||||
|
||||
`define B_I_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
|
@ -317,7 +425,6 @@
|
|||
class riscv_instr_cover_group;
|
||||
|
||||
riscv_instr_gen_config cfg;
|
||||
riscv_instr cur_instr;
|
||||
riscv_instr pre_instr;
|
||||
riscv_instr_name_t instr_list[$];
|
||||
int unsigned instr_cnt;
|
||||
|
@ -537,72 +644,219 @@ class riscv_instr_cover_group;
|
|||
`CG_END
|
||||
|
||||
// floating instructions
|
||||
`INSTR_CG_BEGIN(flw, riscv_floating_point_instr)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
`DV(ignore_bins zero = {ZERO};)
|
||||
}
|
||||
cp_fd : coverpoint instr.fd;
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
|
||||
`DV(cp_lsu_hazard : coverpoint instr.lsu_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
|
||||
})
|
||||
`FP_LOAD_INSTR_CG_BEGIN(flw)
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(fsw, riscv_floating_point_instr)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
`DV(ignore_bins zero = {ZERO};)
|
||||
}
|
||||
cp_fs2 : coverpoint instr.fs2;
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
|
||||
})
|
||||
`DV(cp_lsu_hazard : coverpoint instr.lsu_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD};
|
||||
})
|
||||
`FP_LOAD_INSTR_CG_BEGIN(fld, D)
|
||||
`CG_END
|
||||
|
||||
`FP_STORE_INSTR_CG_BEGIN(fsw)
|
||||
`CG_END
|
||||
|
||||
`FP_STORE_INSTR_CG_BEGIN(fsd, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fadd_s)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fadd_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsub_s)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsub_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmul_s)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmul_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fdiv_s)
|
||||
cp_div_result: coverpoint instr.div_result;
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fdiv_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FSQRT_INSTR_CG_BEGIN(fsqrt_s)
|
||||
`CG_END
|
||||
|
||||
`FSQRT_INSTR_CG_BEGIN(fsqrt_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmin_s)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmin_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmax_s)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fmax_d, D)
|
||||
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fmadd_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fmadd_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fnmadd_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fnmadd_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fmsub_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fmsub_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fnmsub_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R4_INSTR_CG_BEGIN(fnmsub_d, D)
|
||||
`CG_END
|
||||
|
||||
// FCVT floating to floating
|
||||
`INSTR_CG_BEGIN(fcvt_s_d, riscv_floating_point_instr)
|
||||
cp_fs1 : coverpoint instr.fs1;
|
||||
cp_fd : coverpoint instr.fd;
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign;
|
||||
cp_fd_sign : coverpoint instr.fd_sign;
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, D)
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, S)
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(fcvt_d_s, riscv_floating_point_instr)
|
||||
cp_fs1 : coverpoint instr.fs1;
|
||||
cp_fd : coverpoint instr.fd;
|
||||
cp_fs1_sign : coverpoint instr.fs1_sign;
|
||||
cp_fd_sign : coverpoint instr.fd_sign;
|
||||
`FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, S)
|
||||
`FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, D)
|
||||
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_w_s)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_wu_s, , UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_l_s)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_lu_s, UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_l_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_lu_d, D, UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_w_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fcvt_wu_d, D, UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_s_w)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_s_wu, , UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_s_l)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_d_l, D)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_s_lu, , UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_d_w, D)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_d_lu, D, UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fcvt_d_wu, D, UNSIGN)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnj_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnj_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnjn_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnjn_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnjx_s)
|
||||
`CG_END
|
||||
|
||||
`FP_R_INSTR_CG_BEGIN(fsgnjx_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fmv_x_w)
|
||||
`CG_END
|
||||
|
||||
`FP_F2I_INSTR_CG_BEGIN(fmv_x_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fmv_w_x)
|
||||
`CG_END
|
||||
|
||||
`FP_I2F_INSTR_CG_BEGIN(fmv_d_x, D)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(feq_s)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(feq_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(flt_s)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(flt_d, D)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(fle_s)
|
||||
`CG_END
|
||||
|
||||
`FP_CMP_INSTR_CG_BEGIN(fle_d, D)
|
||||
`CG_END
|
||||
|
||||
`FCLASS_INSTR_CG_BEGIN(fclass_s)
|
||||
`CG_END
|
||||
|
||||
`FCLASS_INSTR_CG_BEGIN(fclass_d, D)
|
||||
`CG_END
|
||||
|
||||
// B extension
|
||||
// Count Leading/Trailing Zeros (clz, ctz)
|
||||
`B_R_INSTR_NO_RS2_CG_BEGIN(clz)
|
||||
|
@ -1462,8 +1716,6 @@ class riscv_instr_cover_group;
|
|||
function new(riscv_instr_gen_config cfg);
|
||||
string opts;
|
||||
this.cfg = cfg;
|
||||
cur_instr = riscv_instr::type_id::create("cur_instr");
|
||||
pre_instr = riscv_instr::type_id::create("pre_instr");
|
||||
build_instr_list();
|
||||
`ifdef COMPLIANCE_MODE
|
||||
compliance_mode = 1;
|
||||
|
@ -1659,6 +1911,64 @@ class riscv_instr_cover_group;
|
|||
fnmadd_s_cg = new();
|
||||
fmsub_s_cg = new();
|
||||
fnmsub_s_cg = new();
|
||||
fcvt_w_s_cg = new();
|
||||
fcvt_wu_s_cg = new();
|
||||
fcvt_s_w_cg = new();
|
||||
fcvt_s_wu_cg = new();
|
||||
fsgnj_s_cg = new();
|
||||
fsgnjn_s_cg = new();
|
||||
fsgnjx_s_cg = new();
|
||||
fmv_x_w_cg = new();
|
||||
fmv_w_x_cg = new();
|
||||
feq_s_cg = new();
|
||||
flt_s_cg = new();
|
||||
fle_s_cg = new();
|
||||
fclass_s_cg = new();
|
||||
`CG_SELECTOR_END
|
||||
|
||||
`CG_SELECTOR_BEGIN(RV32D)
|
||||
fld_cg = new();
|
||||
fsd_cg = new();
|
||||
fadd_d_cg = new();
|
||||
fsub_d_cg = new();
|
||||
fdiv_d_cg = new();
|
||||
fmul_d_cg = new();
|
||||
fmadd_d_cg = new();
|
||||
fnmadd_d_cg = new();
|
||||
fmsub_d_cg = new();
|
||||
fnmsub_d_cg = new();
|
||||
fsqrt_d_cg = new();
|
||||
fmin_d_cg = new();
|
||||
fmax_d_cg = new();
|
||||
fsgnj_d_cg = new();
|
||||
fsgnjn_d_cg = new();
|
||||
fsgnjx_d_cg = new();
|
||||
feq_d_cg = new();
|
||||
flt_d_cg = new();
|
||||
fle_d_cg = new();
|
||||
fcvt_w_d_cg = new();
|
||||
fcvt_wu_d_cg = new();
|
||||
fcvt_d_w_cg = new();
|
||||
fcvt_d_wu_cg = new();
|
||||
fclass_d_cg = new();
|
||||
`CG_SELECTOR_END
|
||||
|
||||
`CG_SELECTOR_BEGIN(RV64F)
|
||||
fcvt_l_s_cg = new();
|
||||
fcvt_lu_s_cg = new();
|
||||
fcvt_s_l_cg = new();
|
||||
fcvt_s_lu_cg = new();
|
||||
`CG_SELECTOR_END
|
||||
|
||||
`CG_SELECTOR_BEGIN(RV64D)
|
||||
fmv_x_d_cg = new();
|
||||
fmv_d_x_cg = new();
|
||||
fcvt_d_s_cg = new();
|
||||
fcvt_s_d_cg = new();
|
||||
fcvt_l_d_cg = new();
|
||||
fcvt_lu_d_cg = new();
|
||||
fcvt_d_l_cg = new();
|
||||
fcvt_d_lu_cg = new();
|
||||
`CG_SELECTOR_END
|
||||
|
||||
`CG_SELECTOR_BEGIN(RV32B)
|
||||
|
@ -1913,18 +2223,67 @@ class riscv_instr_cover_group;
|
|||
C_ADDW : `SAMPLE(c_addw_cg, instr)
|
||||
C_ADDIW : `SAMPLE(c_addiw_cg, instr)
|
||||
FLW : `SAMPLE_F(flw_cg, instr)
|
||||
FLD : `SAMPLE_F(fld_cg, instr)
|
||||
FSW : `SAMPLE_F(fsw_cg, instr)
|
||||
FSD : `SAMPLE_F(fsd_cg, instr)
|
||||
FADD_S : `SAMPLE_F(fadd_s_cg, instr)
|
||||
FADD_D : `SAMPLE_F(fadd_d_cg, instr)
|
||||
FSUB_S : `SAMPLE_F(fsub_s_cg, instr)
|
||||
FSUB_D : `SAMPLE_F(fsub_d_cg, instr)
|
||||
FMUL_S : `SAMPLE_F(fmul_s_cg, instr)
|
||||
FMUL_D : `SAMPLE_F(fmul_d_cg, instr)
|
||||
FDIV_S : `SAMPLE_F(fdiv_s_cg, instr)
|
||||
FDIV_D : `SAMPLE_F(fdiv_d_cg, instr)
|
||||
FSQRT_S : `SAMPLE_F(fsqrt_s_cg, instr)
|
||||
FSQRT_D : `SAMPLE_F(fsqrt_d_cg, instr)
|
||||
FMIN_S : `SAMPLE_F(fmin_s_cg, instr)
|
||||
FMIN_D : `SAMPLE_F(fmin_d_cg, instr)
|
||||
FMAX_S : `SAMPLE_F(fmax_s_cg, instr)
|
||||
FMAX_D : `SAMPLE_F(fmax_d_cg, instr)
|
||||
FMADD_S : `SAMPLE_F(fmadd_s_cg, instr)
|
||||
FMADD_D : `SAMPLE_F(fmadd_d_cg, instr)
|
||||
FNMADD_S : `SAMPLE_F(fnmadd_s_cg, instr)
|
||||
FNMADD_D : `SAMPLE_F(fnmadd_d_cg, instr)
|
||||
FMSUB_S : `SAMPLE_F(fmsub_s_cg, instr)
|
||||
FMSUB_D : `SAMPLE_F(fmsub_d_cg, instr)
|
||||
FNMSUB_S : `SAMPLE_F(fnmsub_s_cg, instr)
|
||||
FNMSUB_D : `SAMPLE_F(fnmsub_d_cg, instr)
|
||||
FCVT_W_S : `SAMPLE_F(fcvt_w_s_cg, instr)
|
||||
FCVT_WU_S : `SAMPLE_F(fcvt_wu_s_cg, instr)
|
||||
FCVT_L_S : `SAMPLE_F(fcvt_l_s_cg, instr)
|
||||
FCVT_LU_S : `SAMPLE_F(fcvt_lu_s_cg, instr)
|
||||
FCVT_L_D : `SAMPLE_F(fcvt_l_d_cg, instr)
|
||||
FCVT_LU_D : `SAMPLE_F(fcvt_lu_d_cg, instr)
|
||||
FCVT_S_D : `SAMPLE_F(fcvt_s_d_cg, instr)
|
||||
FCVT_D_S : `SAMPLE_F(fcvt_d_s_cg, instr)
|
||||
FCVT_W_D : `SAMPLE_F(fcvt_w_d_cg, instr)
|
||||
FCVT_WU_D : `SAMPLE_F(fcvt_wu_d_cg, instr)
|
||||
FCVT_S_W : `SAMPLE_F(fcvt_s_w_cg, instr)
|
||||
FCVT_S_WU : `SAMPLE_F(fcvt_s_wu_cg, instr)
|
||||
FCVT_S_L : `SAMPLE_F(fcvt_s_l_cg, instr)
|
||||
FCVT_D_L : `SAMPLE_F(fcvt_d_l_cg, instr)
|
||||
FCVT_S_LU : `SAMPLE_F(fcvt_s_lu_cg, instr)
|
||||
FCVT_D_W : `SAMPLE_F(fcvt_d_w_cg, instr)
|
||||
FCVT_D_LU : `SAMPLE_F(fcvt_d_lu_cg, instr)
|
||||
FCVT_D_WU : `SAMPLE_F(fcvt_d_wu_cg, instr)
|
||||
FSGNJ_S : `SAMPLE_F(fsgnj_s_cg, instr)
|
||||
FSGNJ_D : `SAMPLE_F(fsgnj_d_cg, instr)
|
||||
FSGNJN_S : `SAMPLE_F(fsgnjn_s_cg, instr)
|
||||
FSGNJN_D : `SAMPLE_F(fsgnjn_d_cg, instr)
|
||||
FSGNJX_S : `SAMPLE_F(fsgnjx_s_cg, instr)
|
||||
FSGNJX_D : `SAMPLE_F(fsgnjx_d_cg, instr)
|
||||
FMV_X_W : `SAMPLE_F(fmv_x_w_cg, instr)
|
||||
FMV_X_D : `SAMPLE_F(fmv_x_d_cg, instr)
|
||||
FMV_W_X : `SAMPLE_F(fmv_w_x_cg, instr)
|
||||
FMV_D_X : `SAMPLE_F(fmv_d_x_cg, instr)
|
||||
FEQ_S : `SAMPLE_F(feq_s_cg, instr)
|
||||
FEQ_D : `SAMPLE_F(feq_d_cg, instr)
|
||||
FLT_S : `SAMPLE_F(flt_s_cg, instr)
|
||||
FLT_D : `SAMPLE_F(flt_d_cg, instr)
|
||||
FLE_S : `SAMPLE_F(fle_s_cg, instr)
|
||||
FLE_D : `SAMPLE_F(fle_d_cg, instr)
|
||||
FCLASS_S : `SAMPLE_F(fclass_s_cg, instr)
|
||||
FCLASS_D : `SAMPLE_F(fclass_d_cg, instr)
|
||||
// RV32B
|
||||
CLZ : `SAMPLE_B(clz_cg, instr)
|
||||
CTZ : `SAMPLE_B(ctz_cg, instr)
|
||||
|
@ -2068,8 +2427,7 @@ class riscv_instr_cover_group;
|
|||
end
|
||||
end
|
||||
`VECTOR_INCLUDE("riscv_instr_cover_group_inc_sample.sv")
|
||||
pre_instr.copy(instr);
|
||||
pre_instr.mem_addr = instr.mem_addr;
|
||||
pre_instr = instr;
|
||||
endfunction
|
||||
|
||||
// Check if the instruction is supported
|
||||
|
@ -2096,11 +2454,12 @@ class riscv_instr_cover_group;
|
|||
instr_name = instr_name.first;
|
||||
do begin
|
||||
riscv_instr instr;
|
||||
if (!(instr_name inside {unsupported_instr}) && (instr_name != INVALID_INSTR)) begin
|
||||
if (!(instr_name inside {unsupported_instr}) && (instr_name != INVALID_INSTR) &&
|
||||
riscv_instr::instr_registry.exists(instr_name)) begin
|
||||
instr = riscv_instr::create_instr(instr_name);
|
||||
if ((instr.group inside {supported_isa}) &&
|
||||
(instr.group inside {RV32I, RV32M, RV64M, RV64I, RV32C, RV64C,
|
||||
RV32V, RV64V, RV64B, RV32B})) begin
|
||||
RVV, RV64B, RV32B})) begin
|
||||
if (((instr_name inside {URET}) && !support_umode_trap) ||
|
||||
((instr_name inside {SRET, SFENCE_VMA}) &&
|
||||
!(SUPERVISOR_MODE inside {supported_privileged_mode})) ||
|
||||
|
|
|
@ -328,6 +328,8 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
constraint mstatus_c {
|
||||
if (set_mstatus_mprv) {
|
||||
mstatus_mprv == 1'b1;
|
||||
} else {
|
||||
mstatus_mprv == 1'b0;
|
||||
}
|
||||
if (SATP_MODE == BARE) {
|
||||
mstatus_mxr == 0;
|
||||
|
@ -591,7 +593,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
get_invalid_priv_lvl_csr();
|
||||
endfunction
|
||||
|
||||
function void setup_instr_distribution();
|
||||
virtual function void setup_instr_distribution();
|
||||
string opts;
|
||||
int val;
|
||||
get_int_arg_value("+dist_control_mode=", dist_control_mode);
|
||||
|
@ -643,7 +645,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
end
|
||||
endfunction
|
||||
|
||||
function void get_non_reserved_gpr();
|
||||
virtual function void get_non_reserved_gpr();
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
|
@ -659,7 +661,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
end
|
||||
endfunction
|
||||
|
||||
function void check_setting();
|
||||
virtual function void check_setting();
|
||||
bit support_64b;
|
||||
bit support_128b;
|
||||
foreach (riscv_instr_pkg::supported_isa[i]) begin
|
||||
|
|
77
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
77
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -89,9 +90,8 @@ package riscv_instr_pkg;
|
|||
RV64C,
|
||||
RV128I,
|
||||
RV128C,
|
||||
RV32V,
|
||||
RVV,
|
||||
RV32B,
|
||||
RV64V,
|
||||
RV64B,
|
||||
RV32X,
|
||||
RV64X
|
||||
|
@ -474,12 +474,10 @@ package riscv_instr_pkg;
|
|||
VWMACC,
|
||||
VWMACCSU,
|
||||
VWMACCUS,
|
||||
/*
|
||||
VQMACCU,
|
||||
VQMACC,
|
||||
VQMACCSU,
|
||||
VQMACCUS,
|
||||
*/
|
||||
//VQMACCU,
|
||||
//VQMACC,
|
||||
//VQMACCSU,
|
||||
//VQMACCUS,
|
||||
VMERGE,
|
||||
VMV,
|
||||
VSADDU,
|
||||
|
@ -494,6 +492,7 @@ package riscv_instr_pkg;
|
|||
VSSRA,
|
||||
VNCLIPU,
|
||||
VNCLIP,
|
||||
// 14. Vector Floating-Point Instructions
|
||||
VFADD,
|
||||
VFSUB,
|
||||
VFRSUB,
|
||||
|
@ -543,7 +542,7 @@ package riscv_instr_pkg;
|
|||
VFNCVT_F_X_W,
|
||||
VFNCVT_F_F_W,
|
||||
VFNCVT_ROD_F_F_W,
|
||||
// Vector reduction instruction
|
||||
// 15. Vector reduction instruction
|
||||
VREDSUM_VS,
|
||||
VREDMAXU_VS,
|
||||
VREDMAX_VS,
|
||||
|
@ -590,6 +589,51 @@ package riscv_instr_pkg;
|
|||
VMV2R_V,
|
||||
VMV4R_V,
|
||||
VMV8R_V,
|
||||
// Vector load/store instruction
|
||||
VLE_V,
|
||||
VSE_V,
|
||||
VLB_V,
|
||||
VSB_V,
|
||||
VLH_V,
|
||||
VSH_V,
|
||||
VLW_V,
|
||||
VSW_V,
|
||||
VLBU_V,
|
||||
VLHU_V,
|
||||
VLWU_V,
|
||||
VLSB_V,
|
||||
VLSH_V,
|
||||
VLSW_V,
|
||||
VLSBU_V,
|
||||
VLSHU_V,
|
||||
VLSWU_V,
|
||||
VLSE_V,
|
||||
VSSB_V,
|
||||
VSSH_V,
|
||||
VSSW_V,
|
||||
VSSE_V,
|
||||
VLXB_V,
|
||||
VLXH_V,
|
||||
VLXW_V,
|
||||
VLXBU_V,
|
||||
VLXHU_V,
|
||||
VLXWU_V,
|
||||
VLXE_V,
|
||||
VSXB_V,
|
||||
VSXH_V,
|
||||
VSXW_V,
|
||||
VSXE_V,
|
||||
VSUXB_V,
|
||||
VSUXH_V,
|
||||
VSUXW_V,
|
||||
VSUXE_V,
|
||||
VLBFF_V,
|
||||
VLHFF_V,
|
||||
VLWFF_V,
|
||||
VLBUFF_V,
|
||||
VLHUFF_V,
|
||||
VLWUFF_V,
|
||||
VLEFF_V,
|
||||
// Supervisor instruction
|
||||
DRET,
|
||||
MRET,
|
||||
|
@ -606,6 +650,9 @@ package riscv_instr_pkg;
|
|||
// Maximum virtual address bits used by the program
|
||||
parameter int MAX_USED_VADDR_BITS = 30;
|
||||
|
||||
parameter int SINGLE_PRECISION_FRACTION_BITS = 23;
|
||||
parameter int DOUBLE_PRECISION_FRACTION_BITS = 52;
|
||||
|
||||
typedef enum bit [4:0] {
|
||||
ZERO = 5'b00000,
|
||||
RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7,
|
||||
|
@ -645,7 +692,11 @@ package riscv_instr_pkg;
|
|||
VA_FORMAT,
|
||||
VS2_FORMAT, // op vd,vs2
|
||||
VL_FORMAT,
|
||||
VS_FORMAT
|
||||
VS_FORMAT,
|
||||
VLV_FORMAT,
|
||||
VSV_FORMAT,
|
||||
VLS_FORMAT,
|
||||
VSS_FORMAT
|
||||
} riscv_instr_format_t;
|
||||
|
||||
|
||||
|
@ -1090,9 +1141,9 @@ package riscv_instr_pkg;
|
|||
typedef struct packed {
|
||||
bit ill;
|
||||
bit [XLEN-2:7] reserved;
|
||||
bit [1:0] vediv;
|
||||
bit [2:0] vsew;
|
||||
bit [1:0] vlmul;
|
||||
int vediv;
|
||||
int vsew;
|
||||
int vlmul;
|
||||
} vtype_t;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
|
|
|
@ -275,6 +275,12 @@ class riscv_instr_sequence extends uvm_sequence;
|
|||
str = {prefix, instr_stream.instr_list[i].convert2asm()};
|
||||
instr_string_list.push_back(str);
|
||||
end
|
||||
// If PMP is supported, need to align <main> to a 4-byte boundary.
|
||||
// TODO(udi) - this might interfere with multi-hart programs,
|
||||
// may need to specifically match hart0.
|
||||
if (riscv_instr_pkg::support_pmp && !uvm_re_match("*main*", label_name)) begin
|
||||
instr_string_list.push_front(".align 2");
|
||||
end
|
||||
insert_illegal_hint_instr();
|
||||
prefix = format_string($sformatf("%0d:", i), LABEL_STR_LEN);
|
||||
if(!is_main_program) begin
|
||||
|
|
13
vendor/google_riscv-dv/src/riscv_instr_stream.sv
vendored
13
vendor/google_riscv-dv/src/riscv_instr_stream.sv
vendored
|
@ -186,6 +186,18 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
|
|||
setup_instruction_dist(no_branch, no_load_store);
|
||||
endfunction
|
||||
|
||||
virtual function void randomize_avail_regs();
|
||||
if(avail_regs.size() > 0) begin
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
|
||||
unique{avail_regs};
|
||||
avail_regs[0] inside {[S0 : A5]};
|
||||
foreach(avail_regs[i]) {
|
||||
!(avail_regs[i] inside {cfg.reserved_regs, reserved_rd});
|
||||
},
|
||||
"Cannot randomize avail_regs")
|
||||
end
|
||||
endfunction
|
||||
|
||||
function void setup_instruction_dist(bit no_branch = 1'b0, bit no_load_store = 1'b1);
|
||||
if (cfg.dist_control_mode) begin
|
||||
category_dist = cfg.category_dist;
|
||||
|
@ -227,6 +239,7 @@ class riscv_rand_instr_stream extends riscv_instr_stream;
|
|||
end
|
||||
instr = riscv_instr::get_rand_instr(.include_instr(allowed_instr),
|
||||
.exclude_instr(exclude_instr));
|
||||
instr.m_cfg = cfg;
|
||||
randomize_gpr(instr);
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -120,19 +121,11 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
|
|||
virtual function void gen_load_store_instr();
|
||||
bit enable_compressed_load_store;
|
||||
riscv_instr instr;
|
||||
if(avail_regs.size() > 0) begin
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
|
||||
unique{avail_regs};
|
||||
avail_regs[0] inside {[S0 : A5]};
|
||||
foreach(avail_regs[i]) {
|
||||
!(avail_regs[i] inside {cfg.reserved_regs, reserved_rd});
|
||||
},
|
||||
"Cannot randomize avail_regs")
|
||||
end
|
||||
randomize_avail_regs();
|
||||
if ((rs1_reg inside {[S0 : A5], SP}) && !cfg.disable_compressed_instr) begin
|
||||
enable_compressed_load_store = 1;
|
||||
end
|
||||
foreach(addr[i]) begin
|
||||
foreach (addr[i]) begin
|
||||
// Assign the allowed load/store instructions based on address alignment
|
||||
// This is done separately rather than a constraint to improve the randomization performance
|
||||
allowed_instr = {LB, LBU, SB};
|
||||
|
@ -450,6 +443,7 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
|
|||
}
|
||||
|
||||
`uvm_object_utils(riscv_load_store_rand_addr_instr_stream)
|
||||
`uvm_object_new
|
||||
|
||||
virtual function void randomize_offset();
|
||||
int offset_, addr_;
|
||||
|
@ -465,7 +459,7 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
|
|||
offset[i] = offset_;
|
||||
addr[i] = addr_offset + offset_;
|
||||
end
|
||||
endfunction `uvm_object_new
|
||||
endfunction
|
||||
|
||||
virtual function void add_rs1_init_la_instr(riscv_reg_t gpr, int id, int base = 0);
|
||||
riscv_instr instr[$];
|
||||
|
@ -524,3 +518,136 @@ class riscv_load_store_rand_addr_instr_stream extends riscv_load_store_base_inst
|
|||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_vector_unit_stride_load_store_instr_stream extends riscv_mem_access_stream;
|
||||
|
||||
typedef enum {B_ALIGNMENT, H_ALIGNMENT, W_ALIGNMENT, E_ALIGNMENT} alignment_e;
|
||||
|
||||
rand alignment_e alignment;
|
||||
rand int unsigned data_page_id;
|
||||
rand int unsigned num_mixed_instr;
|
||||
rand riscv_reg_t rs1_reg;
|
||||
|
||||
constraint vec_mixed_instr_c {
|
||||
num_mixed_instr inside {[0:10]};
|
||||
}
|
||||
|
||||
constraint vec_rs1_c {
|
||||
!(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
|
||||
}
|
||||
|
||||
constraint vec_data_page_id_c {
|
||||
data_page_id < max_data_page_id;
|
||||
}
|
||||
|
||||
constraint alignment_sew_c {
|
||||
if (cfg.vector_cfg.vtype.vsew <= 16) {alignment != W_ALIGNMENT;}
|
||||
if (cfg.vector_cfg.vtype.vsew <= 8) {alignment != H_ALIGNMENT;}
|
||||
}
|
||||
|
||||
int base;
|
||||
int max_load_store_addr;
|
||||
riscv_instr load_store_instr;
|
||||
|
||||
`uvm_object_utils(riscv_vector_unit_stride_load_store_instr_stream)
|
||||
`uvm_object_new
|
||||
|
||||
virtual function int get_addr_alignment_mask(int alignment_bytes);
|
||||
return alignment_bytes - 1;
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
randomize_base();
|
||||
// rs1 cannot be modified by other instructions
|
||||
if(!(rs1_reg inside {reserved_rd})) reserved_rd = {reserved_rd, rs1_reg};
|
||||
randomize_avail_regs();
|
||||
gen_load_store_instr();
|
||||
add_mixed_instr(num_mixed_instr);
|
||||
add_rs1_init_la_instr(rs1_reg, data_page_id, base);
|
||||
super.post_randomize();
|
||||
endfunction
|
||||
|
||||
virtual function void randomize_base();
|
||||
int ss = stride_span();
|
||||
bit success;
|
||||
|
||||
repeat (10) begin
|
||||
max_load_store_addr = data_page[data_page_id].size_in_bytes - ss;
|
||||
if (max_load_store_addr >= 0) begin
|
||||
success = 1'b1;
|
||||
break;
|
||||
end
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(data_page_id, data_page_id < max_data_page_id;)
|
||||
end
|
||||
|
||||
assert (success) else begin
|
||||
`uvm_fatal(`gfn, $sformatf({"Expected positive value for max_load_store_addr, got %0d.",
|
||||
" Perhaps more memory needs to be allocated in the data pages for vector loads and stores.",
|
||||
"\ndata_page_id:%0d\ndata_page[data_page_id].size_in_bytes:%0d\nstride_span:%0d",
|
||||
"\nalignment:%s\nstride_bytes:%0d\nVLEN:%0d\nLMUL:%0d\ncfg.vector_cfg.vtype.vsew:%0d\n\n"},
|
||||
max_load_store_addr, data_page_id, data_page[data_page_id].size_in_bytes, ss,
|
||||
alignment.name(), stride_bytes(), VLEN,
|
||||
cfg.vector_cfg.vtype.vlmul, cfg.vector_cfg.vtype.vsew))
|
||||
end
|
||||
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(base, base >= 0; base <= max_load_store_addr;)
|
||||
|
||||
if (!cfg.enable_unaligned_load_store) begin
|
||||
base &= ~get_addr_alignment_mask(stride_bytes());
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function int stride_span();
|
||||
int num_elements = VLEN * cfg.vector_cfg.vtype.vlmul / cfg.vector_cfg.vtype.vsew;
|
||||
stride_span = num_elements * stride_bytes();
|
||||
endfunction
|
||||
|
||||
virtual function int stride_bytes();
|
||||
stride_bytes = 0;
|
||||
if (alignment == B_ALIGNMENT) stride_bytes = 1;
|
||||
else if (alignment == H_ALIGNMENT) stride_bytes = 2;
|
||||
else if (alignment == W_ALIGNMENT) stride_bytes = 4;
|
||||
else if (alignment == E_ALIGNMENT) stride_bytes = cfg.vector_cfg.vtype.vsew;
|
||||
endfunction
|
||||
|
||||
// Generate each load/store instruction
|
||||
virtual function void gen_load_store_instr();
|
||||
build_allowed_instr();
|
||||
randomize_vec_load_store_instr();
|
||||
instr_list.push_back(load_store_instr);
|
||||
endfunction
|
||||
|
||||
virtual function void build_allowed_instr();
|
||||
if (alignment == B_ALIGNMENT) add_byte_aligned_vec_load_stores();
|
||||
else if (alignment == H_ALIGNMENT) add_h_aligned_vec_load_stores();
|
||||
else if (alignment == W_ALIGNMENT) add_w_aligned_vec_load_stores();
|
||||
else if (alignment == E_ALIGNMENT) add_element_vec_load_stores();
|
||||
endfunction
|
||||
|
||||
virtual function void add_element_vec_load_stores();
|
||||
allowed_instr = {VLE_V, VSE_V, allowed_instr};
|
||||
endfunction
|
||||
|
||||
virtual function void add_byte_aligned_vec_load_stores();
|
||||
allowed_instr = {VLB_V, VSB_V, VLBU_V, allowed_instr};
|
||||
endfunction
|
||||
|
||||
virtual function void add_h_aligned_vec_load_stores();
|
||||
allowed_instr = {VLH_V, VSH_V, VLHU_V, allowed_instr};
|
||||
endfunction
|
||||
|
||||
virtual function void add_w_aligned_vec_load_stores();
|
||||
allowed_instr = {VLW_V, VSW_V, VLWU_V, allowed_instr};
|
||||
endfunction
|
||||
|
||||
virtual function void randomize_vec_load_store_instr();
|
||||
load_store_instr = riscv_instr::get_load_store_instr(allowed_instr);
|
||||
load_store_instr.m_cfg = cfg;
|
||||
load_store_instr.has_rs1 = 0;
|
||||
load_store_instr.has_imm = 0;
|
||||
randomize_gpr(load_store_instr);
|
||||
load_store_instr.rs1 = rs1_reg;
|
||||
load_store_instr.process_load_store = 0;
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
|
@ -495,7 +495,7 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
|
|||
// Unset U bit
|
||||
$sformatf("and x%0d, x%0d, x%0d", cfg.gpr[3], cfg.gpr[3], cfg.gpr[2]),
|
||||
// Save PTE back to memory
|
||||
$sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
|
||||
$sformatf("s%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
|
||||
// Move to the next PTE
|
||||
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN/8),
|
||||
// If not the end of the kernel space, process the next PTE
|
||||
|
@ -513,14 +513,14 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
|
|||
$sformatf("add x%0d, x%0d, x%0d", cfg.gpr[0], cfg.gpr[2], cfg.gpr[0]),
|
||||
$sformatf("li x%0d, 0x%0x", cfg.gpr[2], ubit_mask),
|
||||
// Assume 20 PTEs for kernel data pages
|
||||
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], 20 * XLEN/8),
|
||||
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[1], cfg.gpr[1], 20 * XLEN/8),
|
||||
"2:",
|
||||
// Load the PTE from the memory
|
||||
$sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
|
||||
// Unset U bit
|
||||
$sformatf("and x%0d, x%0d, x%0d", cfg.gpr[3], cfg.gpr[3], cfg.gpr[2]),
|
||||
// Save PTE back to memory
|
||||
$sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
|
||||
$sformatf("s%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
|
||||
// Move to the next PTE
|
||||
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN/8),
|
||||
// If not the end of the kernel space, process the next PTE
|
||||
|
|
69
vendor/google_riscv-dv/src/riscv_vector_cfg.sv
vendored
69
vendor/google_riscv-dv/src/riscv_vector_cfg.sv
vendored
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
* Copyright 2020 Andes Technology Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,21 +23,75 @@ class riscv_vector_cfg extends uvm_object;
|
|||
rand vxrm_t vxrm;
|
||||
rand bit vxsat;
|
||||
|
||||
// Allow only vector instructions from the random sequences
|
||||
rand bit only_vec_instr;
|
||||
constraint only_vec_instr_c {soft only_vec_instr == 0;}
|
||||
|
||||
// Allow vector floating-point instructions (Allows vtype.vsew to be set <16 or >32).
|
||||
rand bit vec_fp;
|
||||
|
||||
// Allow vector narrowing or widening instructions.
|
||||
rand bit vec_narrowing_widening;
|
||||
|
||||
// Allow vector quad-widening instructions.
|
||||
rand bit vec_quad_widening;
|
||||
|
||||
constraint vec_quad_widening_c {
|
||||
(!vec_narrowing_widening) -> (!vec_quad_widening);
|
||||
// FP requires at least 16 bits and quad-widening requires no more than ELEN/4 bits.
|
||||
(ELEN < 64) -> (!(vec_fp && vec_quad_widening));
|
||||
}
|
||||
|
||||
rand bit allow_illegal_vec_instr;
|
||||
constraint allow_illegal_vec_instr_c {soft allow_illegal_vec_instr == 0;}
|
||||
|
||||
// Cause frequent hazards for the Vector Registers:
|
||||
// * Write-After-Read (WAR)
|
||||
// * Read-After-Write (RAW)
|
||||
// * Read-After-Read (RAR)
|
||||
// * Write-After-Write (WAW)
|
||||
// These hazard conditions are induced by keeping a small (~5) list of registers to select from.
|
||||
rand bit vec_reg_hazards;
|
||||
|
||||
constraint legal_c {
|
||||
solve vtype before vl;
|
||||
solve vl before vstart;
|
||||
vstart <= vl;
|
||||
vtype.vsew <= $clog2(VLEN/8);
|
||||
vl <= (1 << ($clog2(VLEN/8) - vtype.vsew));
|
||||
vstart inside {[0:vl]};
|
||||
vl inside {[1:VLEN/vtype.vsew]};
|
||||
}
|
||||
|
||||
// Basic constraint for initial bringup
|
||||
constraint bringup_c {
|
||||
vstart == 0;
|
||||
vl == (1 << ($clog2(VLEN/8) - vtype.vsew));
|
||||
vtype.vlmul == 0;
|
||||
vtype.vediv == 0;
|
||||
vtype.vsew == 2;
|
||||
vl == VLEN/vtype.vsew;
|
||||
vtype.vediv == 1;
|
||||
}
|
||||
|
||||
// For all widening instructions, the destination element width must be a supported element
|
||||
// width and the destination LMUL value must also be a supported LMUL value
|
||||
constraint vlmul_c {
|
||||
vtype.vlmul inside {1, 2, 4, 8};
|
||||
vtype.vlmul <= MAX_LMUL;
|
||||
if (vec_narrowing_widening) {
|
||||
vtype.vlmul < 8;
|
||||
}
|
||||
if (vec_quad_widening) {
|
||||
vtype.vlmul < 4;
|
||||
}
|
||||
}
|
||||
|
||||
constraint vsew_c {
|
||||
vtype.vsew inside {8, 16, 32, 64, 128};
|
||||
vtype.vsew <= ELEN;
|
||||
// TODO: Determine the legal range of floating point format
|
||||
if (vec_fp) {vtype.vsew inside {32};}
|
||||
if (vec_narrowing_widening) {vtype.vsew < ELEN;}
|
||||
if (vec_quad_widening) {vtype.vsew < (ELEN >> 1);}
|
||||
}
|
||||
|
||||
constraint vdeiv_c {
|
||||
vtype.vediv inside {1, 2, 4, 8};
|
||||
vtype.vediv <= (vtype.vsew / SELEN);
|
||||
}
|
||||
|
||||
`uvm_object_utils_begin(riscv_vector_cfg)
|
||||
|
|
|
@ -54,14 +54,39 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -54,11 +54,35 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 2;
|
||||
|
|
|
@ -54,14 +54,36 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -54,11 +54,35 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
|
|
@ -54,11 +54,35 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
|
|
@ -54,11 +54,35 @@ bit support_sfence = 1;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
|
|
@ -21,17 +21,17 @@
|
|||
parameter int XLEN = 64;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = SV39;
|
||||
parameter satp_mode_t SATP_MODE = BARE;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {USER_MODE, SUPERVISOR_MODE, MACHINE_MODE};
|
||||
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[] = {VWMACCSU};
|
||||
riscv_instr_name_t unsupported_instr[] = {};
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A,
|
||||
RV32F, RV64F, RV32D, RV64D, RV32V, RV64V};
|
||||
RV32F, RV64F, RV32D, RV64D, RVV};
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
||||
|
@ -54,14 +54,38 @@ bit support_sfence = 1;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 1;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -47,3 +47,19 @@
|
|||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_vector_load_store_test
|
||||
description: >
|
||||
Vector load/store random test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=0
|
||||
+enable_floating_point=1
|
||||
+enable_vector_extension=1
|
||||
+directed_instr_0=riscv_vector_unit_stride_load_store_instr_stream,4
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
|
|
@ -54,11 +54,34 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
|
|
@ -54,11 +54,35 @@ bit support_sfence = 0;
|
|||
// Support unaligned load/store
|
||||
bit support_unaligned_load_store = 1'b1;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 32;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vector extension configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Parameter for vector extension
|
||||
parameter int VECTOR_EXTENSION_ENABLE = 0;
|
||||
|
||||
parameter int VLEN = 512;
|
||||
parameter int ELEN = 64;
|
||||
parameter int SLEN = 64;
|
||||
|
||||
// Maximum size of a single vector element
|
||||
parameter int ELEN = 32;
|
||||
|
||||
// Minimum size of a sub-element, which must be at most 8-bits.
|
||||
parameter int SELEN = 8;
|
||||
|
||||
// Maximum size of a single vector element (encoded in vsew format)
|
||||
parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
|
||||
|
||||
// Maxium LMUL supported by the core
|
||||
parameter int MAX_LMUL = 8;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Multi-harts configuration
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Number of harts
|
||||
parameter int NUM_HARTS = 1;
|
||||
|
|
|
@ -132,11 +132,12 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
riscv_instr instr;
|
||||
instr = riscv_instr::get_instr(instr_name);
|
||||
if (instr.group inside {RV32I, RV32M, RV32C, RV64I, RV64M, RV64C,
|
||||
RV32F, RV32B, RV64B}) begin
|
||||
RV32F, RV64F, RV32D, RV64D,
|
||||
RV32B, RV64B}) begin
|
||||
assign_trace_info_to_instr(instr);
|
||||
instr.pre_sample();
|
||||
instr_cg.sample(instr);
|
||||
end
|
||||
instr.pre_sample();
|
||||
instr_cg.sample(instr);
|
||||
return 1'b1;
|
||||
end
|
||||
end
|
||||
|
@ -177,6 +178,27 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
instr_name[i] = "_";
|
||||
end
|
||||
end
|
||||
|
||||
case (instr_name)
|
||||
// rename to new name as ovpsim still uses old name
|
||||
"FMV_S_X": instr_name = "FMV_W_X";
|
||||
"FMV_X_S": instr_name = "FMV_X_W";
|
||||
// convert Pseudoinstructions
|
||||
// fmv.s rd, rs fsgnj.s rd, rs, rs Copy single-precision register
|
||||
// fabs.s rd, rs fsgnjx.s rd, rs, rs Single-precision absolute value
|
||||
// fneg.s rd, rs fsgnjn.s rd, rs, rs Single-precision negate
|
||||
// fmv.d rd, rs fsgnj.d rd, rs, rs Copy double-precision register
|
||||
// fabs.d rd, rs fsgnjx.d rd, rs, rs Double-precision absolute value
|
||||
// fneg.d rd, rs fsgnjn.d rd, rs, rs Double-precision negate
|
||||
"FMV_S": instr_name = "FSGNJ_S";
|
||||
"FABS_S": instr_name = "FSGNJX_S";
|
||||
"FNEG_S": instr_name = "FSGNJN_S";
|
||||
"FMV_D": instr_name = "FSGNJ_D";
|
||||
"FABS_D": instr_name = "FSGNJX_D";
|
||||
"FNEG_D": instr_name = "FSGNJN_D";
|
||||
default: ;
|
||||
endcase
|
||||
|
||||
return instr_name;
|
||||
endfunction : process_instr_name
|
||||
|
||||
|
|
2
vendor/google_riscv-dv/user_extension/user_init.s
vendored
Normal file
2
vendor/google_riscv-dv/user_extension/user_init.s
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Add custom initialization assembly code here
|
||||
# This file will be included at the very beginning of the program
|
Loading…
Add table
Add a link
Reference in a new issue