diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index fdfbb511..57ed1a99 100644 --- a/vendor/google_riscv-dv.lock.hjson +++ b/vendor/google_riscv-dv.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/google/riscv-dv - rev: 1ad73cc43f8f84d93d49040f8b2928e74efdd854 + rev: 6cf6b4f389272d8ff5e2b397af43ac6c0dfba2e2 } } diff --git a/vendor/google_riscv-dv/.flake8 b/vendor/google_riscv-dv/.flake8 new file mode 100644 index 00000000..5b0913f6 --- /dev/null +++ b/vendor/google_riscv-dv/.flake8 @@ -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 diff --git a/vendor/google_riscv-dv/.travis.yml b/vendor/google_riscv-dv/.travis.yml index dada2b93..2c25db43 100644 --- a/vendor/google_riscv-dv/.travis.yml +++ b/vendor/google_riscv-dv/.travis.yml @@ -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 diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py new file mode 100644 index 00000000..8392a3c9 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py @@ -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() diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py new file mode 100644 index 00000000..a7ed7ac7 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py @@ -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()) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py new file mode 100644 index 00000000..d4f2b23f --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py @@ -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 diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py new file mode 100644 index 00000000..6d59010a --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py @@ -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 diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py new file mode 100644 index 00000000..5edc6a45 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py @@ -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 diff --git a/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py b/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py new file mode 100644 index 00000000..67bcb6a9 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py @@ -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) diff --git a/vendor/google_riscv-dv/requirements.txt b/vendor/google_riscv-dv/requirements.txt index e616e982..a6b0913f 100644 --- a/vendor/google_riscv-dv/requirements.txt +++ b/vendor/google_riscv-dv/requirements.txt @@ -6,3 +6,4 @@ sphinxcontrib-log-cabinet sphinx-issues sphinx_rtd_theme rst2pdf +flake8 diff --git a/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv index 35853f05..bcfcf985 100644 --- a/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv +++ b/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/isa/riscv_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_instr.sv index 087884e9..88e13253 100644 --- a/vendor/google_riscv-dv/src/isa/riscv_instr.sv +++ b/vendor/google_riscv-dv/src/isa/riscv_instr.sv @@ -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); diff --git a/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh b/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh index e828f817..18b79252 100644 --- a/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh +++ b/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh @@ -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) diff --git a/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv index 5fc70b4a..f76f53cb 100644 --- a/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv +++ b/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/isa/rv32v_instr.sv b/vendor/google_riscv-dv/src/isa/rv32v_instr.sv index 91984173..2a3eb7e6 100644 --- a/vendor/google_riscv-dv/src/isa/rv32v_instr.sv +++ b/vendor/google_riscv-dv/src/isa/rv32v_instr.sv @@ -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) diff --git a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv index 96d3cadc..d9a48764 100644 --- a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv +++ b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv index 3dfba5dc..f3bc7080 100644 --- a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv index 9c016e6f..33896ad8 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv @@ -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})) || diff --git a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv index 5f92aa62..3200353a 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv index c60dd574..de51c44c 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv @@ -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] { diff --git a/vendor/google_riscv-dv/src/riscv_instr_sequence.sv b/vendor/google_riscv-dv/src/riscv_instr_sequence.sv index e2a22e97..b343608f 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_sequence.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_sequence.sv @@ -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
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 diff --git a/vendor/google_riscv-dv/src/riscv_instr_stream.sv b/vendor/google_riscv-dv/src/riscv_instr_stream.sv index ab72debc..0f737e2f 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_stream.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_stream.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv index 94c771e0..e95e3ccd 100644 --- a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_page_table_list.sv b/vendor/google_riscv-dv/src/riscv_page_table_list.sv index d05bffdc..5cc37724 100644 --- a/vendor/google_riscv-dv/src/riscv_page_table_list.sv +++ b/vendor/google_riscv-dv/src/riscv_page_table_list.sv @@ -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 diff --git a/vendor/google_riscv-dv/src/riscv_vector_cfg.sv b/vendor/google_riscv-dv/src/riscv_vector_cfg.sv index dd58c91b..90ce5c3b 100644 --- a/vendor/google_riscv-dv/src/riscv_vector_cfg.sv +++ b/vendor/google_riscv-dv/src/riscv_vector_cfg.sv @@ -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) diff --git a/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv b/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv index 46d466bc..707e9199 100644 --- a/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv @@ -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 // ---------------------------------------------------------------------------- diff --git a/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv b/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv index 78d7724b..04a2f55f 100644 --- a/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv index c93e3f30..49c97c8f 100644 --- a/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv @@ -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 // ---------------------------------------------------------------------------- diff --git a/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv index 1fc03481..1aaf1a11 100644 --- a/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv index dfc99c8c..df33010e 100644 --- a/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv index 386c6757..4ca59cdf 100644 --- a/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv index f9033d19..d4181205 100644 --- a/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv @@ -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 // ---------------------------------------------------------------------------- diff --git a/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml b/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml index 350e43b5..50698abe 100644 --- a/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml +++ b/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml @@ -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 diff --git a/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv index 8511dc42..0071ffae 100644 --- a/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv index 2f67acf2..3bf90a55 100644 --- a/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv +++ b/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv @@ -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; diff --git a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv index fb0fa20b..8bfc6253 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv @@ -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 diff --git a/vendor/google_riscv-dv/user_extension/user_init.s b/vendor/google_riscv-dv/user_extension/user_init.s new file mode 100644 index 00000000..2f8b49f1 --- /dev/null +++ b/vendor/google_riscv-dv/user_extension/user_init.s @@ -0,0 +1,2 @@ +# Add custom initialization assembly code here +# This file will be included at the very beginning of the program