Intro
Many people are familiar with the situation when there is no Internet, and a small dinosaur appears on the Google Chrome screen. Today we will tell you how to implement this game on the Cyclone IV FPGA board.
We are Yegor Blinov, Egor Kuziakov, and Inga Ezhova - the first-year students of Innopolis University. In our program, there was a course "Computer Architecture", where we had labs with FPGA boards Cyclone IV and MAX10. We were inspired by this equipment and decided to implement the project on one of the boards.
Short historical background
Field programmable gate arrays (FPGAs) are integrated circuits that enable designers to program customized digital logic in the field. FPGAs have been around since the 1980s and were originally conceived to give all design teams the ability to create custom logic.1
Overview
The algorithm of the project is as follows: the input data is received from the keyboard, then processed by the logic circuit, after that, the picture is displayed on the VGA screen. The rules of the game are simple and well-known. The dinosaur runs along the road, jumping over the cacti. The game is complicated by the fact that over time the speed of the dinosaur increases.
Materials
Altera Cyclone IV (EP4CE6E22C8N)
Quartus Prime Lite Edition 21.0
A VGA monitor
PS/2 Keyboard
Verilog HDL
Architecture
This diagram describes the connections of elements in the project5.

The game is divided into multiple logical blocks. The descriptions of all of them can be found in the list below.
Modules
keyboard
It recognizes the keystroke on the connected PS/2 keyboard.
pll and sync
Pll module converts clock signals which control the entire circuit.
Sync module is used for generating h_sync and v_sync VGA outputs.
bit_stream
It draws game objects on the monitor, generates R, G, B values for an arbitrary pixel.
random
It generates accidental numbers.
cactus generator
It contains the logic of generating 4 cacti and moving them.
game
It processes game objects (such as cactus collision, and dinosaur jumping).
sound
It makes a sound signal when the game starts.
Implementation
Input
We used the PS/2 keyboard to control the game and decode signals according to different values ps_clock and ps_data logical inputs2.

Output
VGA display3 is used for output. Image resolution is 1024*768 60Hz. Video output is divided into 2 modules. The first module is sync. It implements H_Sync and V_Sync signals that are used for drawing images in module bit_stream. This module receives coordinates of a dinosaur and coordinates of cacti from cactus_module and draws a full image using stored in registers sprites. Modules can support colorful images, but they are not needed for this game. For generating the world, bit_stream uses an array of registers of cacti sprites that are randomly selected by a randomizer. Now, it supports up to 7 different cacti sprites.
World’s objects are generated by using Python script. This script receives images and outputs complete Verilog code containing arrays.
Sprites generation
The following are some parts of the code that demonstrate the generating of sprites and the world.
Sprite generator:
from PIL import Image
def generate_sprite(fn: str, check_function, result_string: str) -> str:
im = Image.open(fn)
size = im.size
s = ""
for x in range(size[0]):
for y in range(size[1]):
pixel = im.getpixel((x, y))
if check_function(pixel):
s += result_string.format(x, y)
return s
World generator:
import random
def generate_choices():
s = ""
for i in range(32):
r = random.randint(0, 6)
s += f"cactuses_sprite_choice[{i}] = {r}; "
with open("output.txt", "w") as f:
f.write(s)
Game
In the game module, we have implemented the main game logic: physics for jumping and collision with cacti. As in the original game, we used the parabolic movement for dinosaur jumps.

Cacti are generated by using the cactus_generator module. We tried different algorithms4, but the most effective was the way in which a cactus teleports to its initial position. At the moment, this module generates only one cactus, but it is enough to change the constant and the module will generate up to 4 cacti in one cycle.
Game stages
Game logic depends on these registers and flags: dinosaur and cacti coordinates, game_over flag.
The game starts with the game_over state, then when the keyboard button is pressed the state changes to run.
Over time, the cactus_generator module increases the speed of cacti, thus the dinosaur speed increases.
When the keyboard button is pressed, the state changes to jump, the dinosaur becomes invulnerable to any cacti. The jump state returns to the run state when the dinosaur lands on the ground.
When the dinosaur collides with a cactus, the game state run changes to the state game_over.
Conclusion
After a week of hard work, our team finished the project. We enjoyed the development of the project. In the process of working on it, we have improved the skills of writing hardware descriptions, drawing up logical circuits, and writing technical articles. During our work, we managed to implement the basic concept of the game, develop the logic and create a single mechanism from different elements.
Gratitude
We thank Alexander Tormasov, as primary instructor of the "Fundamentals of computer architecture" course for obtaining basic theoretical knowledge about computer hardware, and Artem Burmyakov for practical skills in hardware designing. We would also like to thank Innopolis University IT Support for providing a VGA display and keyboard for our project.
References:
1 - Historical background - https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/misc/fpgas-for-dummies-ebook.pdf
2 - PS/2 controller - https://www.eecg.utoronto.ca/~jayar/ece241_08F/AudioVideoCores/ps2/ps2.htm
3 - VGA modules - https://youtu.be/v9LLKFrm0w0
4 - Random generating - https://en.wikipedia.org/wiki/Pseudorandom_number_generator
5 - Top-Level entity PDF - https://github.com/KeepError/dino-game-fpga/blob/master/vga.pdf