Commit c1ef9953 authored by aneels3's avatar aneels3 Committed by udinator
Browse files

Add illegal and load store instruction


Signed-off-by: default avataraneels3 <b150023ec@nitsikkim.ac.in>
parent 0f95ad7f
......@@ -30,55 +30,55 @@ class riscv_compressed_instr(riscv_instr):
@vsc.constraint
def rvc_csr_c(self):
# Registers specified by the three-bit rs1, rs2, and rd
with vsc.implies(self.format.inside(vsc.rangelist(riscv_instr_format_t.CIW_FORMAT,
# Registers specified by the three-bit rs1, rs2, and rd
with vsc.if_then(self.format.inside(vsc.rangelist(riscv_instr_format_t.CIW_FORMAT,
riscv_instr_format_t.CL_FORMAT,
riscv_instr_format_t.CS_FORMAT,
riscv_instr_format_t.CB_FORMAT,
riscv_instr_format_t.CA_FORMAT))):
with vsc.implies(self.has_rs1 == 1):
with vsc.if_then(self.has_rs1 == 1):
self.rs1.inside(vsc.rangelist(riscv_reg_t.S0, riscv_reg_t.S1, riscv_reg_t.A0,
riscv_reg_t.A1, riscv_reg_t.A2, riscv_reg_t.A3,
riscv_reg_t.A4, riscv_reg_t.A5))
with vsc.implies(self.has_rs2 == 1):
with vsc.if_then(self.has_rs2 == 1):
self.rs2.inside(vsc.rangelist(riscv_reg_t.S0, riscv_reg_t.S1, riscv_reg_t.A0,
riscv_reg_t.A1, riscv_reg_t.A2, riscv_reg_t.A3,
riscv_reg_t.A4, riscv_reg_t.A5))
with vsc.implies(self.has_rd == 1):
with vsc.if_then(self.has_rd == 1):
self.rd.inside(vsc.rangelist(riscv_reg_t.S0, riscv_reg_t.S1, riscv_reg_t.A0,
riscv_reg_t.A1, riscv_reg_t.A2, riscv_reg_t.A3,
riscv_reg_t.A4, riscv_reg_t.A5))
# _ADDI16SP is only valid when rd == SP
with vsc.implies(self.instr_name == riscv_instr_name_t.C_ADDI16SP):
with vsc.if_then(self.instr_name == riscv_instr_name_t.C_ADDI16SP):
self.rd == riscv_reg_t.SP
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_JR,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_JR,
riscv_instr_name_t.C_JALR))):
self.rs1 != riscv_reg_t.ZERO
self.rs2 == riscv_reg_t.ZERO
@vsc.constraint
def imm_val_c(self):
with vsc.implies(self.imm_type.inside(vsc.rangelist(imm_t.NZIMM, imm_t.NZUIMM))):
with vsc.if_then(self.imm_type.inside(vsc.rangelist(imm_t.NZIMM, imm_t.NZUIMM))):
self.imm[5:0] != 0
with vsc.implies(self.instr_name == riscv_instr_name_t.C_LUI):
with vsc.if_then(self.instr_name == riscv_instr_name_t.C_LUI):
self.imm[31:5] == 0
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_SRAI,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_SRAI,
riscv_instr_name_t.C_SRLI,
riscv_instr_name_t.C_SLLI))):
self.imm[31:5] == 0
with vsc.implies(self.instr_name == riscv_instr_name_t.C_ADDI4SPN):
with vsc.if_then(self.instr_name == riscv_instr_name_t.C_ADDI4SPN):
self.imm[1:0] == 0
# C_JAL is RV32C only instruction
@vsc.constraint
def jal_c(self):
with vsc.implies(self.XLEN != 32):
with vsc.if_then(self.XLEN != 32):
self.instr_name != riscv_instr_name_t.C_JAL
# Avoid generating HINT or illegal instruction by default as it's not supported by the compiler
@vsc.constraint
def no_hint_illegal_instr_c(self):
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_ADDI,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_ADDI,
riscv_instr_name_t.C_ADDIW,
riscv_instr_name_t.C_LI,
riscv_instr_name_t.C_LUI,
......@@ -90,12 +90,12 @@ class riscv_compressed_instr(riscv_instr):
riscv_instr_name_t.C_ADD,
riscv_instr_name_t.C_LWSP))):
self.rd != riscv_reg_t.ZERO
with vsc.implies(self.instr_name == riscv_instr_name_t.C_JR):
with vsc.if_then(self.instr_name == riscv_instr_name_t.C_JR):
self.rs1 != riscv_reg_t.ZERO
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_ADD,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.C_ADD,
riscv_instr_name_t.C_MV))):
self.rs2 != riscv_reg_t.ZERO
with vsc.implies(self.instr_name == riscv_instr_name_t.C_LUI):
with vsc.if_then(self.instr_name == riscv_instr_name_t.C_LUI):
self.rd != riscv_reg_t.SP
def set_imm_len(self):
......
......@@ -98,16 +98,16 @@ class riscv_instr:
@vsc.constraint
def imm_c(self):
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.SLLIW,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.SLLIW,
riscv_instr_name_t.SRLIW,
riscv_instr_name_t.SRAIW))):
self.imm[11:5] == 0
with vsc.implies(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.SLLI,
with vsc.if_then(self.instr_name.inside(vsc.rangelist(riscv_instr_name_t.SLLI,
riscv_instr_name_t.SRLI,
riscv_instr_name_t.SRAI))):
with vsc.implies(self.XLEN == 32):
with vsc.if_then(self.XLEN == 32):
self.imm[11:5] == 0
with vsc.implies(self.XLEN != 32):
with vsc.if_then(self.XLEN != 32):
self.imm[11:6] == 0
@classmethod
......
......@@ -22,7 +22,7 @@ from pygen_src.riscv_instr_sequence import riscv_instr_sequence
from pygen_src.riscv_instr_pkg import (pkg_ins, privileged_reg_t,
privileged_mode_t, mtvec_mode_t,
misa_ext_t, riscv_instr_group_t,
satp_mode_t)
satp_mode_t, exception_cause_t)
from pygen_src.riscv_signature_pkg import (signature_type_t, core_status_t,
test_result_t)
from pygen_src.riscv_instr_gen_config import cfg
......@@ -441,7 +441,7 @@ class riscv_asm_program_gen:
privil_seq = riscv_privileged_common_seq()
for i in range(len(rcs.supported_privileged_mode)):
instr = []
csr_handshake = []
# csr_handshake = []
if rcs.supported_privileged_mode[i] != cfg.init_privileged_mode:
continue
logging.info("Generating privileged mode routing for {}"
......@@ -526,6 +526,7 @@ class riscv_asm_program_gen:
self.gen_instr_fault_handler(hart)
self.gen_load_fault_handler(hart)
self.gen_store_fault_handler(hart)
self.gen_illegal_instr_handler(hart)
def gen_trap_handlers(self, hart):
self.gen_trap_handler_section(hart, "m", privileged_reg_t.MCAUSE,
......@@ -536,7 +537,7 @@ class riscv_asm_program_gen:
def gen_trap_handler_section(self, hart, mode, cause, tvec,
tval, epc, scratch, status, ie, ip):
is_interrupt = 1
# is_interrupt = 1
tvec_name = ""
instr = []
if cfg.mtvec_mode == mtvec_mode_t.VECTORED:
......@@ -571,12 +572,28 @@ class riscv_asm_program_gen:
tvec_name = tvec.name
self.gen_section(pkg_ins.get_label("{}_handler".format(tvec_name.lower()), hart), instr)
# TODO Exception handler
# TODO Exception handlers
instr = []
if cfg.mtvec_mode == mtvec_mode_t.VECTORED:
pkg_ins.push_gpr_to_kernel_stack(
status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr)
pkg_ins.push_gpr_to_kernel_stack(status, scratch,
cfg.mstatus_mprv, cfg.sp, cfg.tp, instr)
self.gen_signature_handshake(instr, signature_type_t.CORE_STATUS,
core_status_t.HANDLING_EXCEPTION)
# The trap is caused by an exception, read back xCAUSE, xEPC to see if these
# CSR values are set properly. The checking is done by comparing against the log
# generated by ISA simulator (spike).
instr.extend(("csrr x{}, 0x{} # {}".format(cfg.gpr[0], epc, epc.name),
"csrr x{}, 0x{} # {}".format(cfg.gpr[0], cause, cause.name),
# Illegal instruction exception
"li x{}, {} # ILLEGAL_INSTRUCTION".format(
cfg.gpr[1], hex(exception_cause_t.ILLEGAL_INSTRUCTION)),
"beq x{}, x{}, {}illegal_instr_handler".format(
cfg.gpr[0], cfg.gpr[1], pkg_ins.hart_prefix(hart)),
# Skip checking tval for illegal instruction as it's implementation specific
"csrr x{}, {} # {}".format(cfg.gpr[1], hex(tval), tval.name),
# use JALR to jump to test_done.
"1: la x{}, test_done".format(cfg.scratch_reg),
"jalr x1, x{}, 0".format(cfg.scratch_reg)))
self.gen_section(pkg_ins.get_label("{}mode_exception_handler".format(mode), hart), instr)
def gen_interrupt_vector_table(self, hart, mode, status, cause, ie,
......@@ -633,7 +650,17 @@ class riscv_asm_program_gen:
pass
def gen_illegal_instr_handler(self, hart):
pass
instr = []
self.gen_signature_handshake(instr, signature_type_t.CORE_STATUS,
core_status_t.ILLEGAL_INSTR_EXCEPTION)
self.gen_signature_handshake(instr, signature_type_t.WRITE_CSR, privileged_reg_t.MCAUSE)
instr.extend(("csrr x{}, {}".format(cfg.gpr[0], hex(privileged_reg_t.MEPC)),
"addi x{}, x{}, 4".format(cfg.gpr[0], cfg.gpr[0]),
"csrw {}, x{}".format(hex(privileged_reg_t.MEPC), cfg.gpr[0])))
pkg_ins.pop_gpr_from_kernel_stack(privileged_reg_t.MSTATUS, privileged_reg_t.MSCRATCH,
cfg.mstatus_mprv, cfg.sp, cfg.tp, instr)
instr.append("mret")
self.gen_section(pkg_ins.get_label("illegal_instr_handler", hart), instr)
def gen_instr_fault_handler(self, hart):
pass
......@@ -655,7 +682,7 @@ class riscv_asm_program_gen:
def gen_interrupt_handler_section(self, mode, hart):
interrupt_handler_instr = []
ls_unit = "w" if rcs.XLEN == 32 else "d"
# ls_unit = "w" if rcs.XLEN == 32 else "d"
if mode < cfg.init_privileged_mode:
return
if(mode is privileged_mode_t.USER_MODE and not (rcs.support_umode_trap)):
......
......@@ -23,6 +23,7 @@ class riscv_data_page_gen:
def __init__(self):
self.data_page_str = []
self.mem_region_setting = defaultdict(list)
@staticmethod
def gen_data(idx, pattern, num_of_bytes, data):
temp_data = 0
......@@ -38,8 +39,6 @@ class riscv_data_page_gen:
def gen_data_page(self, hart_id, pattern, is_kernel=0, amo=0):
tmp_str = ""
temp_data = []
tmp_data = []
page_cnt = 0
page_size = 0
self.data_page_str.clear()
if is_kernel:
......@@ -48,31 +47,33 @@ class riscv_data_page_gen:
self.mem_region_setting = cfg.amo_region
else:
self.mem_region_setting = cfg.mem_region
for i in range(len(self.mem_region_setting)):
logging.info("mem_region_setting {}".format(self.mem_region_setting[i]))
for i in range(len(self.mem_region_setting)):
logging.info("Generate data section: {} size:0x{} xwr:0x{}".format(
self.mem_region_setting[i]["name"],
self.mem_region_setting[i]["size_in_bytes"],
self.mem_region_setting[i]["xwr"]))
self.mem_region_setting[i].name,
self.mem_region_setting[i].size_in_bytes,
self.mem_region_setting[i].xwr))
if amo:
if cfg.use_push_data_section:
self.data_page_str.append(".pushsection .{},\"aw\",@progbits;"
.format(self.mem_region_setting[i]["name"]))
.format(self.mem_region_setting[i].name))
else:
self.data_page_str.append(".section .{},\"aw\",@progbits;"
.format(self.mem_region_setting[i]["name"]))
self.data_page_str.append("{}:".format(self.mem_region_setting[i]["name"]))
.format(self.mem_region_setting[i].name))
self.data_page_str.append("{}:".format(self.mem_region_setting[i].name))
else:
if cfg.use_push_data_section:
self.data_page_str.append(".pushsection .{},\"aw\",@progbits;"
.format(pkg_ins.hart_prefix(hart_id) +
self.mem_region_setting[i]["name"]))
self.mem_region_setting[i].name))
else:
self.data_page_str.append(".section .{},\"aw\",@progbits;"
.format(pkg_ins.hart_prefix(hart_id) +
self.mem_region_setting[i]["name"]))
self.mem_region_setting[i].name))
self.data_page_str.append("{}:".format(pkg_ins.hart_prefix(hart_id) +
self.mem_region_setting[i]["name"]))
page_size = self.mem_region_setting[i]["size_in_bytes"]
self.mem_region_setting[i].name))
page_size = self.mem_region_setting[i].size_in_bytes
for i in range(0, page_size, 32):
if page_size - 1 >= 32:
temp_data = self.gen_data(idx=i, pattern=pattern,
......
......@@ -21,7 +21,9 @@ from pygen_src.riscv_instr_stream import riscv_rand_instr_stream
from pygen_src.isa.riscv_instr import riscv_instr
from pygen_src.riscv_instr_gen_config import cfg
from pygen_src.riscv_instr_pkg import (riscv_reg_t,
riscv_pseudo_instr_name_t, riscv_instr_name_t, pkg_ins)
riscv_pseudo_instr_name_t,
riscv_instr_name_t, pkg_ins,
mem_region_t)
from pygen_src.riscv_pseudo_instr import riscv_pseudo_instr
rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting")
......@@ -51,15 +53,16 @@ class riscv_mem_access_stream(riscv_directed_instr_stream):
super().__init__()
self.max_data_page_id = vsc.int32_t()
self.load_store_shared_memory = 0
self.data_page = {}
self.data_page = vsc.list_t(mem_region_t())
def pre_randomize(self):
self.data_page.clear()
if self.load_store_shared_memory:
self.data_page = cfg.amo_region
self.data_page.extend(cfg.amo_region)
elif self.kernel_mode:
self.data_page = cfg.s_mem_region
self.data_page.extend(cfg.s_mem_region)
else:
self.data_page = cfg.mem_region
self.data_page.extend(cfg.mem_region)
self.max_data_page_id = len(self.data_page)
def add_rs1_init_la_instr(self, gpr, idx, base = 0):
......@@ -67,13 +70,13 @@ class riscv_mem_access_stream(riscv_directed_instr_stream):
la_instr.pseudo_instr_name = riscv_pseudo_instr_name_t.LA
la_instr.rd = gpr
if self.load_store_shared_memory:
la_instr.imm_str = "{}+{}".format(cfg.amo_region[idx]['name'], base)
la_instr.imm_str = "{}+{}".format(cfg.amo_region[idx].name, base)
elif self.kernel_mode:
la_instr.imm_str = "{}{}+{}".format(pkg_ins.hart_prefix(self.hart),
cfg.s_mem_region[idx]['name'], base)
cfg.s_mem_region[idx].name, base)
else:
la_instr.imm_str = "{}{}+{}".format(pkg_ins.hart_prefix(self.hart),
cfg.mem_region[idx]['name'], base)
cfg.mem_region[idx].name, base)
self.instr_list.insert(0, la_instr)
def add_mixed_instr(self, instr_cnt):
......
"""
Copyright 2020 Google LLC
Copyright 2020 PerfectVIPs Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import vsc
import logging
from enum import IntEnum, auto
from importlib import import_module
from pygen_src.riscv_instr_gen_config import cfg
from pygen_src.riscv_instr_pkg import riscv_instr_group_t
rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting")
# ---------------------------------------------------------------------------------------------
# This class is used to generate illegal or HINT instructions.
# The illegal instruction will be generated in binary format and mixed with other valid instr.
# The mixed instruction stream will be stored in data section and loaded to instruction pages
# at run time.
# ---------------------------------------------------------------------------------------------
class illegal_instr_type_e(IntEnum):
kIllegalOpcode = 0
kIllegalCompressedOpcode = auto()
kIllegalFunc3 = auto()
kIllegalFunc7 = auto()
kReservedCompressedInstr = auto()
kHintInstr = auto()
kIllegalSystemInstr = auto()
class reserved_c_instr_e(IntEnum):
kIllegalCompressed = 0
kReservedAddispn = auto()
kReservedAddiw = auto()
kReservedAddi16sp = auto()
kReservedLui = auto()
kReservedLwsp = auto()
kReservedLdsp = auto()
kReservedLqsp = auto()
kReservedJr = auto()
kReservedC0 = auto()
kReservedC1 = auto()
kReservedC2 = auto()
@vsc.randobj
class riscv_illegal_instr:
def __init__(self):
self.comment = ""
self.exception = vsc.rand_enum_t(illegal_instr_type_e)
self.reserved_c = vsc.rand_enum_t(reserved_c_instr_e)
self.instr_bin = vsc.rand_bit_t(32)
self.opcode = vsc.rand_bit_t(7)
self.compressed = vsc.rand_bit_t(1)
self.func3 = vsc.rand_bit_t(3)
self.func7 = vsc.rand_bit_t(7)
self.has_func3 = vsc.rand_bit_t(1)
self.has_func7 = vsc.rand_bit_t(1)
self.c_op = vsc.rand_bit_t(2)
self.c_msb = vsc.rand_bit_t(3)
self.csrs = []
# Default legal self.opcode for RV32I instructions
self.legal_opcode = vsc.list_t(vsc.bit_t(7))
self.legal_opcode = [3, 15, 19, 23, 35, 55, 99, 51, 103, 115, 111]
# Default legal self.opcode for RV32C instructions
self.legal_c00_opcode = vsc.list_t(vsc.bit_t(3))
self.legal_c00_opcode = [0, 2, 6]
self.legal_c10_opcode = vsc.list_t(vsc.bit_t(3))
self.legal_c10_opcode = [0, 2, 4, 6]
self.xlen = vsc.uint8_t(0)
self.xlen = rcs.XLEN
self.temp_1 = vsc.bit_t(6)
@vsc.constraint
def exception_dist_c(self):
vsc.dist(self.exception,
[vsc.weight(illegal_instr_type_e.kIllegalOpcode, 3),
vsc.weight(illegal_instr_type_e.kIllegalCompressedOpcode, 1),
vsc.weight(illegal_instr_type_e.kIllegalFunc3, 1),
vsc.weight(illegal_instr_type_e.kIllegalFunc7, 1),
vsc.weight(illegal_instr_type_e.kReservedCompressedInstr, 1),
vsc.weight(illegal_instr_type_e.kHintInstr, 3),
vsc.weight(illegal_instr_type_e.kIllegalSystemInstr, 3)
])
@vsc.constraint
def instr_bit_assignment_c(self):
vsc.solve_order(self.opcode, self.instr_bin)
vsc.solve_order(self.func3, self.instr_bin)
vsc.solve_order(self.func7, self.instr_bin)
vsc.solve_order(self.c_msb, self.instr_bin)
# vsc.solve_order(self.c_op, self.instr_bin)
with vsc.if_then(self.compressed == 1):
self.instr_bin[1:0] == self.c_op
self.instr_bin[15:13] == self.c_msb
with vsc.else_then():
self.instr_bin[6:0] == self.opcode
with vsc.if_then(self.has_func7 == 1):
self.instr_bin[31:25] == self.func7
with vsc.if_then(self.has_func3 == 1):
self.instr_bin[14:12] == self.func3
# Invalid SYSTEM instructions
@vsc.constraint
def system_instr_c(self):
with vsc.if_then(self.exception == illegal_instr_type_e.kIllegalSystemInstr):
self.opcode == 115
# ECALL/EBREAK/xRET/WFI
with vsc.if_then(self.func3 == 0):
# Constrain RS1 and RD to be non-zero
self.instr_bin[19:15] != 0
self.instr_bin[11:7] != 0
# Valid SYSTEM instructions considered by this
# Constrain the upper 12 bits to be invalid
self.instr_bin[31:20].not_inside(vsc.rangelist(0, 1, 2, 258, 770, 1970, 261))
with vsc.else_then():
# Invalid CSR instructions
self.instr_bin[31:20].not_inside(vsc.rangelist(self.csrs))
# self.instr_bin[20:31].not_inside(vsc.rangelist(self.custom_csr))
@vsc.constraint
def legal_rv32_c_slli(self):
with vsc.if_then((self.c_msb == 0) and (self.c_op == 2) and (self.xlen == 32)):
with vsc.if_then(self.exception == illegal_instr_type_e.kReservedCompressedInstr):
self.instr_bin[12] == 1
with vsc.else_then():
self.instr_bin[12] == 0
@vsc.constraint
def exception_type_c(self):
with vsc.if_then(self.compressed == 1):
self.exception.inside(vsc.rangelist(illegal_instr_type_e.kReservedCompressedInstr,
illegal_instr_type_e.kIllegalCompressedOpcode,
illegal_instr_type_e.kHintInstr))
with vsc.else_then():
self.exception.inside(vsc.rangelist(illegal_instr_type_e.kIllegalOpcode,
illegal_instr_type_e.kIllegalFunc3,
illegal_instr_type_e.kIllegalFunc7,
illegal_instr_type_e.kIllegalSystemInstr))
with vsc.if_then(self.has_func7 == 0):
self.exception != illegal_instr_type_e.kIllegalFunc7
with vsc.if_then(self.has_func3 == 0):
self.exception != illegal_instr_type_e.kIllegalFunc3
@vsc.constraint
def compressed_instr_op_c(self):
self.c_op != 3
# Avoid generating illegal func3/func7 errors for self.opcode used by B-extension for now
# TODO: add support for generating illegal B-extension instructions
@vsc.constraint
def b_extension_c(self):
if riscv_instr_group_t.RV32B in rcs.supported_isa:
with vsc.if_then(self.exception in [illegal_instr_type_e.kIllegalFunc3,
illegal_instr_type_e.kIllegalFunc7]):
self.opcode.inside(vsc.rangelist([51, 19, 59]))
@vsc.constraint
def illegal_compressed_op_c(self):
with vsc.if_then(self.exception == illegal_instr_type_e.kIllegalCompressedOpcode):
self.c_op != 1
with vsc.if_then(self.legal_c00_opcode.size == 8):
self.c_op != 0
with vsc.else_then():
self.c_msb.not_inside(vsc.rangelist(self.legal_c00_opcode))
with vsc.if_then(self.legal_c10_opcode.size == 8):
self.c_op != 2
with vsc.else_then():
self.c_msb.not_inside(vsc.rangelist(self.legal_c10_opcode))
@vsc.constraint
def reserved_compressed_instr_c(self):
vsc.solve_order(self.exception, self.reserved_c)
vsc.solve_order(self.exception, self.opcode)
vsc.solve_order(self.reserved_c, self.instr_bin)
vsc.solve_order(self.reserved_c, self.c_msb)
vsc.solve_order(self.reserved_c, self.c_op)
with vsc.if_then(self.xlen == 32):
# c.addiw is RV64/RV128 only instruction, the encoding is used for C.JAL for RV32C
self.reserved_c != reserved_c_instr_e.kReservedAddiw
with vsc.if_then(self.exception == illegal_instr_type_e.kReservedCompressedInstr):
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kIllegalCompressed):
self.instr_bin[15:0] == 0
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedAddispn):
((self.instr_bin[15:0] == 0) and (self.c_op == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedAddiw):
((self.c_msb == 1) and (self.c_op == 1) and
(self.instr_bin[11:7] == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedC0):
((self.instr_bin[15:10] == 39) and
(self.instr_bin[6:5] == 2) and (self.c_op == 1))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedC1):
((self.instr_bin[15:10] == 39) and
(self.instr_bin[6:5] == 3) and (self.c_op == 1))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedC2):
((self.c_msb == 4) and (self.c_op == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedAddi16sp):
((self.c_msb == 3) and (self.c_op == 1) and
(self.instr_bin[11:7] == 2) and
(not self.instr_bin[12]) and (self.instr_bin[6:2] == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedLui):
((self.c_msb == 3) and (self.c_op == 1) and
(not self.instr_bin[12]) and (self.instr_bin[6:2] == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedJr):
self.instr_bin == 32770
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedLqsp):
((self.c_msb == 1) and (self.c_op == 2) and
(self.instr_bin[11:7] == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedLwsp):
((self.c_msb == 2) and (self.c_op == 2) and
(self.instr_bin[11:7] == 0))
with vsc.if_then(self.reserved_c == reserved_c_instr_e.kReservedLdsp):
((self.c_msb == 3) and (self.c_op == 2) and (self.instr_bin[11:7] == 0))
@vsc.constraint
def hint_instr_c(self):
with vsc.if_then(self.exception == illegal_instr_type_e.kHintInstr):
((self.c_msb == 0) and (self.c_op == 1) and (self.instr_bin[12] +
self.instr_bin[6:2] == 0)) or \
((self.c_msb == 2) and (self.c_op == 1) and (self.instr_bin[11:7] == 0)) or \
((self.c_msb == 4) and (self.c_op == 1) and (self.instr_bin[12:11] == 0) and
(self.instr_bin[6:2] == 0)) or \
((self.c_msb == 4) and (self.c_op == 2) and (self.instr_bin[11:7] == 0) and
(self.instr_bin[6:2] != 0)) or \
((self.c_msb == 3) and (self.c_op == 1) and (self.instr_bin[11:7] == 0) and
(self.instr_bin[12] + self.instr_bin[6:2]) != 0) or \
((self.c_msb == 0) and (self.c_op == 2) and (self.instr_bin[11:7] == 0)) or \
((self.c_msb == 0) and (self.c_op == 2) and (self.instr_bin[11:7] != 0) and
not(self.instr_bin[12]) and (self.instr_bin[6:2] == 0)) or \
((self.c_msb == 4) and (self.c_op == 2) and (self.instr_bin[11:7] == 0) and
self.instr_bin[12] and (self.instr_bin[6:2] != 0))
@vsc.constraint
def illegal_opcode_c(self):
vsc.solve_order(self.opcode, self.instr_bin)
with vsc.if_then(self.exception == illegal_instr_type_e.kIllegalOpcode):
self.opcode.not_inside(vsc.rangelist(self.legal_opcode))
self.opcode[1:0] == 3