05 · Read the screen programmatically

The PC can ask the FPGA for the picture it is sending to the LCD and VGA, over the same USB cable that programs it. That makes graphics testable: this example moves a box from the PC and checks every pixel against the simulation.

Verified on the board 2026-10-24: 0 of 76,800 pixels differ Quartus Prime Lite 17.1 LCD shield or VGA monitor (the test does not need either) Skill: read-screen
Download screen_readback.qar (full project)

The repo keeps the full project (.qar, plus the sources here) but no prebuilt bitstream: one build (a few minutes) makes the .sof on your computer.

The result

Two identical test cards side by side: left, the picture read back from the board; right, the frame rendered by the simulation. Colour bars, the title 05 SCREEN READBACK, a grey ramp, a grid and a white box.

$ python examples/05_screen_readback/test_screen.py
0 of 76800 pixels differ
step 'H' -> box (64, 192): match
step 'RRDD' -> box (128, 256): match
step 'UUUUUULL' -> box (64, 64): match
OK: every capture matches the simulation

Left: read back from the board. Right: rendered by simulating the same Verilog. Three positions of the box, all 76,800 sampled pixels identical. (A capture takes about 6 s: 230 KB of text over JTAG.)

How it works

test_cardbox at (bx, by) LCD + VGA debug_linkon 'F': store 320×240 (M9K)send as hex text lines jtag_uartUSB-Blaster PCde10.py screen → PNGsim/tb_frame.sv → expected PNGscreen_check.py: pixel by pixel commands H L R U D move the box

With 2-pixel sampling, every dot of the 2× and 4× text fonts in this BKM is captured. For a STEP 4 capture (160 × 120, 14 % of the RAM) use debug_link #(.STEP(4)).

Things learned

Run it

python scripts/de10.py build examples/05_screen_readback
python scripts/de10.py program examples/05_screen_readback
python examples/05_screen_readback/test_screen.py        # moves the box, captures 3 times, compares
python scripts/de10.py send R 1; python scripts/de10.py screen logs/now.png     # by hand

Build it yourself

python scripts/new_project.py examples/05_screen_readback screen_top --lib display debug font
python scripts/de10.py build examples/05_screen_readback

Test without the board

python scripts/sim.py lib/sim/tb_debug_link.sv -D JTAG_UART_SIM     → pixels 76800, errors 0   PASS

Files

FileWhat
src/screen_top.sv, src/test_card.svThe design and its picture
sim/tb_frame.sv, test_screen.pyExpected frames and the board test
lib/rtl/debug_link.sv, jtag_uart.svScreen read-back and the USB link
scripts/de10.py, frame_to_png.py, screen_check.pyCapture, decode, compare