Skip to content

alexswo/FlappyBird

Repository files navigation

FlappyBird

####FlappyBird on Verilog

###Introduction:

The purpose of this project was to create a version of the game Flappy Bird. The game consisted of a bird, which was simplified to a black square, that attempted to flap its way through a series of obstacle pipes. The horizontal distance between the pipes remained constant, but the vertical height of each pipe was randomly generated. The player earned a point for each pipe the bird flew through, represented by a pink dot on the bottom right of the screen. If the current score was greater than the highest score, the current score replaced the highest score on the seven segment display. When a bird crashed into a pipe or landed on the floor, the bird dropped to the ground, the game ended, and a reset button could be used to play again.

###Design Description: We used the files provided as part of this VGA demo as the backbone of our project: https://pumpingstationone.org/2013/04/nerp-fpgaok/

NERP_demo_top.v: This was the top module for the game handling input and most game behavior. The game had three different states: when the bird crashed, when the game was reset, and when the bird was in flight. The first always block detected crashes, score kept, and controlled the current state of the bird. The second always block was used to create a clock that was implemented to generate the pipe coordinates and change them at a speed that the VGA displayed smoothly. The third always block, running at the posedge of the clock that was created in the second always block, incremented the horizontal coordinates of the pipes when the bird is in flight, regenerated random pipes whenever a pipe crossed the left-end of the screen, and reset the initial pipe’s location when the reset button was pressed. The randomness of the pipes came from using the module RNG.v, which will be discussed later in this report.

Vga640x480.v: This module, the framework of which was from the online tutorial files given to us by the TA, was used to display the objects on the VGA. While we kept most of the mechanics, we used them to draw something considerably different. The inputs, which came from the NERP_demo_top.v module, gave the coordinates for the pipes, bird, and the current score. The bird had a constant horizontal assignment of 40 pixels right of the horizontal back porch. But the vertical assignment was dependent on the state of the bird. The pipes, which their positions were inputted from the NERP_demo_top.v module, had a constant width of 50 pixels and were always above the green patch of grass. Furthermore, in order to display our scores, we created a case statement to display in symbolic form the current number of points accrued.

RNG.v: This module was used to randomly generate the y-coordinates of the pipes. This module was implemented as a 21 bit linear-feedback shift register that XORed the 21th bit with the 18th bit, shifted the stored value right by 1, and set the new leftmost bit to the XORed value at the positive edge of each clock cycle. Using sequential logic, we were able to reinitialize our “random” register and create our pseudo-random output. Because we let the RNG continuously run from the start and did not reset the register at any point, we ensured that the values taken from the register to be used as pillar height would differ between playthroughs.

bird.v: This module was used to implement the physics of the bird. Our first always block was used to divide the input clk’s value in order to slow down the pace of the bird’s flight to one better suited to gameplay. The second always block was used to either increase or decrease the bird’s velocity depending on the bird state and the signal of the jump button. When the bird was in flight and the jump button was pressed, the bird’s velocity increased by a decimal value of 10. However, when the jump button was not pressed, the bird’s velocity decreased by 1 for every time unit, emulating a physically accurate fall with constant acceleration. Furthermore, if the bird was no longer in flight, we assigned the velocity to be 0, since the bird had crashed and the game had not restarted yet. The third always block was used to assign the y-coordinate of the bird based on its velocity. If the bird was in flight, we added the velocity’s value to its current y-coordinate value in order to either increment or decrement its y-coordinate position. When the bird had crashed, its y-coordinate was fixed to 0 to represent the fact that it had fallen to the ground. And when the game was reset, then the bird’s y-coordinate was reset to the starting y-coordinate position, which we determined to be 300.

clockdiv.v: This module was given to us by the TA. However, we had to modify this module in order to create a 25MHz clock for the display with our faster chip clock, and to create a clock output with suitable frequency for the bird’s flight. Using an always block, the author of the code created a 17-bit counter. Then using the 17 bit counter, we were able to create a 381.47 Hz and 25 Mhz clock for the bird and the VGA display respectively.

segdisplay.v: This module was used to output the highest score achieved so far on the seven-segment display in hexadecimal. The module cycled through the anodes of the display, lighting one digit up at a time. We used two case statements, one to convert the current score into its cathode representation, and one to synchronize the current anode with the correct lit cathodes to display the digit in that position.

###Conclusion: In summary, our Verilog design of Flappy Bird took the framework code linked to above as a starting point and evolved it greatly. We added new modules bird.v and RNG.v to represent the coordinates of the actors in the game, the bird’s physics-based flight and the pipes’ randomized heights. We also elaborated heavily upon the preexisting modules so that they could support the game behavior we desired. We modified clockdiv.v to work correctly with our different model of FPGA and generate the right frequency for the VGA display, while also providing an appropriate update rate for the bird. We added high score representation capabilities to segdisplay.v. As the top module, NERP_demo_top.v controlled all input and output, as well as all the important game mechanics related to the interaction of actor submodules, like collision detection, game state and scorekeeping. Finally, vga640x480.v drew everything onto the display: current score, bird, pipes, and a background of blue skies and green grass.

We experienced many challenges during our implementation process. Some were related to our inexperience with VGAs. For example, we didn’t realize that vertical coordinates on the display started from the top of the screen and decreased as one moved downward, opposite of what we expected, until after we’d implemented bird.v. We ended up simply “flipping” bird.v’s outputted coordinates where they were used by collision detection and the VGA. Some were bugs in the program itself, such as when it repeatedly gave errors during mapping because it insisted that we’d given it incorrect LOCs in our .ucf file, even though we’d used that same file successfully in every other lab utilizing the Nexys3 FPGA. We finally got the program to map by creating a new project each time and copying all our files over. Many small, insidious bugs also sprang up as we connected modules. Forgetting to denote the correct width of the receiving register or having a typo in the name of the register we were passing wouldn’t keep the program from synthesizing, but it would cause incorrect results that were difficult and time-consuming to trace back to the culprit. With more experience, however, we learned to double-check those parts first when something went wrong, speeding up our debugging process.

This project was a great test of the things we’d learned and our ability to apply them to a fun idea of our own choosing. However, we wish that, in the future, there could be more office hour opportunities. Toward the end, the office hours were very crowded, and sometimes there were entire two-hour periods without free spots where we could work with the lab equipment. It was very difficult to test many aspects of gameplay without an FPGA and a VGA adaptor, and we wish we could have had the time to further improve our game.

About

Flappy Bird on Verilog

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published