build18 hackathon 2025
teammates: kody liang, jaehyun lim*, john alacce

tools: systemverilog, vcs, vivado
project repository

*Thanks to Jaehyun for writing the original project description (which this article is largely based on) and for making such pretty graphics!


JustOneFlappyBird is a turing complete, one instruction set processor that can run the programming langugae SUBLEQ. As a demonstration of its functionality, we animated the video game Flappy Bird via VGA display. We targeted a Boolean Board Xilinx Spartan 7 FPGA using SystemVerilog RTL, Synopsys VCS simulation, and Vivado synthesis. Our team of 4 built JustOneFlappyBird as a part of Build18 2025, CMU ECE’s annual week-long hardware hackathon.

SUBLEQ, briefly

SUBLEQ is an esoteric programming language consisting of a single instruction, SUBtract and branch if Less-than or EQual to zero. Instructions are of the form A B C where A, B, and C are all memory addresses. The processor computes the value of *B - *A (* representing memory dereferences) and stores it back into B. If the result was less than or equal to 0, the PC jumps to C. That’s it!

uniprocessor design

uniprocessor-datapath

Our processor consists of a PC register, two “general purpose” registers for collecting the value of operand A and operand B, and a register for saving the value of the memory address B for storing the result of the subtraction later. We used a 2-read-1-write memory (reading/writing B, as well as reading A or C), as well as a subtractor (calculating *B - *A) and comparator (checking *B - *A <= 0).

uniprocessor-fsm

Our processor executes each SUBLEQ instruction in 8 cycles, or 5 primary steps (non-await-memory stages):

  1. Use PC and PC+1 to fetch addresses A and B
  2. Store address B into the B address register
  3. Read from addresses A and B to get *A and *B
  4. Store *A and *B into their respective registers, use PC+2 to fetch address C
  5. Save *B - *A into address B, jump to address C if result is less than or equal to 0

graphics & VGA

vga

Bird and pipe sprites where drawn via combinational logic. Each sprite was divided into “column groups” (sets of columns where each row had the same colors), which was then used in conjunction with the current row to save us from having to write logic to set the color for each pixel individually!

Once we had a row/col –> color assignment, we rendered it via a VGA engine we previously designed for 18-240’s Pong project. Because the Boolean Board ultimately used a HDMI output, we used Xilinx IP to convert our VGA into HDMI for display.

system architecture

Our processor (and corresponding program memory) is connected via MMIO to the graphics modules “Draw Bird” and VGA. When the processor writes a value to a MMIO-reserved addreses, the Draw Bird module intercepts to update the bird’s position on the screen and output to the VGA graphics engine.

system

group photos!

group-photo-1
(above) left to right: John Alacce, David Chan, Kody Liang, Jaehyun Lim

group-photo-2
"You guys are goofballs" - Professor Bill Nace