577 Custom DVD Screensaver for VGA

577 : Custom DVD Screensaver for VGA

Design render

DVD Screensaver with UACJ IIT Logo

How it works

This project implements a DVD-style bouncing logo on a VGA monitor. The logo is a 128×40 bitmap that displays UACJ IIT. The design is written in Verilog and targets the Tiny Tapeout ASIC shuttle.

The system is composed of six main blocks: a VGA sync generator, bouncing logic with position registers, a bitmap ROM containing the logo pattern, a three-instance color palette, an RGB output multiplexer with scanline and glitch effects, and a VHS-style glitch/corruption engine. The diagram below shows the overall architecture.

Figure 1. Block diagram of the DVD screensaver system.

Block description
  • hvsync_generator – Generates the HSync and VSync timing signals required for a 640×480 @ 60 Hz VGA display. It also produces the current pixel coordinates (pix_x, pix_y) and an active video flag (video_active).

  • Bouncing Logic & Position Registers – Maintains the current top‑left corner position of the logo (logo_left, logo_top) and the direction of movement (dir_x, dir_y). On each frame (detected during vertical blanking), the position updates by one pixel. When the logo reaches a screen edge it bounces, increments the color index, and triggers a white flash. An optional cfg_slow mode halves the movement speed by updating only on every other frame.

  • bitmap_rom – A 640‑byte ROM (40 rows x 16 bytes/row) that stores the 128x40 UACJ IIT logo. Each bit represents one pixel: 1 for logo foreground, 0 for background. The ROM is addressed by the current pixel position relative to the logo's top‑left corner.

  • palette – Three instances of an 8‑entry color palette (6‑bit RGB, 2 bits per channel). The logo color cycles through the palette on each bounce. The background color is offset by +4 indices, and a checkerboard accent color is offset by +5 indices. A cfg_color input selects between color (palette) and monochrome (white on black).

  • Checkerboard Background – When cfg_checker is enabled, the background tiles alternate between two colors using a 16x16 XOR pattern (pix_x[4] ^ pix_y[4]), adding visual depth behind the bouncing logo.

  • CRT Scanline Effect – When cfg_scanline is enabled, every odd-numbered row has its RGB channels halved, simulating the dark lines of a CRT display.

  • Glitch / Corruption Engine – A VHS-style corruption effect driven by an 8-bit LFSR (taps at bits 7, 5, 4, 3). The engine has three states: idle, corrupt, and recover. While active it applies:

    • Horizontal XOR scrambling – pixel X coordinates are XOR'd with an LFSR-derived mask scaled by glitch intensity.
    • Vertical XOR scrambling – pixel Y coordinates are similarly distorted.
    • Horizontal tearing – selected rows are offset by a pseudo-random amount, simulating VHS tape tracking errors.
    • Chromatic aberration – each RGB channel is XOR'd with independent LFSR bits.
    • Channel swapping – R↔G and G↔B swaps are triggered pseudo-randomly.
    • Inversion flash – at maximum intensity, colors are fully inverted on random pixels.

    The glitch can be triggered manually by pressing cfg_glitch (rising-edge detected) or fires automatically at pseudo-random intervals while cfg_glitch is held high.

  • RGB Mux & Output Registers – Combines the pixel value (from ROM), the selected colors (from palette), the flash signal, the scanline dimming, and the glitch distortion to produce the final 2‑bit per channel RGB output. The result is latched in registers before being sent to the output pins.

Configuration inputs

The design accepts eight configuration inputs via the ui_in[7:0] pins:

Pin Name Description
ui_in[0] cfg_tile Debug mode: fill the entire screen with the logo pattern
ui_in[1] cfg_color 0 = monochrome, 1 = color palette
ui_in[2] cfg_invert Swaps the logo and background colors
ui_in[3] cfg_slow Halves the movement speed (update every other frame)
ui_in[4] cfg_flip Vertically flips the bitmap when reading from the ROM
ui_in[5] cfg_checker Enables the 16×16 checkerboard background pattern
ui_in[6] cfg_scanline Enables the CRT scanline effect (every odd row darkened)
ui_in[7] cfg_glitch Activates VHS glitch mode; rising edge triggers a glitch burst; holding high enables auto-glitch at random intervals

