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 illegal_func3_c(self): vsc.solve_order(self.opcode, self.func3) with vsc.if_then(self.compressed == 0): with vsc.if_then( self.exception == illegal_instr_type_e.kIllegalFunc3): with vsc.if_then(self.opcode == 103): self.func3 != 0 with vsc.if_then(self.opcode == 99): self.func3.inside(vsc.rangelist(2, 3)) with vsc.if_then(self.xlen == 32): with vsc.if_then(self.opcode == 35): self.func3 >= 3 with vsc.if_then(self.opcode == 3): self.func3.inside(vsc.rangelist(3, 7)) with vsc.else_then(): with vsc.if_then(self.opcode == 35): self.func3 > 3 with vsc.if_then(self.opcode == 3): self.func3 == 7 with vsc.if_then(self.opcode == 15): self.func3.not_inside(vsc.rangelist(0, 1)) with vsc.if_then(self.opcode == 115): self.func3 == 4 with vsc.if_then(self.opcode == 27): self.func3.not_inside(vsc.rangelist(0, 1, 5)) with vsc.if_then(self.opcode == 59): self.func3.inside(vsc.rangelist(2, 3)) self.opcode.inside( vsc.rangelist(103, 99, 3, 35, 15, 115, 27, 59)) with vsc.else_then(): with vsc.if_then(self.opcode == 103): self.func3 == 0 with vsc.if_then(self.opcode == 99): self.func3.inside(vsc.rangelist(2, 3)) with vsc.if_then(self.xlen == 32): with vsc.if_then(self.opcode == 35): self.func3 < 3 with vsc.if_then(self.opcode == 3): self.func3.inside(vsc.rangelist(3, 7)) with vsc.else_then(): with vsc.if_then(self.opcode == 35): self.func3 <= 3 with vsc.if_then(self.opcode == 3): self.func3 != 7 with vsc.if_then(self.opcode == 15): self.func3.inside(vsc.rangelist(0, 1)) with vsc.if_then(self.opcode == 115): self.func3 != 4 with vsc.if_then(self.opcode == 27): self.func3.inside(vsc.rangelist(0, 1, 5)) with vsc.if_then(self.opcode == 59): self.func3.not_inside(vsc.rangelist(2, 3))
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 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 has_func7_c(self): vsc.solve_order(self.opcode, self.func7) with vsc.if_then((self.opcode == 19) and (self.func3 == 1 or self.func3 == 5) or (self.opcode == 51 or self.opcode == 59)): self.has_func7 == 1 with vsc.else_then(): self.has_func7 == 0
def addr_translation_c(self): with vsc.if_then( (self.init_privil_mode != privileged_mode_t.MACHINE_MODE) & (self.SATP_MODE != satp_mode_t.BARE)): self.virtual_addr_translation_on == 1 with vsc.else_then(): self.virtual_addr_translation_on == 0
def aligned_amo_c(self): with vsc.foreach(self.offset, idx = True) as i: with vsc.if_then(self.XLEN == 32): self.offset[i] % 4 == 0 with vsc.else_then(): self.offset[i] % 8 == 0
def has_func3_c(self): vsc.solve_order(self.opcode, self.func7) with vsc.if_then(self.opcode == 55 or self.opcode == 111 or self.opcode == 23): self.has_func3 == 0 with vsc.else_then(): self.has_func3 == 1
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
def ab_c(self): self.a == 1 with vsc.if_then(self.a == 1): self.b == 1 with vsc.else_then(): self.b == 2
def mtvec_c(self): self.mtvec_mode.inside(vsc.rangelist(self.supported_interrupt_mode)) with vsc.if_then(self.mtvec_mode == mtvec_mode_t.DIRECT): vsc.soft(self.tvec_alignment == 2) with vsc.else_then(): # Setting MODE = Vectored may impose an additional alignmentconstraint on BASE, # requiring up to 4×XLEN-byte alignment vsc.soft(self.tvec_alignment == self.tvec_ceil)
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 mstatus_c(self): with vsc.if_then(self.set_mstatus_mprv == 1): self.mstatus_mprv == 1 with vsc.else_then(): self.mstatus_mprv == 0 with vsc.if_then(self.SATP_MODE == satp_mode_t.BARE): self.mstatus_mxr == 0 self.mstatus_sum == 0 self.mstatus_tvm == 0
def post_randomize(self): last_level = 0 last_level = self.stack_level[self.program_cnt - 1] for i in range(len(self.program_h)): self.program_h[i].program_id = i self.program_h[i].call_stack_level = self.stack_level[i] # Top-down generate the entire call stack. # A program can only call the programs in the next level. for i in range(last_level): program_list = [] next_program_list = [] sub_program_id_pool = vsc.randlist_t() sub_program_cnt = [] idx = 0 for j in range(self.program_cnt): if self.stack_level[j] == i: program_list.append(j) if self.stack_level[j] == i + 1: next_program_list.append(j) # Randmly duplicate some sub programs in the pool to create a case that # one sub program is called by multiple caller. Also it's possible to call # the same sub program in one program multiple times. total_sub_program_cnt = random.randrange( len(next_program_list), len(next_program_list) + 1) sub_program_id_pool = [0] * total_sub_program_cnt for i in range(len(sub_program_id_pool)): with sub_program_id_pool[i].randomize_with(): with vsc.if_then(sub_program_id_pool[i]): sub_program_id_pool[i] == next_program_list[i] with vsc.else_then(): sub_program_id_pool[i].inside( vsc.rangelist(next_program_list)) random.shuffle(sub_program_id_pool) sub_program_cnt = [0] * len(program_list) logging.info( "{} programs @Lv{}-> {} programs at next level".format( len(program_list), i, len(sub_program_id_pool))) # Distribute the programs of the next level among the programs of current level # Make sure all program has a caller so that no program is obsolete. for j in range(len(sub_program_id_pool)): caller_id = random.randrange(0, len(sub_program_cnt) - 1) sub_program_cnt[caller_id] += 1 for j in range(len(program_list)): id = program_list[j] self.program_h[id].sub_program_id = [0] * sub_program_cnt[j] logging.info( "{} sub programs are assigned to program[{}]".format( sub_program_cnt[j], id)) for k in range(len(self.program_h[id].sub_program_id)): self.program_h[id].sub_program_id[k] = sub_program_id_pool[ idx] idx += 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 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
def ab_c(self): self.a == 5 with vsc.if_then(self.a == 1): self.b == 1 with vsc.else_if(self.a == 2): self.b == 2 with vsc.else_if(self.a == 3): self.b == 4 with vsc.else_if(self.a == 4): self.b == 8 with vsc.else_if(self.a == 5): self.b == 16 with vsc.else_then(): self.b == 0
def loop_c(self): vsc.solve_order(self.num_of_nested_loop, self.loop_init_val) vsc.solve_order(self.num_of_nested_loop, self.loop_step_val) vsc.solve_order(self.num_of_nested_loop, self.loop_limit_val) vsc.solve_order(self.loop_limit_val, self.loop_limit_reg) vsc.solve_order(self.branch_type, self.loop_init_val) vsc.solve_order(self.branch_type, self.loop_step_val) vsc.solve_order(self.branch_type, self.loop_limit_val) self.num_of_instr_in_loop.inside(vsc.rangelist((1, 25))) self.num_of_nested_loop.inside(vsc.rangelist(1, 2)) self.loop_init_val.size.inside(vsc.rangelist(1, 2)) self.loop_step_val.size.inside(vsc.rangelist(1, 2)) self.loop_limit_val.size.inside(vsc.rangelist(1, 2)) self.branch_type.size.inside(vsc.rangelist(1, 2)) self.loop_init_val.size == self.num_of_nested_loop self.branch_type.size == self.num_of_nested_loop self.loop_step_val.size == self.num_of_nested_loop self.loop_limit_val.size == self.num_of_nested_loop self.branch_type.size == self.num_of_nested_loop with vsc.foreach(self.branch_type, idx=True) as i: with vsc.if_then(cfg.disable_compressed_instr == 0): self.branch_type[i].inside( vsc.rangelist( riscv_instr_name_t.C_BNEZ, riscv_instr_name_t.C_BEQZ, riscv_instr_name_t.BEQ, riscv_instr_name_t.BNE, riscv_instr_name_t.BLTU, riscv_instr_name_t.BLT, riscv_instr_name_t.BGEU, riscv_instr_name_t.BGE)) with vsc.else_then(): self.branch_type[i].inside( vsc.rangelist(riscv_instr_name_t.BEQ, riscv_instr_name_t.BNE, riscv_instr_name_t.BLTU, riscv_instr_name_t.BLT, riscv_instr_name_t.BGEU, riscv_instr_name_t.BGE)) with vsc.foreach(self.loop_init_val, idx=True) as i: with vsc.if_then(self.branch_type[i].inside( vsc.rangelist(riscv_instr_name_t.C_BNEZ, riscv_instr_name_t.C_BEQZ))): self.loop_limit_val[i] == 0 self.loop_limit_reg[i] == riscv_reg_t.ZERO self.loop_cnt_reg[i].inside(vsc.rangelist(compressed_gpr)) with vsc.else_then: self.loop_limit_val[i].inside(vsc.rangelist((-20, 20))) self.loop_limit_reg[i] != riscv_reg_t.ZERO with vsc.if_then(self.branch_type[i].inside( vsc.rangelist(riscv_instr_name_t.C_BNEZ, riscv_instr_name_t.C_BEQZ, riscv_instr_name_t.BEQ, riscv_instr_name_t.BNE))): self.loop_limit_val[i] != self.loop_init_val[i] ((self.loop_limit_val[i] - self.loop_init_val[i]) % self.loop_step_val[i]) == 0 with vsc.else_if(self.branch_type[i] == riscv_instr_name_t.BGE): self.loop_step_val[i] < 0 with vsc.else_if(self.branch_type[i].inside( vsc.rangelist(riscv_instr_name_t.BGEU))): self.loop_step_val[i] < 0 self.loop_init_val[i] > 0 # Avoid count to negative (self.loop_step_val[i] + self.loop_limit_val[i]) > 0 with vsc.else_if(self.branch_type[i] == riscv_instr_name_t.BLT): self.loop_step_val[i] > 0 with vsc.else_if(self.branch_type[i] == riscv_instr_name_t.BLTU): self.loop_step_val[i] > 0 self.loop_limit_val[i] > 0 self.loop_init_val[i].inside(vsc.rangelist((-10, 10))) self.loop_step_val[i].inside(vsc.rangelist((-10, 10))) with vsc.if_then(self.loop_init_val[i] < self.loop_limit_val[i]): self.loop_step_val[i] > 0 with vsc.else_then: self.loop_step_val[i] < 0
def floating_point_c(self): with vsc.if_then(self.enable_floating_point): self.mstatus_fs == 1 with vsc.else_then(): self.mstatus_fs == 0
def my_a_c(self): self.a < 10 with vsc.if_then(self.a == 2): self.b < 1000 with vsc.else_then(): self.b < 2000
def ab_c(self): with vsc.if_then(self.a < self.b): self.c < self.d with vsc.else_then(): self.c == self.d
def mtvec_c(self): self.mtvec_mode.inside(vsc.rangelist(self.supported_interrupt_mode)) 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 == self.tvec_ceil)