In this Instructable we will be making what I call a “Rock-Paper-Scissor Machine” which is basically just a computer device that you can play rock paper scissors against. A human (hopefully) will be able to push one of three buttons on a Basys3 board (rock, paper, or scissors) in an attempt to beat out the computer, which randomly chooses either rock, paper or scissors. The computer uses standard Ro-Sham-Bo rules.
FYI, this Instructable is less of a step by step process of how to code this FPGA and more about how this machine works and the basic idea of how to set it up. Everyone codes a project in different ways, so we expect you, the reader, to challenge yourself and try to construct this machine without copying and pasting the code. (which is available in a downloadable file).
Step 1: Materials List!
Here is what you need to make this machine:
Basys 3 Artix-7 FPGA Trainer Board
A computer with some version of Vivado installed on it (I used Vivado 2016.2)
USB A to Micro B
The equipment that we will be using on the board itself is the 7-Segment Display and the set of 5 push-buttons.
Step 2: Top Level Design
In digital design land, we always start our project by drawing what is called a "Black Box Diagram", which is just a pictorial representation of our circuit on the highest level of design (the term "highest" when used in this context can also mean "simplest"). A Black Box Diagram should give the reader a good idea of what kind of inputs the circuit takes and what it outputs.
In our case, our circuit takes in a total of 5 inputs. Three buttons on the board will be the options for Rock, Paper, or Scissors, another button will allow the player to Reset the game, and the last input is a Clock that will control the computer AI and display functions.
Our circuit outputs exactly two things: one 4-bit bus that controls which digit of the 7-Segment Display is on at a moment in time, and another 7-bit bus that controls which segments are displayed at a moment in time.
Step 3: Sub-Module Design
This is a screen shot of our circuit with all of its sub-modules. Each of these performs a specific task on the input data in order to generate a computer answer, compare it to the player answer, and display the results of the game. In consequent steps I will go over what each one of sub-modules do.
Step 4: Clock System
Our design requires clock signals of differing speeds. To do this, we built a generic clock divider that takes an input frequency of 100 MHz and 32 bit divisor and then outputs a desired clock frequency with a 50% duty cycle. The output frequency follows the equation of: Frequency_Out = 100MHz / (2 * Divisor). Using this system, we can divide down to get any desired frequencies to run any of our devices.
Step 5: Storing Input Data and Locking System
This device is connected to the three rock, paper, and scissors inputs as well as the reset button. When one of the inputs is activated, this component stores it in memory and outputs it in three bits and turns the enable output on. When the enable output is activated, it tells other components in the circuit to activate or deactivate. Any components with EI as an input will be connected to this output. The reset input clears the memory, turns the enable output off, and allows another input to be pressed. The device runs at ~500 Hz.
Step 6: Computer Select
This device is what allows the computer to select a random input. While CEN is high, the device will cycle through rock, paper, and scissors. When CEN goes low, it will stop cycling and output the computer's choice in two bits. When RST goes high, the counter will reset. This device runs at 1000 Hz.
Step 7: Computer Selection Decoder
The input for this device is connected to the two bit output from the computer select device. This device converts the two bit input it receives into a three bit output that can be compared to the player's input. When EI is high, it will output the converted three bit signal, otherwise, when EI is low, it will not output anything. This device runs at ~1000 Hz.
Step 8: Comparing User Input to Computer
Now that we have a computer and player selection, we need to compare the two results and see who wins!
Out Input_comparator (IN_comp) module takes the 3-bit buses from the Storage and Computer_selection_decoder modules and uses case statements to output a 7-bit bus to the led_controller. This 7-bit bus will represent a letter on the 7-segment display (for more info on how the 7-segment display works, see Step 9: Displaying the Results). For our project, we chose to represent a Win with the letter "A" (for "Awesome"), an "L" for a loss, and a lowercase "d" for a draw.
This is where the standard rules of Rock-Paper-Scissors come into play (look up the rules in case you do not know how to play Rock-Paper-Scissors).
We compared the two values using case statements. For example, in the case where the Player Input (PI) is rock ("001") and the Computer Input (CI) is paper ("010"), the comparator will output the 7-bit bus "1110001" (L).
Again, we used case statements to do this, but we encourage you to find a better way! Guaranteed our method is probably not the most efficient.
Step 9: Step 8: Decoders
Now we have a Computer Selection, a Player Selection, and a Result. Before we can display them on the board, however, we need to convert these values into a format that the 7-segment can read.
Before we get into converting numbers however, we must first understand how the 7-segments works. Take a look at the internal wiring diagram of the 7-segment and try to figure out how it works on your own.
There are two inputs that a 7-segment requires: a signal that controls the Anode and a signal that controls the Cathode. Each digit has what is called a common cathode for each segment on the display. What this means is if you turn on segment "a", all four digits will have their "a" segment turned on. Also, the cathode (as well as the anode) uses negative logic, which means a '1' turns the LED off and a '0' turns the LED on. So to light segment "a" we would output "0111111" to the cathode.
We chose to represent rock as a little "r", paper as a big "P", and scissors as a big "S" on the 7 segment. Look at the diagram and figure out what segment combinations make these patterns of letters! Or, choose your own interpretation of how rock, paper or scissors should be displayed. It's up to you!
Our decoders operate very similarly to our input comparator. They take in the 3-bit player or computer selection and, using case statements, converts the value into the appropriate 7-segment letter. The main difference is that the decoder is modulated by the rising edge of the Comp_clock. If this is not included, infinite loop errors occur, which is not a good thing.
Step 10: Step 9: Displaying the Results
Finally, we can display the results! The led_controller takes in the decoded Player input, Computer selection, and Result and allows each input to be displayed distinctly on the 7-segment.
The main idea behind this module is to control which digit is displayed at which time. If we were to display all three inputs at the same time, we would get illegible writing all of the display, since all the digits have a common cathode. However, there are four anodes, and if we can cycle through turning on the anodes fast enough, we can fool the human eye into thinking that all anodes are on at the same time (when really they are not).
We achieve this through another counter. A 2 bit counter will do the trick so that at each count of the clock ("00", "01", "10", "11"), we can send out a different anode-bus ("0111", "1011", "1101", "1110"). Note that the anode uses negative logic.
The led_controller then takes one of these unique anode-buses and associates it to the related cathode value. For example, we decided that the first digit would the the player selection, so whenever the anode-bus was "0111" the controller output the player choice (PC) cathode value. We decided that the first digit would be the player choice, the second digit would be the computer choice, the third digit would always be blank and the last digit would be the result.
Step 11: Congrats
If you understood anything about what we said, good job. Hope you have fun playing against your cool new Rock-Paper-Scissors Machine!
If you end up adding anything to your machine (like a countdown or lights or sounds or anything) be sure to let us know!!! We would love to hear about your modifications.