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 with vsc.else_then(): self.opcode.inside(vsc.rangelist(self.legal_opcode))
def randomize_offset(self): print("randomize_offset " + str(self.num)) addr_ = vsc.rand_int32_t() offset_ = vsc.rand_int32_t() self.offset = [0] * self.num self.addr = [0] * self.num for i in range(self.num): try: with vsc.randomize_with(addr_, offset_): if self.level == level_t.LOW: offset_.inside( vsc.rangelist(vsc.rng(-256, 256))) elif self.level == level_t.MEDIUM: offset_.inside( vsc.rangelist(vsc.rng(-512, 512))) elif self.level == level_t.HIGH: offset_.inside( vsc.rangelist(vsc.rng(-1024, 1024))) addr_ == self.num + offset_ addr_.inside(vsc.rangelist(vsc.rng(0, 32))) except SolveFailure as e: print("Cannot Randomize offset: " + e.diagnostics) self.offset[i] = offset_ self.addr[i] = addr_
def gen_amo_instr(self): allowed_lr_instr = [] allowed_sc_instr = [] if riscv_instr_group_t.RV32A in rcs.supported_isa: allowed_lr_instr.append(riscv_instr_name_t.LR_W) allowed_sc_instr.append(riscv_instr_name_t.SC_W) if riscv_instr_group_t.RV64A in rcs.supported_isa: allowed_lr_instr.append(riscv_instr_name_t.LR_D) allowed_sc_instr.append(riscv_instr_name_t.SC_D) self.lr_instr = riscv_instr.get_rand_instr( include_instr=allowed_lr_instr) self.sc_instr = riscv_instr.get_rand_instr( include_instr=allowed_sc_instr) with self.lr_instr.randomize_with(): # self.lr_instr.rs1 == self.rs1_reg[0] # TODO Getting error with vsc.if_then(self.reserved_rd.size > 0): self.lr_instr.rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.lr_instr.rd.not_inside(vsc.rangelist(cfg.reserved_regs)) # self.lr_instr.rd != self.rs1_reg[0] # TODO with self.sc_instr.randomize_with(): # self.sc_instr.rs1 == self.rs1_reg[0] # TODO with vsc.if_then(self.reserved_rd.size > 0): self.sc_instr.rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.sc_instr.rd.not_inside(vsc.rangelist(cfg.reserved_regs)) # self.sc_instr.rd != self.rs1_reg[0] # TODO self.instr_list.extend((self.lr_instr, self.sc_instr))
def ab_c(self): self.a < 8 self.a in vsc.rangelist(1, 4, 8) self.b in vsc.rangelist((2, 4), (8, 12)) self.b < 11 self.c in vsc.rangelist((2, 4), (8, 12)) self.c < 4
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, 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): 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): 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): 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): self.rd == riscv_reg_t.SP with vsc.implies(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
def test_2(self): @vsc.randobj class my_sub_s(object): def __init__(self): self.has_rs1 = vsc.uint8_t(1) self.has_rs2 = vsc.uint8_t(1) self.has_rd = vsc.uint8_t(1) self.avail_regs = vsc.rand_list_t(vsc.uint8_t(0), 10) self.reserved_rd = vsc.rand_list_t(vsc.uint8_t(0), 10) self.reserved_regs = vsc.rand_list_t(vsc.uint8_t(0), 10) self.rd = vsc.rand_uint8_t(0) self.rs1 = vsc.rand_uint8_t(0) self.rs2 = vsc.rand_uint8_t(0) self.format = vsc.uint8_t(2) obj = my_sub_s() with obj.randomize_with() as it: with vsc.if_then(obj.avail_regs.size > 0): with vsc.if_then(obj.has_rs1): obj.rs1.inside(vsc.rangelist(obj.avail_regs)) with vsc.if_then(obj.has_rs2): obj.rs2.inside(vsc.rangelist(obj.avail_regs)) with vsc.if_then(obj.has_rd): obj.rd.inside(vsc.rangelist(obj.avail_regs)) with vsc.foreach(obj.reserved_rd, idx=True) as i: with vsc.if_then(obj.has_rd): obj.rd != obj.reserved_rd[i] with vsc.if_then(obj.format == 2): obj.rs1 != obj.reserved_rd[i] with vsc.foreach(obj.reserved_regs, idx=True) as i: with vsc.if_then(obj.has_rd): obj.rd != obj.reserved_regs[i] with vsc.if_then(obj.format == 2): obj.rs1 != obj.reserved_regs[i]
def default_c(self): self.sub_program_instr_cnt.size == self.num_of_sub_program self.debug_sub_program_instr_cnt.size == self.num_debug_sub_program self.main_program_instr_cnt in vsc.rangelist( vsc.rng(10, self.instr_cnt)) with vsc.foreach(self.sub_program_instr_cnt, idx=True) as i: self.sub_program_instr_cnt[i].inside( vsc.rangelist(vsc.rng(10, self.instr_cnt)))
def ab_c(self): self.a in vsc.rangelist(1, 2, 4, 8) self.c != 0 self.d != 0 self.c < self.d self.b in vsc.rangelist(vsc.rng(self.c, self.d))
def sp_tp_c(self): with vsc.if_then(self.fix_sp == 1): self.sp == riscv_reg_t.SP self.sp != self.tp self.sp.not_inside( vsc.rangelist(riscv_reg_t.GP, riscv_reg_t.RA, riscv_reg_t.ZERO)) self.tp.not_inside( vsc.rangelist(riscv_reg_t.GP, riscv_reg_t.RA, riscv_reg_t.ZERO))
def illegal_func7_c(self): with vsc.if_then(self.compressed == 0): with vsc.if_then(self.exception == illegal_instr_type_e.kIllegalFunc7): self.func7.not_inside(vsc.rangelist(0, 32, 1)) with vsc.if_then(self.opcode == 9): # SLLI, SRLI, SRAI self.func7[6:1].not_inside(vsc.rangelist(0, 16)) with vsc.else_then(): self.func7.inside(vsc.rangelist(0, 32, 1))
def sp_tp_c(self): if self.fix_sp: self.sp == riscv_reg_t.SP self.sp != self.tp self.sp.not_inside(vsc.rangelist(riscv_reg_t.GP, riscv_reg_t.RA, riscv_reg_t.ZERO)) self.tp.not_inside(vsc.rangelist(riscv_reg_t.GP, riscv_reg_t.RA, riscv_reg_t.ZERO))
def ab_c(self): # self.a in vsc.rangelist(self.b+1, [self.b+2,self.c], 8) self.a in vsc.rangelist(1, 2, 4, 8) self.c != 0 self.d != 0 self.c < self.d self.b in vsc.rangelist(vsc.rng(self.c, self.d))
def gpr_c(self): self.gpr0.not_inside(vsc.rangelist(self.sp, self.tp, self.scratch_reg, self.pmp_reg, riscv_reg_t.ZERO, riscv_reg_t.RA, riscv_reg_t.GP)) self.gpr1.not_inside(vsc.rangelist(self.sp, self.tp, self.scratch_reg, self.pmp_reg, riscv_reg_t.ZERO, riscv_reg_t.RA, riscv_reg_t.GP)) self.gpr2.not_inside(vsc.rangelist(self.sp, self.tp, self.scratch_reg, self.pmp_reg, riscv_reg_t.ZERO, riscv_reg_t.RA, riscv_reg_t.GP)) self.gpr3.not_inside(vsc.rangelist(self.sp, self.tp, self.scratch_reg, self.pmp_reg, riscv_reg_t.ZERO, riscv_reg_t.RA, riscv_reg_t.GP)) vsc.unique(self.gpr0, self.gpr1, self.gpr2, self.gpr3)
def imm_val_c(self): with vsc.implies(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): self.imm[31:5] == 0 with vsc.implies(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): self.imm[1:0] == 0
def a_c(self): self.a in vsc.rangelist((1,9)) self.b in vsc.rangelist((1,9)) self.c in vsc.rangelist((1,9)) self.d in vsc.rangelist((1,9)) self.e in vsc.rangelist((1,9)) self.f in vsc.rangelist((1,9)) self.g in vsc.rangelist((1,9)) self.h in vsc.rangelist((1,9)) self.i in vsc.rangelist((1,9)) self.j in vsc.rangelist((1,9))
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))
def gen_amo_instr(self): for i in range(self.num_amo): self.amo_instr.append(riscv_instr.get_rand_instr( include_category=[riscv_instr_category_t.AMO])) with self.amo_instr[i].randomize_with(): with vsc.if_then(self.reserved_rd.size > 0): self.amo_instr[i].rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.amo_instr[i].rd.not_inside(vsc.rangelist(cfg.reserved_regs)) self.amo_instr[i].rs1.inside(vsc.rangelist(self.rs1_reg)) self.amo_instr[i].rd.inside(vsc.rangelist(self.rs1_reg)) self.instr_list.insert(0, self.amo_instr[i])
def imm_c(self): with vsc.implies(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, riscv_instr_name_t.SRLI, riscv_instr_name_t.SRAI))): with vsc.implies(self.XLEN == 32): self.imm[11:5] == 0 with vsc.implies(self.XLEN != 32): self.imm[11:6] == 0
def ab_c(self): with vsc.foreach(self.a_list, idx=True) as i: if self.c: self.a_list[i] in vsc.rangelist(5,6,7,8) else: self.a_list[i] in vsc.rangelist(10,11,12,13) with vsc.foreach(self.temp_list, idx=True) as i: with vsc.if_then(self.a_list[i].inside(vsc.rangelist(6,7))): self.temp_list[i] == 0 with vsc.else_then: self.temp_list[i] == 1
def ab_c(self): with vsc.foreach(self.a_list, idx=True) as i: if self.c: self.a_list[i] in vsc.rangelist(5,6,7,8) else: self.a_list[i] in vsc.rangelist(10,11,12,13) with vsc.foreach(self.temp_list, idx=True) as i: if self.a_list[i] in [6,7]: self.temp_list[i] == 0 else: self.temp_list[i] == 1
def randomize_avail_regs(self): if self.avail_regs.size > 0: try: with vsc.randomize_with(self.avail_regs): vsc.unique(self.avail_regs) self.avail_regs[0].inside( vsc.rangelist(vsc.rng(riscv_reg_t.S0, riscv_reg_t.A5))) with vsc.foreach(self.avail_regs, idx=True) as i: self.avail_regs[i].not_inside( vsc.rangelist(cfg.reserved_regs, self.reserved_rd)) except Exception: logging.critical("Cannot randomize avail_regs") sys.exit(1)
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
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))
def gpr_c(self): with vsc.foreach(self.gpr, idx=True) as i: self.gpr[i].not_inside( vsc.rangelist(self.sp, self.tp, self.scratch_reg, self.pmp_reg, riscv_reg_t.ZERO, riscv_reg_t.RA, riscv_reg_t.GP)) vsc.unique(self.gpr)
def mtvec_c(self): self.mtvec_mode.inside( vsc.rangelist(mtvec_mode_t.DIRECT, mtvec_mode_t.VECTORED)) if (self.mtvec_mode == mtvec_mode_t.DIRECT): vsc.soft(self.tvec_alignment == 2) else: vsc.soft(self.tvec_alignment == (rcs.XLEN * 4) / 8)
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]))
def test_in_list_comb(self): @vsc.randobj class my_s(object): def __init__(self): super().__init__() self.a = vsc.rand_bit_t(8) self.b = vsc.rand_bit_t(8) self.l = vsc.list_t(vsc.uint8_t()) for i in range(4): self.l.append(i) @vsc.constraint def ab_c(self): self.a in vsc.rangelist(self.l, 10, 12, 14) v = my_s() with v.randomize_with() as it: it.a in vsc.rangelist(0, 1, 2, 3) self.assertTrue(v.a in [0, 1, 2, 3]) # Now, clear the list so only 10, 12, 14 exist v.l.clear() v.randomize() self.assertTrue(v.a in [10, 12, 14])
def generate_return_routine(self, prefix): routine_str = '' jump_instr = [riscv_instr_name_t.JALR] rand_lsb = random.randrange(0, 1) ra = vsc.rand_enum_t(riscv_reg_t) try: with vsc.randomize_with(ra): ra.not_inside(vsc.rangelist(cfg.reserved_regs)) ra != riscv_reg_t.ZERO except Exception: logging.critical("Cannot randomize ra") sys.exit(1) routine_str = prefix + "addi x{} x{} {}".format( ra.get_val(), cfg.ra, rand_lsb) self.instr_string_list.append(routine_str) if not cfg.disable_compressed_instr: jump_instr.append(riscv_instr_name_t.C_JR) if not (riscv_reg_t.RA in cfg.reserved_regs): jump_instr.append(riscv_instr_name_t.C_JALR) i = random.randrange(0, len(jump_instr) - 1) if jump_instr[i] == riscv_instr_name_t.C_JALR: routine_str = prefix + "c.jalr x{}".format(ra.get_val()) elif jump_instr[i] == riscv_instr_name_t.C_JR: routine_str = prefix + "c.jr x{}".format(ra.get_val()) elif jump_instr[i] == riscv_instr_name_t.JALR: routine_str = prefix + "jalr x{} x{} 0".format( ra.get_val(), ra.get_val()) else: logging.critical("Unsupported jump_instr: {}".format( jump_instr[i])) sys.exit(1) self.instr_string_list.append(routine_str)
def mtvec_c(self): self.mtvec_mode.inside( vsc.rangelist(mtvec_mode_t.DIRECT, mtvec_mode_t.VECTORED)) with vsc.if_then(self.mtvec_mode == mtvec_mode_t.DIRECT): vsc.soft(self.tvec_alignment == 2) with vsc.else_then(): vsc.soft(self.tvec_alignment == (rcs.XLEN * 4) // 8)
def generate_return_routine(self, prefix): string = '' jump_instr = [riscv_instr_name_t.JALR] rand_lsb = random.randrange(0, 1) ra = vsc.rand_enum_t(riscv_reg_t) try: with vsc.randomize_with(ra): ra.not_inside(vsc.rangelist(cfg.reserved_regs)) ra != riscv_reg_t.ZERO except Exception: logging.critical("Cannot randomize ra") sys.exit(1) string = (prefix + pkg_ins.format_string("{}addi x{} x{} {}".format( ra.name, cfg.ra.name, rand_lsb))) self.instr_string_list.append(string) if (not cfg.disable_compressed_instr): jump_instr.append(riscv_instr_name_t.C_JR) if (not (riscv_reg_t.RA in {cfg.reserved_regs})): jump_instr.append(riscv_instr_name_t.C_JALR) i = random.randrange(0, len(jump_instr) - 1) if (jump_instr[i] == riscv_instr_name_t.C_JAL): string = prefix + pkg_ins.format_string("{}c.jalr x{}".format( ra.name)) elif (jump_instr[i] == riscv_instr_name_t.C_JR): string = prefix + pkg_ins.format_string("{}c.jr x{}".format( ra.name)) elif (jump_instr[i] == riscv_instr_name_t.JALR): string = prefix + pkg_ins.format_string( "{}c.jalr x{} x{} 0".format(ra.name, ra.name)) else: logging.critical("Unsupported jump_instr: %0s" % (jump_instr[i])) sys.exit(1) self.instr_string_list.append(string)