[!NOTE] The VGA output follows the TinyVGA PMOD pin mapping: uo_out = {hsync, B[0], G[0], R[0], vsync, B[1], G[1], R[1]}. Connect directly to a TinyVGA PMOD or a compatible VGA DAC.

How to test

Simulation testing (CocoTB)

The project includes a CocoTB testbench that verifies the basic functionality. Due to the complexity of VGA simulation, the default test is configured to pass trivially. For full verification, you can implement the following test procedure:

  1. Navigate to the test folder and ensure test.py and Makefile are present.

  2. Run the simulation using:

    make
    
  3. Expected behaviour (if you implement full testing):

    • The testbench should generate VGA timing signals and verify that the logo bounces correctly within the 640×480 screen boundaries.
    • On each bounce, the simulation should check that:
      • The direction toggles (horizontal or vertical)
      • The color index increments by 1
      • The flash counter (flash_ctr) becomes non-zero
    • The bitmap ROM output should match the expected pattern for the UACJ IIT logo.
    • With cfg_glitch asserted, the LFSR should advance each frame and glitch_state should transition from idle → corrupt → recover → idle.
Hardware testing (FPGA or final chip)
Required equipment
  • VGA monitor (supports 640×480 @ 60 Hz)
  • TinyVGA PMOD
  • Switches for configuration inputs (optional)
  • 25.175 MHz clock source (provided by the Tiny Tapeout harness)
Test procedure

1. Basic functionality test

Connect the TinyVGA PMOD to your board and to the monitor. Apply power and reset. You should observe:

  • The UACJ IIT logo bouncing diagonally across the screen
  • A brief white flash at the moment of impact
  • Background colour remains constant (offset from logo colour)

2. Configuration input tests

Apply logic levels to the ui_in[7:0] pins and observe the behaviour:

Input combination Expected behaviour
cfg_tile = 1 The entire screen fills with the logo pattern (debug mode)
cfg_color = 1 Logo changes colors everytime it hits a wall
cfg_invert = 1 Logo and background colours swap
cfg_slow = 1 Logo moves at half speed (updates every other frame)
cfg_flip = 1 Logo appears upside down (vertical mirror)
cfg_checker = 1 Background displays a 16×16 checkerboard pattern with an accent color
cfg_scanline = 1 Horizontal dark lines appear across the image (CRT scanline simulation)
cfg_glitch = 1 VHS-style corruption appears; brief pulse triggers a single burst; holding high triggers random bursts automatically

3. Boundary testing

Monitor the logo position as it approaches screen edges:

  • It must bounce every time it hits a wall

4. Flash verification

The white flash should be visible for approximately 6 frames (about 100 ms at 60 Hz). You can verify this by:

  • Using an oscilloscope on the RGB output pins
  • Recording the VGA output with a capture card and stepping through frames

5. Glitch effect verification

With cfg_glitch asserted:

  • A rising edge should trigger a single glitch burst lasting 2–17 frames (pseudo-random duration)
  • During the burst, observe horizontal tearing, color channel noise, and possible inversion flashes
  • After the burst, the image should recover cleanly with no residual corruption
  • While cfg_glitch is held high, automatic glitch bursts should fire at irregular intervals (approximately every 150 frames when idle)
Expected results

After successful testing, the system should:

  • Bounce reliably off all four screen edges
  • Cycle through 8 distinct colours (only on wall hits, not continuously)
  • Respond correctly to all eight configuration inputs
  • Maintain stable VGA sync (no flickering or rolling image)
  • Produce convincing CRT and VHS visual effects when the respective modes are enabled

