Yoshi’s Nightmare: FPGA Based Video Game


Introduction

Video games are typically designed around a microprocessor that is embedded within a console or computer system. While this is the typical case these days, it is not the way that video games always been crafted. In its infancy, the first video game experience was that of a fully analog system which implemented a crude form of table tennis on the quaint black and white CRT televisions of the time. With the introduction of TTL and then CMOS logic chips, there existed a new toolset to create simple logic games. The introduction of the microprocessor and its evolution over the many decades has provided a powerful and flexible platform for which to design video game systems and to write software around.

Why would one consider implementing a video game with the reconfigurable logic of an FPGA? There are many ways that FPGA technology can help in the realm of video games. Graphics co-processors can be developed and tested using FPGA technology, providing a more flexible and affordable testing platform than the ASIC. In consideration of small toys and low cost game devices, FPGAs can be used to test standalone digital systems that can later be translated to an ASIC design and mass manufactured to provide an affordable and fun experience for the consumer. Beyond these possibilities, the intellectual challenge of coordinating a digital system that interprets inputs from a game controller and output graphics to a VGA monitor is very intriguing to me, and I have strived to make the experience as compelling as possible.

 

The Game: A broad overview

The game that I envisioned when beginning this project revolved around a small green dinosaur named Yoshi, a popular character from Nintendo’s Mario series. The first objective was to fully animate his actions, allowing the player to make him run around, and jump up and down from platforms on the screen.

This involved fully implementing a form of 2D Physics for his motion in the x and y dimensions on the screen, keeping in mind conservation of momentum and accelerations, as well as collisions with objects, walls, and platforms.

Next there needed to be reasons for Yoshi to move about, and these are eggs and ghosts. Eggs are objects which Yoshi usually collects in his classic games, so I made his purpose in my game to collect randomly placed eggs on the screen to gain points. Ghosts are traditional enemy characters from the Mario series, and were a fitting object for use as an enemy in the game. These ghosts chase Yoshi around as he collects eggs, and introduce a sense of urgency and challenge to the otherwise simple task at hand.

To create the environment for the game, stationary platforms and an outer wall around the screen are drawn on the monitor, and a separate collision detection circuit is used to determine when Yoshi encounters them. Other assets to the game, such as score display, life hearts display, gameover display, background, as well as title screen were implemented at the end of the design as finishing touches to the game.

To play the game, I decided to use a classic Nintendo NES controller, as this would provide sufficient buttons to control the gameplay and would add to the retro feel of the game. I harvested a female controller port from a scrap Nintendo console and soldered jumper wires from the pins to interface with GPIO on the FPGA board. The controller uses a serial protocol for communicating button states, and therefore a receiver module needed to be implemented to use the controller with the game.

I based the project around the affordable and capable Basys 3 development board which uses a Xilinx Artix-7 series FPGA, with 33k logic cells, and 1800 kbits of block RAM.  The board has “p-mod” connector which allow for outside input, as well as a seven-segment display to display the score on.

Continue reading

Advertisements

Storing Image Data in Block RAM on a Xilinx FPGA

Now that we have a VGA synchronization circuit we can move on to designing a pixel generation circuit that specifies unique RGB data for certain pixels (i.e. an image). Before we actually go there, I thought I would separately talk a little bit about how to store image data on an FPGA. This discussion will focus mainly with using a Xilinx FPGA, more specifically the Basys 3, which uses 12-bit color.

Raw images are arrays of pixel data. Each pixel has a number of bits that specifies the intensity of the red, green, and blue color components. Assuming that an image is stored in 24-bit “True Color”, there are 8 bits specifying each respective color component. Since we are using the Basys 3 FPGA, we will need only the upper four bits of each color component (3 colors * 4 bits/color = 12 bits). So we need 12 bits per pixel to represent color, and y*x pixels, where y is the image height, and y is the image width.

The image of Yoshi shown above is scaled up such that we can easily see each pixel as a block of color on our screen. This image has a height of 32 pixels, and a width of25 pixels. That means that in total we have 800 pixels, each needing 12 bits to represent color, so 9600 bits altogether. There are a few ways to store all of these bits.

Continue reading

Driving a VGA Monitor Using an FPGA

Learning how to directly drive a VGA monitor with an FPGA opens up a window for many potential projects: video games, image processing, a terminal window for a custom processor, and many more. To get started, we will need to learn how to drive the necessary signals to display things on a VGA monitor. We will then use a test circuit to display some colors on the screen. In future posts I will detail how to design pixel generating circuits for displaying custom graphics and animations. More on that soon!

Computer monitors used to be bulky cathode ray tube (CRT) devices. VGA technology was developed with driving the physical CRT in mind, so knowing how that device works can be instructive in understanding why VGA signals are driven the way they are. That being said, computer monitors nowadays are LCD monitors without a CRT, yet the VGA interfaces for these monitors still use the same signals to display images on their screens. Instead of going into the details of CRTs in this post, we will instead inspect the necessary signals for a VGA monitor and their timing diagrams, and implement a synchronization circuit in Verilog HDL.

Keep in mind that different FPGA development boards have different color depth capabilities. I will focus here on using the Basys 2 which has 8-bit color and the Basys 3 which has 12-bit color. While I am covering the Basys 2 here, in the future I will focus on and use the more capable Basys 3 for my VGA projects.
Continue reading