Do you remember spending whole afternoons playing arcade-style games as a kid? Asteroids, Pac-Man, Galaga, Space Invaders, Breakout, Missile Command, or anything else. Have you ever wanted to recreate games like those out of nostalgia, but never knew where to start? Have you ever wanted to make a game like those just for fun? If you have, then look no further.
This is a project that uses a Nexys-2 Digilent board to display an obstacle avoiding game on an 8x8 LED matrix. This game consists of obstacles that scroll down from the top of the display, and the user moves their character left or right along the bottom of the display to avoid the scrolling obstacles. If the user hits an obstacle, the display will flash red and the game will reset. If the user survives until reaching the end of the map, the display flashes green, and the user can begin the game again. This is a simple design, but we chose this because it captures the charming gameplay of those old arcade-style games.
Nexys-2 Digilent FPGA board
USB-to-miniUSB connector (comes with Nexys-2 board)
CILE 2088RGB-5 LED matrix or any 8x8 LED matrix display
Four sets of 8 wires (ex: white, red, green, and blue)
Software (Can be Found for Free Online):
ISE Deign Suite 14.5 (for describing hardware)
Adept FPGA Programmer
Step 1: Downloading Software
Ignore this step if you already have the software.
If you do not already have the software, below are some instructions on how to download it. The process is a bit long, but it is worth it to finally get started, and you can use the software for future projects.
Instructions to Download ISE Design Suite 14.5
1.) Go to Xilinx.com
and create a user account. Xilinx locks everything to the user account created,
so create an account and keep the login/password handy.
2.) Click on Products -> Design Resources -> Development Tools -> ISE Design Suite.
3.) Click on the “ISE WebPACK Design Software” landing page link.
4.) Click on the “Download ISE WebPACK Software for Windows and Linux” link.
5.) On the Downloads page, click on the ISE Design Tools tab and select version 14.5.
6.) Click on the “Full Installer for Windows” link in the ISE Design Suite – 14.5 Full Product Installation section.
7.) Download this and install.
8.) WINDOWS 8 Users only: ISE is officially not compatible with Windows 8. To get the program working, delete libPortability.dll and rename libPortabilityNOSHh.dll to libPortability.dll
If this does not work, go to this link (http://forums.xilinx.com/t5/Design-Entry/ISE-12-3-...) or other online resources. The PlanAhead tools will not work on Windows 8, so if you choose to work from a Windows 8 machine, you’ll need to manually assign FPGA pins in a user constraint (ucf) file.
Getting the ISE license working
1.) Upon starting the Xilinx ISE, you may select “Get Free ISE WebPack License” from the license radio-button options.
2.) Log in to the Xilinx Licensing account and proceed through all screens until the Product Licensing screen is reached.
3.) Select “ISE WebPACK License” from within the Certificate Based Licenses area and then click on the button to generate a license. The “Generate Node-Locked License” option will create a license locked to a specific workstation.
4.) Select ISE WebPACK License from within the Product Selection area and continue to complete the process and generate a license to be delivered via email.
5.) Follow the instructions in the email to activate the license. Note that the license manager is located in the “Help” pulldown window of the Xilinx ISE.
Other guides to this can be found online.
Step 2: Wiring the Nexys-2 Board and the LED Display
Wiring is another exciting part of this project. Watching your VHDL come to life in front of you is a feeling that is hard to duplicate because nothing is more satisfying then watching the lights flicker on after wiring. Make sure to program the Nexys-2 board in the next step to see for yourself. Below are the datasheets and the pin connections we used.
CILE 2088RGB-5 LED Display Datasheet:
If you used a different LED Display, it might have different pin connections. However, you can find the datasheet by Google searching its serial number.
Nexys-2 Board Datasheet:
Relevant pin assignments can be found on pages 5 and 15 .
The Nexys-2 board Pmod outputs can drive the LED displays at 3.3 V without having to setup an external supply or use current limiting resistors, so the outputs can be directly connected to the display on the breadboard.
The 8x8 LED matrix uses common anodes for each row and common cathodes for each column and color. To turn on a particular LED, apply positive 3.3 V to its row and 0 V to its column. In other words, the common anodes are active high and the common cathodes are active low. Both need to be activated to turn on the LED. A matrix like this can only have one row activated at a time, otherwise the same columns will be displayed in all the active rows. This problem is avoided by using only one row at a time and cycling through the rows several hundred times a second.
Use the picture above to determine how the pins on the LED matrix count up.
JA1 (Nexys-2 board) to pin 17 (LED Display)
JA2 to pin 18
JA3 to pin 19
JA4 to pin 20
JA7 to pin 29
JA8 to pin 30
JA9 to pin 31
JA10 to pin 32
Red Common Cathode
JB1 to pin 9
JB2 to pin 10
JB3 to pin 11
JB4 to pin 12
JB7 to pin 13
JB8 to pin 14
JB9 to pin 15
JB10 to pin 16
Green Common Cathode
JC1 to pin 28
JC2 to pin 27
JC3 to pin 26
JC4 to pin 25
JC7 to pin 24
JC8 to pin 23
JC9 to pin 22
JC10 to pin 21
Blue Common Cathode
JD1 to pin 1
JD2 to pin 2
JD3 to pin 3
JD4 to pin 4
JD7 to pin 5
JD8 to pin 6
JD9 to pin 7
JD10 to pin 8
Step 3: Importing VHDL and Programming to the Nexys-2 Board
Attached is our VHDL source code.
Download and unzip the FinalProject folder, then open FinalProject with ISE Design Suite 14.5.
To program this to the Nexys-2 board, select the top module "game - Behavioral" and double click "Generate Post-Synthesis Simulation Module." Reference the first attached picture.
Then open Digilent Adept, select the "game.bit" file, connect the Nexys-2 using the miniUSB cable, select "Nexys2" in the Connect box, and select "program." Reference the second attached picture. If your Adept menu looks differently, press the "Initialize Chain" button so your computer can detect the Nexys-2 board.
Once you program the VHDL to the board, wait for the LEDs to turn on and try moving around! Unfortunately, there are still some bugs in our VHDL, and the LED display may not be working as intended. However, the movement is functional, so move left and right as you so desire.
Certain parts of the VHDL are created by Bryan Mealy and are cited as such in the VHDL modules he contributed to.
Step 4: Description of VHDL
Here is an explanation of our VHDL. There are some bugs, but this will help you improve it or use some of its components in your own projects. Above are pictures of the finite state machine and black box diagram that you can use to help understand the VHDL.
"Game" is the top level module that connects all of the components of the project and assigns the outputs. Signals and port maps are used to connect the components together. This is also the module where we output the position of your character and the obstacles to the display. This also contains the process that makes all LEDs flash green or red and resets the game when you win or lose, respectively.
"scroll_clk0" is the module containing the slowed clock used to increment the progress and score of the player. This is a basic clock divider that counts clock cycles to create a slower clock pulse about once per second.
"map_decoder0" is the module that reads the obstacle positions from the ROM so they can be displayed on the LED matrix and checked against the user position.
"display_counter0" is the module with the 3 bit counter that cycles through which row of the LED matrix is being displayed. This counter is built with toggle flip flops that can be reset to 0.
"map_progres_counter0" is the module that keeps track of how far the user has progressed through the game. This uses an 8 bit counter made from toggle flip flops that can be reset to 0 when the game ends.
"address_adder" is a module that uses one half adder and seven full adders to make an 8 bit ripple carry adder. This is used to add the progress of the user to the row currently being displayed in order to read the correct obstacle positions from the ROM.
"standard_decoder" is the module that has a 3 to 8 standard decoder which uses the three bit number from the display_counter0 module to determine which row to turn on.
"map_rom0" is the module that contains the read-only memory of the position of the obstacles on each row. Using this creates the synthesis warning " Instantiating black box module " and several dangling pin warnings. However, these warnings do not affect the game because this is leftover from the automatic creation of block memory. In order to edit the ROM using the ISE Design Suite 14.5 program, first create a notepad file with the following:
Add 1's wherever you want an obstacle to be located, and this file can be up to 256 lines long. Make sure only the last line ends with a semicolon.
Next, save this file as a .coe file by adding ".coe" to the end of the file name and changing the "save as type" to "all files.
After this, double click on on the module "map_rom0." After this opens, go to page 2 and make sure the Memory Type is Single Port ROM in the dropdown menu. On page 3, make sure that the Read Width is 8 bits and the Read Depth is 256. If you want to change the size of the map, see page 6 of this instructable. On page 4, make sure the Load Init File and the Fill Remaining Memory Location boxes are checked, and that your .coe file is used in the Coe File box. You can see the values of the map by selecting Show. Finally, select Generate.
"buffer_with_output_enable0" is the module that makes sure the obstacles are outputted as active low and allows them to be turned off when the game ends. This is made using D flip flops and inverters.
"win_lose_logic0" is the module that checks if the user has reached the end of the map or has collided with an obstacle so that the "game" module can flash the display with all red or green LEDs and reset the counters in "map_decoder0"
"sseg_dec0" is the module that reads an 8 bit number and displays its decimal value equivalent on the seven segment display on the Nexys-2 board. This also contains a clock divider used for controlling the refresh rate of the Move finite state machine and the seven segment display, and the LED matrix.
"move_fsm0" is the module that reads the inputs of Left and Right and outputs the position of the user after moving. This also decodes the 3 bit value for position to a one-hot 8 bit output. Above is a diagram of the Moore state machine.
"buffer_with_output_enable1" is a module that has the same structure as "buffer_with_output_enable0." However, this is used to make the user's position active low and it can be turned off when the game ends.
"game.ucf" is the user constraint file that defines which pins on the board connect to the inputs and outputs of the game.
Step 5: Bugs
As previously mentioned, we have identified some bugs that have not been fixed yet. One is that the left and right movement is inverted in the Move finite state machine. Another bug in the Move finite state machine is that the movement is disabled when a second button is pressed while the first is still being held, rather than allowing movement in the second direction. The obstacles also do not display correctly on the LED matrix, although collisions are registered correctly, despite not being visible on the display. The user is also displayed in all eight rows instead of only the bottom row of the LED matrix.
I encourage you to look through our VHDL and comment with any fixes you can find. We spent a long time trying to debug this project, and we would love to see this fully functional so that people can fully enjoy an arcade-style game in a DIY setting. Even more than that, we would love to play it, too.
Step 6: What You Can Do With This Project
Although there are bugs in our project, the majority of the components are functional on their own. For example, the Move finite state machine can easily be made to move left and right if you do not need to press both buttons at once. Even if you do, the bug is not game-breaking. Most components of this project can be adapted and used for other projects. The Move finite state machine can be used to move in other games, the map decoder and collision detection components can be used to scroll through any map stored in ROM and check for intersections, and the counters and adders will always be able to count and do arithmetic in any project.
If you are hesitant to do this project because it is not fully functional, don't be. This project helped us learn about VHDL and the debugging process that game developers go through, and it was exciting to take the first step towards building our very own game. Our project may not fully work, but it provides building blocks for the next one to be even better.