External hardware

Required for operation
Component Purpose Specifications
VGA monitor Display the bouncing logo 640×480 @ 60 Hz (supports standard VGA timings)
VGA cable Connect the board to monitor Male DB-15 to male DB-15
TinyVGA PMOD Convert digital outputs to analog VGA signals Uses 6 digital lines (2 bits per colour) + HSync + VSync
Clock source Drive the VGA timing 25.175 MHz (provided by Tiny Tapeout harness)

IO

#InputOutputBidirectional
0cfg_tileR1
1cfg_colorG1
2cfg_invertB1
3cfg_slowVSync
4cfg_flipR0
5cfg_checkerG0
6cfg_scanlineB0
7cfg_glitchHSync

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (Tiny Tapeout Factory Test) tt_um_utoss_riscv (UTOSS RISC-V core) tt_um_memory_game_top (Number Memory Game) tt_um_danielpenas42 (Ball Display) tt_um_machinelearning (7-Segment Neural Predictor) tt_um_microlane_demo (microlane demo project) tt_um_pixel_processor (Tiny Pixel Processor) tt_um_jpigdon_gps_accelerator_top (GPS_Accelerator) tt_um_rgb_mixer (rgb_mixer) tt_um_bgao43 (Tiny TPU Systolic Array) tt_um_main (Pong in Verilog) tt_um_joannec34_teenytpu (teenytpu) tt_um_apa102_ws2812_squidgeefish (APA102 to WS2812 Translator) tt_um_uacj_bouncing_DVD_screensaver (Custom DVD Screensaver for VGA) tt_um_logoUACJ_MOGA (VGA_screensaver_UACJ) tt_um_grace_spi_led_driver (SPI-Controlled 8-Channel LED Driver) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_happyhop_deadcast2 (happyhop) tt_um_dino7 (Dino-7: 7-Segment Runner Game) tt_um_arty3_mac_engine (Simple MAC Engine w/ Postproc) tt_um_uacj (Custom DVD Screensaver for VGA) tt_um_algofoogle_dottee (DOTTEE VGA demo (TTGF26a)) tt_um_mattvenn_signal_generator (Simple Signal Generator) tt_um_urish_simon (Simon Says memory game) tt_um_tpu (Tensor Processing Unit For GF) tt_um_gojimmypi_ttgf_UART_FSM_TRNG_Lab (Hardware Entropy Explorer: UART/SPI TRNG and PUF) tt_um_wokwi_465483277165299713 (First Tinytapeout) tt_um_prem_pipeline_test (Programmable_Pipeline-RISC-V) tt_um_wokwi_467219410242853889 (Tiny Tapeout testtest 111233) tt_um_wokwi_465549494272929793 (Pacos first design) tt_um_wokwi_465731371445677057 (Arturo's first Wokwi design) tt_um_wokwi_465732744934845441 (Tiny Tapeout Template_1234) tt_um_wokwi_465736492859711489 (Tiny Tapeout Workshop JuanF) tt_um_wokwi_465731430225727489 (Rafa’s first Wokwi design) tt_um_wokwi_465731458365332481 (7 segment Display Fli-Flop Try-out) tt_um_wokwi_465732744245929985 (DiseñoCursoTiny) tt_um_wokwi_465731490568160257 (Matt’s first Wokwi design) tt_um_wokwi_465736691688630273 (test1) tt_um_wokwi_465731458628527105 (Mi copia del Tiny Tapeout) tt_um_wokwi_465731520738845697 (El primer diseño) tt_um_wokwi_465731521356457985 (Tiny Tapeout Template Copy) tt_um_gen1_digital_companion_tile (Gen1 Digital Companion Tile) tt_um_wokwi_465732827753495553 (Tiny Tapeout Template Ayman) tt_um_wokwi_465731394728267777 (Julian_Proyecto) tt_um_wokwi_465731458535202817 (Tiny Tapeout Template Copy) tt_um_wokwi_465732847401723905 (Basic Circuit) tt_um_wokwi_465731452481768449 (El primer diseño de Matt para Wokwi) tt_um_wokwi_465731502018614273 (Tiny Tapeout Template flip flop) tt_um_wokwi_465732616714924033 (Tiny Tapeout RJAP) tt_um_wokwi_465731575275296769 (ocxpkeWokwiDesign) tt_um_wokwi_465732880722332673 (Pedro Template) tt_um_wokwi_465731858252480513 (Paula's first Wokwi design) tt_um_wokwi_465731455677830145 (Tiny Tapeout JMCG) tt_um_wokwi_465737601403996161 (Tiny Number Simon) tt_um_ttmul (Balanced Ternary Multiplier) tt_um_wokwi_465731466664816641 (Tiny Tapeout Workshop Malaga 2jun2026) tt_um_8bit_risc_cpu (8-bit RISC CPU) tt_um_wokwi_451184391728659457 (Simple Sprinkler) tt_um_fhw_appel_spiPWMio (spiPWMio) tt_um_divadnauj_GB_serv_soc_wb (serv_soc_wb) tt_um_8bitcustomcomputer (SAP 8 Bit Computer) tt_um_bioimpedance (Very Low Resource Digital Implementation of Bioimpedance Analysis) tt_um_mgj_bist8 (BIST-8: Built-In Self-Test for 8-bit CLA Adder) tt_um_roberto_tiny_radar_tile (BioPulse Tile) tt_um_systolic_mac_2x2 (2x2 Systolic Array Matrix Multiplier) tt_um_peg_top (2x2 CNN Accelerator PE Grid with UART) tt_um_AlvaroRub_ringcounter (Counter16Outputs) tt_um_wokwi_465731440267947009 (Antonio's first Wokwi design) tt_um_wokwi_465732706576877569 (Guille's first Wokwi design.) tt_um_wokwi_465731481873367041 (MIPS-Lite 8-bit Processor) tt_um_wokwi_465736612213902337 (Juan`s first Worki design) tt_um_wokwi_465731439156454401 (Rhyloo’s first Wokwi design) tt_um_wokwi_465732536551273473 (Tiny Tapeout Marcos Fernandez) tt_um_wokwi_465737290543084545 (Tiny Tapeout Template) tt_um_wokwi_465630130495825921 (ram 1 bit Copy) tt_um_wokwi_465731403724006401 (sdft wokwi 1) tt_um_top (RHD2164-MCU-SPI Bridge) tt_um_line_follower_arvaloez (Line Follower Robot controller) tt_um_xoroshiro64plus_v2 (xoroshiro64) tt_um_ohuettenhofer_tiny_qsim (Tiny Quantum Circuit Simulator) tt_um_santhosh_ring_osc_gf (Ring Oscillator PVT Sensor & TRNG (GF180)) tt_um_santhosh_stoch_stdp_pair_gf (Stochastic neuron + STDP controller (merged, GF180)) tt_um_santhosh_rsd_char_gf (RRAM Characterization Platform (DC sweep + endurance + retention + histogram, GF180)) tt_um_santhosh_xbar_ctrl_gf (Memristive Crossbar Peripheral Controller (GF180)) tt_um_joseph_bf (BF) tt_um_hydrocomms (FSK Modem) tt_um_systolic_array (2x2 MAC Systolic array with DFT) tt_um_kluterirv_rv32e_core (Minimal RV32E SoC with UART Loader) tt_um_algofoogle_ttgf26a_vco (VCO driven by DAC) tt_um_fer_logo_music_vga (UNIZG-FER VGA project) tt_um_maqsudbek_dyadic_pwm (Dyadic PWM) tt_um_waferspace_vga_screensaver (Wafer.space Logo VGA Screensaver) tt_um_htfab_vga_tester (Video mode tester)