Pull to refresh

The Dino game from Google Chrome using FPGA

Reading time4 min
Views3.6K

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.

  1. The game starts with the game_over state, then when the keyboard button is pressed the state changes to run.

  2. Over time, the cactus_generator module increases the speed of cacti, thus the dinosaur speed increases.

  3. 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.

  4. 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.

Source code on GitHub

References:
Tags:
Hubs:
Total votes 7: ↑7 and ↓0+7
Comments3

Articles