def insert_illegal_hint_instr(self): idx = 0 insert_str = "" self.illegal_instr.initialize() bin_instr_cnt = int(self.instr_cnt * cfg.illegal_instr_ratio / 1000) if bin_instr_cnt >= 0: logging.info( "Injecting {} illegal instructions, ratio {}/100".format( bin_instr_cnt, cfg.illegal_instr_ratio)) for _ in range(bin_instr_cnt): with vsc.randomize_with(self.illegal_instr): self.illegal_instr.exception != illegal_instr_type_e.kHintInstr insert_str = "{}.4byte {} # {}".format( pkg_ins.indent, self.illegal_instr.get_bin_str(), self.illegal_instr.comment) idx = random.randrange(0, len(self.instr_string_list)) self.instr_string_list.insert(idx, insert_str) bin_instr_cnt = int(self.instr_cnt * cfg.hint_instr_ratio / 1000) if bin_instr_cnt >= 0: logging.info("Injecting {} HINT instructions, ratio {}/100".format( bin_instr_cnt, cfg.hint_instr_ratio)) for _ in range(int(bin_instr_cnt)): with vsc.randomize_with(self.illegal_instr): self.illegal_instr.exception == illegal_instr_type_e.kHintInstr insert_str = "{}.2byte {} # {}".format( pkg_ins.indent, self.illegal_instr.get_bin_str(), self.illegal_instr.comment) idx = random.randrange(0, len(self.instr_string_list)) self.instr_string_list.insert(idx, insert_str)
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 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 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)
def test_simple_rand_inline2(self): a = vsc.rand_uint8_t() b = vsc.rand_uint8_t() for i in range(10): with vsc.randomize_with(a, b): a < b self.assertLess(a.val, b.val)
def test_sum_overflow(self): list = vsc.rand_list_t(vsc.rand_bit_t(32), 8) for i in range(10): with vsc.randomize_with(list): list.sum <= 4096 self.assertLessEqual(list.sum, 4096)
def test_simple_intenum2(self): class my_e(IntEnum): A = auto() B = auto() a = vsc.rand_enum_t(my_e) b = vsc.rand_enum_t(my_e) for i in range(10): with vsc.randomize_with(a, b): a != b self.assertNotEqual(a.get_val(), b.get_val())
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 gen_stack_enter_instr(self): allow_branch = 0 if (self.illegal_instr_pct > 0 or self.hint_instr_pct > 0) else 1 allow_branch &= not cfg.no_branch_jump try: with vsc.randomize_with(self.program_stack_len): self.program_stack_len in vsc.rangelist(vsc.rng(cfg.min_stack_len_per_program, cfg.max_stack_len_per_program)) self.program_stack_len % (rcs.XLEN // 8) == 0 except Exception: logging.critical("Cannot randomize program_stack_len") sys.exit(1) self.instr_stack_enter.push_start_label = self.label_name + "_stack_p" self.instr_stack_enter.gen_push_stack_instr(self.program_stack_len, allow_branch = allow_branch) self.instr_stream.instr_list.extend((self.instr_stack_enter.instr_list))
async def run_xfer(self): channel = vsc.rand_uint32_t() xfer_spec = XferSpec() # Randomly select a channel not currently in use with vsc.randomize_with(channel): channel < self.n_channels with vsc.foreach(self.active_channels, idx=True) as i: with vsc.implies(i == channel): self.active_channels[i] == False print("channel: " + str(channel)) self.active_xfers += 1 self.active_channels[channel] = True xfer_spec.randomize() # TODO: program channel ch = self.dma_regs.channel(int(channel)) sz = await ch.read_sz() sz.chk_sz = xfer_spec.chksz sz.tot_sz = xfer_spec.totsz await ch.write_sz(sz) csr = await ch.read_csr() csr.ine_done = 1 csr.inc_src = xfer_spec.inc_src csr.inc_dst = xfer_spec.inc_dst print("INC_SRC: " + str(csr.inc_src) + " INC_DST: " + str(csr.inc_dst)) csr.en = 1 await ch.write_csr(csr) await ch.write_src_addr(0x00000000 | int(channel) << 16) await ch.write_dst_addr(0x80000000 | int(channel) << 16) # TODO: start xfer # Wait for completion await self.done_ev[int(channel)].wait() self.done_ev[int(channel)].clear() # TODO: program and carry out transfer # await cocotb.triggers.Timer(1, "us") self.active_xfers -= 1 print("Channel " + str(channel) + " done " + str(self.active_xfers)) self.active_channels[channel] = False self.n_complete += 1 pass
def init_gpr(self): reg_val = vsc.rand_bit_t(pkg_ins.DATA_WIDTH) for i in range(rcs.NUM_GPR): if i in [cfg.sp.value, cfg.tp.value]: continue try: with vsc.randomize_with(reg_val): vsc.dist(reg_val, [vsc.weight(0, 1), vsc.weight(0x80000000, 1), vsc.weight(vsc.rng(0x1, 0xf), 1), vsc.weight(vsc.rng(0x10, 0xefffffff), 1), vsc.weight(vsc.rng(0xf0000000, 0xffffffff), 1)]) except Exception: logging.critical("Cannot Randomize reg_val") sys.exit(1) init_string = "{}li x{}, {}".format(pkg_ins.indent, i, hex(reg_val.get_val())) self.instr_stream.append(init_string)
def test_distweight(self): PCID = vsc.rand_uint16_t() hist1 = [0]*65536 hist2 = [0]*65536 items = 10000 for i in range(items): # vsc.randomize(PCID) with vsc.randomize_with(PCID, debug=0): # PCID.inside(vsc.rng(1,65534)) vsc.dist(PCID, [ vsc.weight(0, 1), vsc.weight(vsc.rng(1,65534), 900), vsc.weight(65535, 1) ]) # print("PCID: " + str(PCID.get_val())) hist1[PCID.get_val()] += 1 hist2[random.randint(1,65534)] += 1 hist1_hit = 0 hist2_hit = 0 for e in hist1[1:65534]: if e != 0: hist1_hit += 1 for e in hist2[1:65534]: if e != 0: hist2_hit += 1 print("Items: %d hist1=%f hist2=%f" % (items, hist1_hit/65534, hist2_hit/65534)) # Only check deeper if full random actually hit more than weighted if hist1_hit > hist2_hit: # Fail if plain randomization hit 15% more than weighted hist1_15p = int(hist1_hit * 0.15) self.assertLessEqual((hist1_hit-hist2_hit), hist1_15p)
def task(self, a, b): print("self.value: %d" % self.value) with vsc.raw_mode(): with vsc.randomize_with(self.value): self.value in vsc.rangelist(a, b)
async def run(self): tasks = [] cocotb.fork(self.irq_handler()) self.irq_bfm.add_callback(self.irq_cb) await self.init_dma() while self.n_complete < self.total_xfers: t = cocotb.fork(self.run_xfer()) tasks.append(t) # TODO: Delay a random amount before # starting the next transfer # If all channels are occupied, then clean # up at least enough tasks to allow us to # proceed if self.active_xfers == self.n_channels: desired_active = vsc.rand_uint8_t() with vsc.randomize_with(desired_active): desired_active.inside( vsc.rangelist(vsc.rng(0, self.n_channels - 2))) print("--> waiting for transfers to complete (" + str(desired_active) + ")") while self.active_xfers > int(desired_active): print("active: " + str(self.active_xfers) + " desired: " + str(desired_active)) print("--> Wait for first") await cocotb.triggers.First(*tasks) print("<-- Wait for first") # Now, find completed tasks while len(tasks) > 0: idx = -1 for i, t in enumerate(tasks): if t._finished: idx = i break if idx == -1: print("No more to remove " + str(idx)) break else: print("Remove " + str(idx)) tasks.pop(idx) print("<-- waiting for transfers to complete") # Wait for any pending transfers to complete # First, clean out already-completed transfers while len(tasks) > 0: idx = -1 for i, t in enumerate(tasks): if t._finished: idx = i break if idx == -1: print("No more to remove " + str(idx)) break else: print("Remove " + str(idx)) tasks.pop(idx) if len(tasks) > 0: await cocotb.triggers.Combine(*tasks)