Introduction: FPGA Asteroid Game
For our CPE 133 Final Project, we decided to create an asteroids game on our FPGA using two push button switches and the 7-segment display. The game works so that an asteroid spawns in one of three randomly selected rows, and comes hurtling toward the ship on the other side of the 7-segment display. The upper button and lower button can be used to move your ship out of the way of the asteroid. Upon failure to do so, the display reads ‘BAnG’ for a moment and then quickly restarts the game so the user may try again. What follows is a brief description of how the project was made so that any user may replicate or improve our design.
Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.
Step 1: Overview
The project largely consists of Finite State Machines (FSMs), which use logic to transfer the FPGA between states which store and display different values of ship and rock positions. The two major modules are the game FSMs for the rock and ship, and the binary to 7-segment display decoder FSM, which are integrated together using a very simple structural model in VHDL.
FSMs were created for the ship’s position, the rock’s position, and for the 7-segment decoder. The purpose of the ship’s FSM is so that the ship can move to the correct position when the player presses an up or down button. The FSM is needed because it needs to remember which position it was last in in order to move to the correct position.
The purpose of the rock’s FSM is to move the rock to the correct position based on which row it is in and the last position in that row. In addition, it keeps track of the position for the module that will display it and pseudo-randomly picks a new row to appear on next.
The FSM for the 7-segment display decoder was used to not only display the ship and the rock but also to display “BAnG” when the ship position and the rock position are the same.
Step 2: Materials
The materials used in the project were:
- Basys3 Development Board from Digilent, Inc.
- Vivado Design Suite
- sseg_dec.vhd (This file was provided to us on Polylearn and was written by Bryan Mealy)
- Clk_div.vhd (This file was provided to us on Polylearn and was written by Bryan Mealy)
- Three Finite State Machines (FSMs)
Step 3: Making the Game
The game module was created by using behavioral modeling to describe the states of the ship and rock for their own respective FSMs. The advantage of this is that it is far easier to model the circuit behaviorally by describing what it does rather than figuring out all of the components needed to design the hardware.
The rock states were done using a pseudo random number generator for the first position of the rock. To accomplish this, we gave the generator its own clock which was extremely fast relative to the speed of the game. On each rising edge, a three bit number is incremented, and all of its values correspond to one of three start states for the ship. Therefore, three values correspond to position 3 (the top right), three correspond to position 7 (the center), and two correspond to position 11 (the bottom right).
Once the random generation has occurred and the asteroid has been given an initial state, it flows horizontally toward the ship with no interruption.
0 ← 1 ← 2 ← 3
4 ← 5 ← 6 ← 7
11 ← 10 ← 9 ← 8
The clock used for the rock’s next state logic controls the speed of the game; we found through trial and error that 9999999 is a good value for its max count.
The ship’s logic works by initializing into the center position (position 4) on the far left side. If the upper button or lower button are pressed, the ship will move up and down into position 0 and 11 corresponding to the button that has been pressed.
In order to have the ship movement feel good for the user, we did not make its movement asynchronous. We used a clock for its state changes, and we used a max count of 5555555.
Step 4: Displaying the Result
The binary to 7-segment decoder takes in the 4-bit position variables for the ship and the asteroid and displays the appropriate image (either the ship and rock or the message “BAnG”).
It accomplishes this by first checking if the two are equal and then displaying the message “BAnG” if the check returns true.
If it does not return true, the decoder will display the ship and the rock by switching between them at a very high clock frequency and fooling the eye into seeing them as if they are being displayed at the same time.
Step 5: Putting It All Together
We encompassed the ship’s and rock’s FSM in one large FSM that we wired to the display FSM. The inputs to the game are the up button and the down button on the BASYS3 board and the system clock. The outputs are the segment and anode vectors seven segment-display.
These inputs and outputs will be seen in the constraints file where they are port mapped.
Step 6: Future Modifications
In the future, adding more ship movement functionality to the project would be an improvement. This can be accomplished simply by giving 2 more button inputs and allowing the ship to take positions (states) other than 0, 4, and 8. Another possible modification could be controlling the asteroid’s next state timing so that it starts slowly and increase speed by 1.5x every time it misses the ship until it gets a hit, where it would restart and become slow again. This would increase the difficulty of the game and make it more fun for the user if it were implemented, and could be done by creating a variable for the max count of the rock’s next state clock, multiplying that variable by 1.5 every time the asteroid doesn’t hit, and resetting it to it’s initial value every time the rock hits.
Step 7: Conclusion
This project has helped us to better understand finite state machines, clocks, and interactively displaying on the seven-segment displays.
The biggest thing about finite state machines is that it is important to know (remember) what state you are currently in in order to move to next desired state. Ironically, good life advice; you must know where you are to know where you are going.
By manipulating different instances of clocks, we were able to randomly generate numbers, move the rock to the next position, and manage the displaying of the ship, the rock, and end-of-game message.
We learned that more than one anode cannot be displayed at the same time. The module given to us took advantage that the human eye can only see the difference up to a certain frequency. So a higher frequency of switching anodes was chosen. The ship and rock being seen at the same time is actually an allusion since each are displayed separately, but very quickly. That concept was applied to display the movement of the ship, the rock, and the “BAnG” message.