Introduction: 'Simon' CPE 133 Final Project
The all time classic childhood game "Simon" will be recreated to be implemented using VHDL on the NEXYS 3 board. Instead of pressing the colored buttons, users will witness the random pattern created and then have to input that said pattern on the buttons on the NEXYS 3 board. Users will have to use their skills in memory and understanding to recreate the pattern to beat the game. If user fails to recreate the pattern, they can simply try again.
Best of luck!
Authors: Vineal Singh and Dennis Tsuker
Step 1: First Finite State Machine
The two states of the first FSM we created were display and wait to properly display a pattern on the LEDs.
The FSM begins in the wait state and once the start signal is pressed, it would move to the display state to show the pattern. Once the display was generated, the program would move back to the wait state based on the max counter value being high it would then transfer over to the second FSM which would compare the user's input to the display.
In our project, we wanted to create a random pattern for the LEDs. In order to do so, the code must have a random number generator. We used vhdl for an LFSR (linear feedback shift register) that was given to us in class by Professor Danowitz for the random number generator.
This random number generator needs to be connected to the LEDs, where different outputs of the generator are associated to each of the 4 LEDs. Our random number generator creates a random 32 bit number, and we divided each LED to turn on based on what the value of the random number generator was in hex.
It is important in the vhdl to have a start signal, which we assigned to a button. In this case, whenever the button is pushed then the random number generator would start and therefore the LEDs would display. With this, the user has the option of starting the game whenever they are ready.
In addition, we created a timer to slow down the clock in order for the LED display to be visible to the human eye instead of being lit up for a nanosecond. We found an example of a timer online which we altered to work for our game which can be found in the references. The timer also creates a max counter signal: this happens when clock goes through one cycle.
We also introduced a d-flip-flop to latch the value generated from the LFSR for one clock cycle. This output then became the input of a multiplexer so that the LED would be either turned on or off for one clock cycle. Because of the multiplexer, we have a select signal that is determined by the state of the FSM; if the state is display then select would be high, if it was in wait then it would be low. This is a technique we used so that the LED would stay lit for a short period of time and then turn off to create a pattern.
The purpose of the wait state was for the LED display to tell the program when the pattern was ready to be generated and then continue onto the next FSM when it was finished displaying the pattern.
Step 2: Second Finite State Machine
Once the LED pattern works, we need to be able to obtain the user's input to see if they are either correct or incorrect. In Simon, every part of the pattern must be matched in order to beat the game. In this FSM we had two states: wait and check-input.
In this state, we had to create a module for mapping the buttons to there respective LEDs. We used buttons instead of switches to mimic the game type of the real Simon game. We also had another module for the comparison between the user's input and the actual pattern displayed by the LEDs. If the user was correct, the game would be transferred to the first FSM and a new pattern would be generated. If the input did not match, then it would go to the game over state in the third FSM. Once the check input state would finish (the player's input is correct OR incorrect) it would transfer back to the wait state.
Similarly to the first wait state, this state would act like a hold for the program. When the max counter would be high it would go to the check-input state, or else the FSM would stay in the wait state.
Step 3: Third Finite State Machine
In this game over FSM we had two states: game over and wait state.
If the check-input state from the second FSM was incorrect, it would then transition the game into the game over state.
Game Over state:
In this state, if the start button was pressed the game would transfer back to the first FSM into the display state and also the game over state would transfer into the wait state of the third FSM. The game itself starts in the game over state and awaits the signal to start when the user presses the start button. Whenever in the game over state an external LED would turn on signifying that the game is ready for the user to begin and is waiting for the start button to be pushed.
Similar to the other two wait states, this state would transition to the game over state only if the user pressed an incorrect button when trying to match the pattern of the display.
Step 4: TOP LEVEL MODULE
The purpose of this module is to connect all three FSMs together to run smoothly to create the Simon game.
We created signals to connect certain outputs of FSMs with inputs of FSMs.
The start button from the third FSM became the input of the first FSM, which acted as a start signal for the whole program.
Next, the max counter in the first FSM was used as an input for the second FSM in which it told the program that the display was finished and it was ready for the user's input.
In the second FSM, the check input state's output would either go to the first or third FSM depending on whether or not the user's input was correct or incorrect. If it was correct, the signal of the output would be sent to the first FSM as a start signal to begin displaying a new pattern; if it was incorrect, the signal would be sent to the game over state.
Step 5: User Constraint File
In order for the program to work how we wanted it, we had to map the inputs and outputs properly onto the NEXYS 3 board.
Step 6: Photos of Start(top) and Game Play(bottom)
Andrew Danowitz, "LFSR", Cal Poly, 20-132, November 21st, 2014
"VHDL Clock Divider: Counter - Duty Cycle." - Stack Overflow. N.p., n.d. Web. 27 Nov. 2014.