In this project, we worked on our version of the whack a mole game which was all simulated on a Nexys-2 board. A Nexys-2 board is a field programmable gate array (FPGA). The FPGA acts as a device based on a program given to it. We use Virtual Hardware Description Language(VHDL) to describe the circuit and send it to the FPGA board to simulate it. We’ll go over what materials are needed, the modules and how the modules work, and how to set the game up itself.
The tweaks we made to the original game include a no loss situation needing a manual reset. Our project is ideal for beginner enthusiasts because of its simplicity and only needing a few materials while still being fun and challenging.
This instructable was made by Michael Le and Joshua Cinco for our CPE 133 class at Cal Poly San Luis Obispo.
Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.
Step 1: Required Materials
- 3 LEDs (Any Colors)
- Nexys FPGA Board by Digilent (We used a Nexys 2 Board)
- ISE Design Suite by Xilinx (Used to write VHDL)
- Adept (Used to send FPGA to the Nexys board)
- Whackamole.zip(All the xilinx files are in here including the vhd files attached at each step)
Step 2: How the Game Works
The whack a mole game uses the bottom row of leds to indicate when "moles" pop up and the user toggles the switch underneath the led to "whack" the "mole". The switch only has to be toggled one way to consider it being a hit to increase the play ability of the game and make it more enjoyable! If the mole isn't "whacked" in a certain time frame the mole will escape and the player loses a life. The "moles" appear in waves and the next wave will only appear when all the moles have been cleared either by being "whacked" or escaping.
The seven segment display on the board keeps track of the score and adds 1 point every time a mole is whacked.
The game can be restarted by pushing the far right button. This will reset all the LEDs and the score.
The game doesn't have a game over state. When 0 lives is reached the lives counter will instead reset to 3 and the game will continue so the player can continuously play and have fun regardless of lives.
Step 3: VHDL Overview
Whack a mole is a game that can be broken up into components that create the functionality of the game.
- Linear Feedback Shift Register (linfeedshift.vhd)
- Whack and Score (whackandscore.vhd)
- Seven Segment Display (sseg_dec.vhd)
- Led Controller (ledcontroller.vhd)
- Clock Divider (clk_div2.vhd)
The functionality of each block will be broken down and described in the following steps with the corresponding the VHDL files attached to the bottom of each step....
Step 4: Linear Feedback Shift Register(linfeedshift.vhd)
That's what we want for when the moles pop up on the board; we don't want them to pop up in a set pattern. To simulate a pseudo-random array we use a linear feedback shift register(LFSR) of 8 bits. A LFSR basically cycles through a finite amount of combinations based on the present state and a little bit of logic. While this isn't exactly random there are up to 377 possible combinations giving the appearance of randomness.
The LFSR takes inputs from the clock, update, and reset signals to output an 8-bit standard logic vector that will be used for the state of the LED. The updated signal input is necessary to change the outputs. If the update is high then the output will change, otherwise the output will stay constant. Regardless of the state the internal signals and the present state of the LFSR is constantly changing on the rising edge of the clock. This helps to create the illusion of randomness because the LFSR and the whack a mole game will only update the LEDs when the wave of moles is gone.
In summary it's an 8-bit random number generator.
Step 5: Hit or Miss? (hitormiss.vhd)
Whack a mole is a game that can be broken down into many components. The main driving force is determining whether the player has successfully "whacked" the mole or if they missed their chance and the mole escaped. Keep in mind the point of this description is to describe the functionality of the module. There are small details within the vhd file that help to create this functionality but they won't be discussed here.
The inputs we have to consider for this module are the LEDs, switch, clock, and reset signals in order to determine a correct output. The outputs are "hit" and "valid" which we will go into detail about later.
The clock is necessary because there is a counter embedded into the hit or miss module that adds 1 on the rising edge of the clock. When the timer reaches its max it creates an internal signal called "maxtime" to indicate that the module needs to update. Maxtime is how we determine whether the player allowed the mole to escape.
Another important internal signal that we need to create is the present state of the switch which will be referred to as "prs". This signal is necessary to create the toggle function that we want to when it comes to whacking a mole. To consider the mole as whacked we have to compare the state of the current state of the switch to the prs. This will create the functionality of being able to toggle a switch from its current state to an opposite state and have it indicate a hit. Without the prs signal, the player would have to move the switch up and down for a hit, which isn't as enjoyable of a gaming experience.
Now we take these signals, the LED, switch, prs, and maxtime and use those to determine the output states of hit and valid. If the LED is low then regardless of the other signals, it outputs low for both hit and valid. Otherwise, if the LED is high, then we have to consider the switch, prs, and maxtime. If maxtime is reached it will output high for valid and low for hit. Otherwise, we have to compare the prs to the switch and if they are not equal it will output high for both valid and hit.
The reason we don't have "miss" as an output is because it can be indicated by the low state of hit. Valid is also necessary because there has to be an indicator that goes along with the hit signal to determine whether or not to take the hit signal.
Now we duplicate this component 8 times to create the vhd file "whack8moles.vhd" which will be integrated into the whack and hit module.
In summary we check the LED, switch, and present state to determine if there was a hit or miss.
Step 6: Keeping Score(using a 8-bit Ripple Carry Adder(ripplecarryadder.vhd) and D Flip Flops(dlfip))
Another important component of whack a mole is to add 1 whenever there is a successful hit and keep track of the score for the player (otherwise what's the point of playing).
We are going to use an 8 bit ripple carry adder(RCA) to add to the score. The RCA is going to take the inputs: current score, hit, valid, and reset. It will add the current score with the hit value when valid is high; otherwise it won't it leaves the score as is. (Picture1)
The RCA will output the new score and a success signal.
The success signal is an output that is high when it successfully adds and has very important implications. It means that the circuit has gone through the whole process of determining if the mole has been hit or not and updating the current score. This signal will be used in the next module: the LED driver.
To update the current score of the game, a d flip flop is necessary because it only updates on the rising edge of the clock when the enable switch is high. Updating on the rising edge of the clock is very important because it allows time for signals to propagate through the circuit and disable the adder so it won't continuously add to itself. (Picture 2)
Next we need a custom adder that will take 8 scores(1 for each potential mole) and give you a final sum. This can be achieved by taking the previous RCAs and just stacking them together to add all the sums together. (Picture 3).
After that the module takes the 8 RCAs, 8 D flip flops, and one custom adder to add the 8 scores together. (Picture 4). It may seem like a lot, but it's just a lot of addition blocks put together to create the final score.
All of this goes to "score8adder.vhd" to make it easier to integrate it together with the other parts.
In summary we use an 8 bit Ripple Carry adder and D flip flops to add scores.
Step 7: Displaying the Lives(Led8miss.vhd)
Keeping track of lives is very similar to keeping track of score, except we have to cap it to 4 possible states. There are only 3 states for lives ( 3 down to 1) and the last state is for when all the lives are lost. In order to do this, we take the signals hit and valid and use them to determine if the player has missed the mole. If it is true, it will add 1 to the current score and one of the lives indicators will turn off. This will go down until there is no more lives left and all the LEDs are off. When that happens, the next miss will overflow the miss counter and the lives will reset to 3 lives.
In summary, it's about the same as counting score, but we are counting misses.
Step 8: Whack and Score(whackandscore.vhd)
Since the scoring and missing is solely dependent on the hit or miss module, we can combine them together into its own module make it simpler to integrate with other modules. This makes "whackandscore.vhd".
Step 9: Seven Segment Display(sseg_dec.vhd)
This module was provided to us by Brian Mealy, a professor at Cal Poly. This module takes an 8 bit binary number and outputs a display on the seven segment display on the nexys board. This module is going to take the current score from the previous step and allow the player to see what their score is.
Step 10: Led Controller(LEDdriver.vhd)
The LED controller is the key component for the user interface between the game and the player. It displays when the moles are ready to be whacked and when they escape. Without this component, there would be no way to play the game.
Remember the success signal in the previous steps? It is very important in this step and will be the main signal that will determine whether the LEDs need to update
The LED controller takes the inputs of reset, 8 success signals(1 for each signal adder in the previous step), clock, and LEDsOn(taken from the LFSR and indicates the next state the LEDs need to be in). The outputs are LEDs(this feeds into the hit or miss module) and an update signal for the LFSR. The LED controller takes these inputs uses them to determine when to turn the LEDs on or off. This is done by individually comparing the success signal with the corresponding LED state. If success is high and the LED state is high, then it will turn off the LED to show the player that the mole has been whacked. If all success signals are high, then it will output a high update signal to the LFSR and will obtain a new set of LEDs to turn on and this process will restart.
In summar, we check the current states of LEDs and success signals, turn LEDs on or off and repeat.
Step 11: Clock Divider(clock_div2.vhd)
The clock divider was also provided by Brian Mealy. Using this module, we can divide the clock cycles to make it slower. We use this to create the cool random sequence of LEDs that appear between waves of moles by giving the random number generator at a faster clock speed and giving the LED controller a slower clock speed. That way the LED controller updates at a slower speed and will take a longer time to latch onto a wave from the LFSR.
Step 12: Connecting the Inputs and Outputs
In Xilinx's I/O pin planning, we assign the inputs and outputs according to the pin outs in the images. In the images above, the pin out can be found for the switches, on-board LEDs, buttons, and the Pmod buses . Connecting the external LEDs to the Pmod buses is a little different, so here's a little guide to help connect them properly:
1. LEDs are polarized with the shorter leg being negative (cathode) and the longer leg being positive (anode). It is really important to identify this or else you’ll burn out the LEDs!
2. Locate the 6-pin Pmod connectors, there are four of them.
3. Starting with the leftmost Pmod connector, which is Pmod JA1, locate the port at the top row closest to the on switch and connect the cathode of one LED directly into it. The anode of this LED goes directly into the fifth port at the top row of JA1.
4. Repeat this with the other two LEDs and the other two Pmods—JB1 and JC1.
Images from Digilent Nexys2 Board Reference Manual
Step 13: Sample Game Play
Here's a video showing the game play! Enjoy!
Note: Sometimes lives are lost even though the player has hit all the moles. This is a result of having different clock speeds for different modules, but it's a trade off to create the random sequence of LEDs to appear between waves of moles.