Esempio n. 1
0
class MonoFifoRGBTest(unittest.TestCase):
    def setUp(self):
        self.res = RESOLUTIONS['TEST16'] # Requires resolution divisible by 16
        self.video_timer = VideoTimer(self.res)
        self.fifo = SyncFIFO(width=16, depth=2, fwft=True)
        h = self.res.horizontal
        self.rgb = MonoFifoRGB(self.video_timer, self.fifo)

        m = Module()
        m.submodules += [self.fifo, self.rgb, self.video_timer]

        self.sim = Simulator(m)
        self.sim.add_clock(1) # 1Hz for simplicity of counting

        # Make a list of random numbers. Turn that into a list of bits
        self.test_numbers = [random.randrange(65536) for _ in range(500)]
        self.test_bits = all_bits_list(self.test_numbers)
        #sum([[int(b) for b in format(n, '016b')[::-1]] for n in self.test_numbers], [])

    def add_fill_fifo_process(self):
        # A process to continually fill the fifo
        def process():
            i = 0
            while True:
                for d in self.test_numbers:
                    while not (yield self.fifo.w_rdy):
                        yield
                    yield self.fifo.w_data.eq(d)
                    yield self.fifo.w_en.eq(1)
                    #print(f'writing {i}: {d} = {d:016b}')
                    i += 1
                    yield
        self.sim.add_sync_process(process)

    def show_fifo_state(self):
        # for debugging
        def process():
            f = self.fifo
            i = 0
            last_log = ''
            while True:
                r_rdy = yield f.r_rdy
                r_en = yield f.r_en
                r_data = yield f.r_data
                log = f'rdy:{r_rdy}, en:{r_en}, {r_data} = {r_data:016b}'
                if (log != last_log):
                    print(f'read_fifo@{i}: {log}')
                last_log = log
                yield
                i += 1
        self.sim.add_sync_process(process)

    def show_video_timer_state(self):
        # for debugging
        def process():
            vt = self.video_timer
            i = 0
            last_log = ''
            while True:
                active = yield vt.active
                nf = yield vt.at_frame_m1
                nl = yield vt.at_line_m1
                nal = yield vt.at_active_line_m1
                log = f'active:{active} nf:{nf} nl:{nl} nal:{nal}'
                if (log != last_log):
                    print(f'vt@{i}: {log}')
                last_log = log
                yield
                i += 1
        self.sim.add_sync_process(process)
        
    def test_signals(self):
        def process():
            while not (yield self.video_timer.at_frame_m1):
                r = yield self.rgb.red[0]
                g = yield self.rgb.green[0]
                b = yield self.rgb.blue[0]
                self.assertTrue((r, g, b) in [(1, 0, 1), (0, 1, 1)])
                yield
            pixel = 0
            bits = self.test_bits
            while bits:
                r = yield self.rgb.red[0]
                g = yield self.rgb.green[0]
                b = yield self.rgb.blue[0]
                if (yield self.video_timer.active):
                    #s = yield self.rgb.shift_register
                    #pc = yield self.rgb.pixel_counter
                    #srfmt = f'{s:016b}'[::-1]
                    #print(f'pixel {pixel} out: {r} expected: {bits[:16]} sr= {srfmt} pc={pc:03x}')
                    self.assertEqual(bits[0], r)
                    bits = bits[1:]
                    pixel += 1
                yield
        self.add_fill_fifo_process()
        #self.show_fifo_state()
        #self.show_video_timer_state()
        self.sim.add_sync_process(process)
        self.sim.run_until(5000)
class VideoTimerTest(unittest.TestCase):
    def setUp(self):
        self.res = RESOLUTIONS['TEST']
        self.video_timer = VideoTimer(self.res)
        self.sim = Simulator(self.video_timer)
        self.sim.add_clock(1)  # 1Hz for simplicity of counting

    def test_signals(self):
        h = self.res.horizontal
        h_at = h.value_at
        v = self.res.vertical
        v_at = v.value_at

        def process():
            # step through cycles and assert each signal has correct value
            # for that cycle
            cycle = 0
            while True:
                x = yield self.video_timer.x.value
                assert_x = lambda step: self.assertEqual(x, h.value_at(step))
                y = yield self.video_timer.y.value
                assert_y = lambda step: self.assertEqual(y, v.value_at(step))

                pix_x = cycle % h.total
                pix_y = cycle // h.total % v.total
                self.assertEqual(x, h_at(pix_x))
                self.assertEqual(y, v_at(pix_y))

                ls = yield self.video_timer.at_line_m1
                self.assertEqual(ls, pix_x == h.total - 1)

                fs = yield self.video_timer.at_frame_m1
                self.assertEqual(fs, pix_x == h.total - 1
                                 and pix_y == v.total - 1)
                fsm2 = yield self.video_timer.at_frame_m2
                self.assertEqual(fsm2, pix_x == h.total - 2
                                 and pix_y == v.total - 1)

                self.assertEqual((yield self.video_timer.horizontal_sync),
                                 h.sync_start <= pix_x < h.sync_end)
                self.assertEqual((yield self.video_timer.vertical_sync),
                                 v.sync_start <= pix_y < v.sync_end)
                self.assertEqual(
                    (yield self.video_timer.vertical_blanking),
                    (pix_y == (v.active - 1) and pix_x >= h.active)
                    or pix_y >= v.active)
                self.assertEqual(
                    (yield self.video_timer.at_active_line_m1),
                    pix_x == (h.total - 1)
                    and (pix_y == (v.total - 1) or pix_y < v.active - 1))
                self.assertEqual(
                    (yield self.video_timer.at_active_line_m2),
                    pix_x == (h.total - 2)
                    and (pix_y == (v.total - 1) or pix_y < v.active - 1))
                self.assertEqual((yield self.video_timer.active),
                                 pix_x < h.active and pix_y < v.active)
                cycle += 1
                yield

        self.sim.add_sync_process(process)
        # Run 3 and a bit frames
        self.sim.run_until(self.res.frame_clocks * 3 + 100)