GitHub

🏆 3rd Place — Ralphton Seoul (2026-03-29)

A fully hardware-implemented Tetris game in SystemVerilog. No CPU. No firmware. Pure RTL.

Built using ART — a 4-stage autonomous AI pipeline that writes HDL, generates tests, runs Vivado, and reviews synthesis in a self-healing loop.

Target: Nexys A7-100T (Xilinx Artix-7 XC7A100T-1CSG324C) | Clock: 100 MHz single domain | Toolchain: Vivado 2025.2

How It Was Built — ART Pipeline

This project was developed using ART, an autonomous AI agent pipeline that iterates through build-test-synthesize-review cycles with self-healing feedback loops.

ART Pipeline Editor

Pipeline stages:

Stage Type Role
Build Agent Reads PLAN.md spec, implements/fixes SystemVerilog modules
Testbench Agent Generates self-checking tb_top.sv with PPM frame rendering
Sim Command Vivado xsim — compile, elaborate, simulate with pass/fail detection
Synth Review Agent Analyzes Vivado timing/utilization reports, writes fix guidelines

Simulation failures route back to Build. Synthesis timing violations trigger targeted fixes via synth_review.md guidance. Agents communicate through file-based artifacts — no shared memory.

Example of self-healing: the pipeline caught a runtime division in audio_engine.sv causing a -52ns timing violation (WNS). The review agent wrote fix guidelines, and the build agent replaced it with precomputed lookup tables.

Features

  • Full Tetris gameplay — 7 tetrominoes with SRS wall kicks, gravity per level, lock delay (500ms, 15 resets), ghost piece, soft & hard drop
  • 5-button control — BTNL/R movement, BTNU rotate, BTND drop, BTNC start/pause. SW[0] hard-drop toggle, SW[15] master reset. 20ms debounce + DAS auto-repeat (200ms initial, 50ms repeat)
  • 7-segment score display — 8 multiplexed digits showing Lv.XX SSSS at 1 kHz refresh with custom L/v glyphs
  • PWM audio synthesis — 7 distinct sound effects (move tick, rotate click, lock thud, line sweep, tetris fanfare, hard drop slam, game over descend), 100-1200 Hz with frequency sweeps
  • UART live display — 216-byte binary protocol with checksum, full board + piece + score transmitted on every game event for PC terminal rendering (115200 baud, ~53 packets/sec)
  • 16 context-aware LEDs — Larson scanner on title, board fill meter during play, 2 Hz blink when paused, all solid on game over

Module Hierarchy

tetris_top ── Top-level port mapping
├── tetris_engine ─── Game FSM, board state, scoring (~850 lines)
├── collision_checker  Combinational 4x4 vs 10x20 board check
├── piece_rom ──────── 28 bitmasks (7 pieces x 4 rotations)
├── btn_debounce x5 ── 20ms debounce + edge detect
├── lfsr_rng ───────── 16-bit LFSR, rejection sampling
├── uart_tx ────────── 115200 baud, 8N1
├── uart_packet_builder 216-byte game state serializer
├── seven_seg_driver ── 8-digit MUX @ 1 kHz
├── led_controller ──── Larson scanner + fill meter
└── audio_engine ────── PWM synth, 7 sound effects

Synthesis Results

Resource Usage
LUT 3-6% of XC7A100T
FF 1-2%
BRAM 0
DSP 0

Vivado Elaborated Design Vivado Synthesis

Known Issues

  • 7-segment display mapping — Segments A and G are swapped in seven_seg_driver.sv, causing incorrect digit rendering on the physical board.

Building

Requires Vivado 2025.2 with Artix-7 support.

make xsim                              # Run simulation testbench
vivado -mode batch -source synth.tcl   # Run synthesis + place & route

program.sh is the script used to flash the board at the competition venue. It depends on a Docker image prepared for the ART pipeline and will not work standalone.

PC Display

display.py receives UART packets and renders the game board in the terminal with ANSI colors:

python display.py /dev/ttyUSB1

Project Stats

Metric Value
RTL modules 11
Lines of SystemVerilog ~3100 (incl. testbench)
Piece bitmasks 28
UART packet size 216 bytes
Sound effects 7
Clock domain Single, 100 MHz

Presentation

See presentation/FPGA-Tetris-Presentation.pdf for the full project deck.

Read the original on github.com ↗