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)