예제 #1
0
 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)
예제 #2
0
            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_
예제 #3
0
 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)
예제 #4
0
 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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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())
예제 #8
0
 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))
예제 #10
0
    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
예제 #11
0
 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)
예제 #12
0
    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)
예제 #13
0
 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)
예제 #14
0
    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)