BLACKJACK STRATEGY MASTER
Contents
Design Details
Complete Design Documents
Testing Procedures
VHDL Code
The following report documents the development of the blackjack card counting system. The card counting system is a digital device created for an EE 552 project. The system is capable of informing the user of the appropriate play and the amount to wager on each hand played. The goal of the blackjack card counter is to increase the player's odds to that greater than the house.
The design of the blackjack card counter is implemented with the use of Maxplus2 and is implemented with the Altera EPF10K20RC240-4 FPGA. External hardware used in our design included a 4x4 keypad and a Liquid Crystal Display (LCD), the Emerging Display EC16220YLYU.
For our project we have designed a Blackjack Strategy Device. The user inputs card values, and our device will output how to play the hand (ie stay, hit, double down, split), and a betting factor. These are based respectively on the cards on the table and on those already played.
We have implemented this device with a 4x4 keypad for the input, an Altera 10K20 FPGA for the strategy and counting, and a 2x16 LCD screen for the output.
The user inputs the cards by entering the first digit of the card code (see 5.1, User's Manual), and then pressing the player enter button. The second digit is then pressed, followed by either the player or dealer enter button, depending on whose card it is. The order of cards input does not matter. When both of the player's cards and dealer's card has been entered input logic state machine then waits for a play code, after which it clears registers and changes states as required.
The user also enters the count values via the keypad. They are controlled by the same input logic. There are three count buttons on the keypad that corresponds to high, low and null (H, L, Z). The high corresponds to the cards of value ten to ace, the low corresponds to two through six and the null corresponds to values seven to nine. When one of these buttons are pressed the control logic increments and decrements the betting count, and the running as required. All cards on the table must be entered for the count given to be accurate. Until two thirds of the deck has been dealt, the LCD displays a count of 'X'. When enough cards have been laid, the count will display a betting factor that the user's base bet should be multiplied by for the next hand.
The strategy is implemented in a single entity. It began as a simple strategy, needing only the three card values, but now includes a sum and a flag to indicate extra cards for cases in which there are more than two cards in the players hand. Also, the strategy receives a flag from the input to indicate that the input is valid and outputs a flag for valid output, to avoid sending information to the output that is incorrect. The entity is little more than a very large case statement which depends on the three input cards and the flags.
The output uses the imbedded RAM on the Altera FPGA to store several screens, calling them up as needed and sending the data to the LCD. This RAM has been set as ROM by grounding the write signal, as there is no need to change the data during use. We use a dynamic overwrite to place the betting factor on the screen.
Design Details
The keypad module in our design is the one available to us on the student application notes (www.ee.ualberta.ca/~elliott/ee552/studentAppNotes/98w/keypad/keypad.vhd). Curtis Wickman designed the module and it has been altered by the addition a signal.
The keypad operates with the use of drive and sense lines. The sense lines refer to the lines that are connected to 10 kW resistors and 5 V. These are connected as inputs into the FPGA. The drive lines refer to the lines that are connected as outputs of the FPGA.
When a button is pressed a path to ground is made and the voltage drops to zero. When this happens, the sense signal goes to zero, which signifies that a button has been pressed. The FPGA then sends 5 V through the drive lines. It does so one at a time to determine which row has been pressed. When the correct row has been driven the voltage at the appropriate key's sense line will return to 5 V. In this manner the FPGA is able to determine what key has been pressed.
The keypad module outputs the key pressed in a binary coded format. When the data is outputted, a key detected flag is set and the module will output the data until it receives a continue signal. The continue signal signifies that the data has been received. The addition made to Curtis Wickman's design was the output 'LED'. This signal corresponds to the numerical value that is to be displayed on a seven-segment display.
The control_in receives all the data that relates to the hand played. The player enters the dealer's card and both of the player's cards, each card corresponding to two digits. The cards are inputted by entering one digit followed by an enter and then the next digit followed by the enter that correspond to either the dealer or player. After each card is entered the FSM checks to see if all the cards have been entered by checking if the registers are full. Once all the cards have been entered, the data sent to the strategy, and a dealt flag set high, the FSM wait for its instructions from the strategy. The possible instructions from basic strategy include hit, stand, split and double.
When the stand instruction is received the FSM treats this as a partial reset. The registers that contain the cards played are reset and the FSM returns to the Keypressed State, waiting for more data to be inputted.
When the double instruction is received, it is treated the same as the stand. There is no need to input the next card, as the player is allowed no options after he doubles down.
When the hit instruction is received the FSM must then be capable of receiving the next card. To receive another card, the card 2 register is emptied and the FSM waits for this next card to be inputted. Once the card is inputted, the registers are full and the data is sent to the strategy. Initially, the data to be sent to basic strategy in this case would simply be the sum of all of the cards. The strategy would then base its next play on the sum of the cards. However, this does not take into account the possibility of a soft total. For example, if the player's hand is an ace, a four and a five, the sum will be ten (ace is assigned a value 1). The strategy would then output the play hit, when obviously the correct play is stand because the hand has a value of twenty. To correct this we added a signal that totaled the value of only the cards that are inputted into the card 2 register. We also added a state check that is used to check if the player has been dealt an ace and if so the ace is placed in the card 1 register. What is then outputted to the strategy is card 1 (which contains the ace if dealt) and card 2 (which is the sum of the cards that were in the card 2 register). We must also check to ensure that the value of the cards in the card 2 sum does not exceed ten. If it does, then we simply use the total of all the cards including an ace of value one and set the use_total flag. So for the example above, the data that would be sent to basic strategy is an ace and a nine.
When the play is split, the FSM must know that there are two cards to examine, albeit one at a time. The design must also be able to handle the possibility of splitting an already split hand several times. To accomplish this a counter called split count was created and functions in the following manner. When the play is split the split counter is incremented by one and the card 2 registers are cleared and the hand is played. When the hand is completed and the play is stand the FSM checks the split count before it returns to normal operation. If the split count is not equal to zero there is another hand to be played. The card 2 register is cleared and the split count is decreased by one. In this manner the split count can be incremented several times and the FSM knows that there are still hands to be played.
The buttons labeled 'H', 'L' and 'Z' are the count buttons. When the card dealt is in the range of 10 to ace the 'H' is pressed and the count is decremented by one and increments 'played' by one. If the card dealt is between 2 and 6 then the 'L' button is pressed and the count is incremented by one and 'played' is incremented by one. If the card dealt falls in the range of 7 to 9 then the 'Z' button is pressed and the count is unchanged and 'played' is incremented by one. The current value of the count is sent to the LCD only when two thirds of the deck has been dealt, otherwise a default value of "01111" is sent. To determine when two thirds of the deck has been dealt; the 'played' signal is checked to see if it exceeds two thirds of six decks, a value of 208. When this occurs, the value of the count is sent to the LCD logic as signed binary coded decimal (BCD). The counter uses 2's complement in all its calculations and must be converted to signed BCD. To convert, the first bit of the count is analyzed to determine if the number is positive or negative. If the number is positive it is outputted to the LCD logic. If the number is negative then the FSM sets the first bit of the count is set to one and the 4 LSBs are complemented and one is added. This is now in signed BCD format and is sent to the LCD logic. The value is displayed as the bet factor and has a range between -9 to +9. If the count exceeds these limits the value of the signal sent to the LCD logic is either -9 or +9, whichever is the value exceeded.
The playing strategy was originally implemented in a very basic manner, with few cases, based mostly on the sum of the two cards, and the dealer's possible sum. However, after this was developed, problems were discovered when the player held an ace, as this card has a variable value. So a search was performed for more detailed cases. Once this was found, it was a simple matter of entering all the cases in the new strategy, and double-checking them to ensure that all was as it should be.
It was brought to our attention that we could reduce chip usage if we were to use the embedded RAM on the Altera chip and create a table of cases and their play codes. We decided leave things as they were, but to keep the option open in case of space problems. This way, it would be easier to transfer our design to a different manufacturer's chip, if such a change were demanded. As we continued with our work on the output, we discovered that the LCD output would use nearly the entire chip, and we chose to use RAM for these displays. However, there was still no need to alter the strategy, as the LCD required little space after altering to use RAM, and there was still ample space for the strategy.
There are two main components that controls the output to the LCD. A pictorial view of the architecture can be seen in the following pages. The first of these is the Character codes component. The character codes component controls the screens that the LCD outputs. The second component is the LCD output component. This component outputs all the appropriate instructions to LCD.
The character codes component of the system decides on which screen the LCD should display. A flowchart of these screens is included. It uses the action codes from the strategy logic and a valid flag from the input logic. It does this by setting the ROM address to the first character of the appropriate screen. If there is a betting factor in this screen, then data screen flag is set high so that the LCD output logic will overwrite the ROM at the correct character.
The LCD output logic of our system simply sends a series of instructions to the Liquid Crystal Display (LCD) component. A flowchart of these is included. The instructions can be easily separated into two groups:
When working on our project, we discovered that our original LCD character codes component needed too many logic cells to allow for other significant tasks to be controlled by our FPGA. The manner in which we initially chose to implement the outputs was combinational logic. The combinational logic method output all 32 characters (128 bits) to the LCD output component. This proved inefficient because the printing of only two screens required 623 logic cells. Because our project required eight different output screens, this would have been impossible using combinational logic approach. We would have left no logic cells for the remainder of our project.
The solution to this shortage of logic cells was to implement the output using ROM. The other components in the project did not use any ROM so we had all six embedded array blocks (EABs) at our disposal. The ROM stores the output data, which we then access when necessary. The data is placed in a file that it is programmed in EABs on the FPGA.
The use of combinational logic requires that the all output lines be driven when the output flag has been set. This drives the correct values for the desired output. When using the ROM the data is accessed from the memory location at which it is stored. Once the output flag has been set the LPM_ROM module simply accesses the data stored at the specified memory location. The data is written in a memory file and then configured upon compilation.
Combinational Logic Method
Logic Cells: 623/1152
Number of EAB's -- 0/6
ROM Method
Logic Cells -- 197/1152
Number of EAB's -- 1/6
We find the ROM much preferable when dealing with the case of constant output to LCD. The reduction in the number of logic cells used is dramatic and resolves our major concern. The minimum clock periods for both cases are comparable. In regards to the complexity of our design both cases were once again comparable. Alterations to the output of the LCD will be easier to implement in ROM than in combinational logic, as it requires changes to only the data file.
Another alternative may have been to use the RAM available on the Flex10K20 chip with the aid of the LPM_RAM module. The RAM module allows the user to write to memory during operation as opposed to writing only at load up. The ROM module and RAM module are identical, save that the write line on the module is tied to ground for ROM.
The top level code ties together the four main components: the key pad decoder, the input control, the strategy logic, and the output logic. It was also necessary to slow down the clock through a clock dividing circuit. The external 25Mhz clock was divided by 1000, to make it a 25Khz clock.
Complete Design Documents
Congratulations on your purchase of the Blackjack Strategy Master 2000! Provided below is a brief instruction manual, to insure correct operation.
Step 1: As the hand is dealt out to you and the other player's at the table, enter the count values. If a card falls in the range 10 - Ace then press the 'H' button. If the card dealt lies between 2 - 6 then press the 'L' button. If the card lies between 7 - 9 then press the 'Z' button. When the count has been inputted then proceed to step 2.
Step 2: Now its time to play your hand. All cards correspond to two digits as given below. Input the first digit, followed by the player enter key. Then the next digit is pressed followed by either the player or dealer enter key. It is not required to enter the player's card or the dealer's card in any specific order.
Card |
Digit 1 |
Digit 2 |
2 |
0 |
2 |
3 |
0 |
3 |
4 |
0 |
4 |
5 |
0 |
5 |
6 |
0 |
6 |
7 |
0 |
7 |
8 |
0 |
8 |
9 |
0 |
9 |
10 |
1 |
0 |
Jack |
1 |
1 |
Queen |
1 |
2 |
King |
1 |
3 |
Ace |
0 |
1 |
Step 3: Once all of the data is inputted, a play instruction will be. If the play is hit or split then input the cards that are dealt to you thereafter and follow the play instructions. When the play is stand the strategy master is awaiting the next hand.
Step 4: This step deals with how to use the betting factor. The betting factor is outputted as both a sign and a numerical number (e.g. +7). If the sign is '+' then this signifies that you should increase your wager by a factor of the number being outputted. For the example above your wager should increase seven times. If the sign is '-' then you should decrease your wager by a factor if the number being outputted. For example if the bet factor is '-7' then your wager should be reduced to one seventh's its value. If the bet factor is '+X' then you should proceed with your normal wager.
If at anytime you should press the wrong button then press the reset button on the keypad. This reset button will clear the hand just played and allow you to enter the cards again. This reset does not affect the bet values so it is not necessary to repeat step 1.
The Blackjack Strategy Master 2000 is based on Las Vegas rules blackjack. These rules form the following:
You are now ready to use the Blackjack Strategy Master 2000, Good Luck!
Features:
The Blackjack Strategy Master 2000 is based on Las Vegas rules blackjack. These rules form the following:
- six decks
- dealer stand on soft 17
- doubling allowed on any two cards
- doubling after split allowed
- no surrender
For instructions of the usage of the Blackjack Strategy Master 2000, please refer to the user's manual(5.1).
Device Requirements:
Input Output Memory Logic Cells
Device Pins Pins Bits Percent # %
output_logic
EPF10K20RC240-4 10 11 2048 16 % 197 17 %
extended
EPF10K20RC240-4 20 3 0 0 % 136 11 %
clk_div
EPF10K20RC240-4 1 1 0 0 % 37 3 %
keypad
EPF10K20RC240-4 7 16 0 0 % 139 12 %
control_in
EPF10K20RC240-4 17 41 0 0 % 523 45 %
top
EPF10K20RC240-4 6 29 2048 16 % 992 86 %
Clock period: 100.2ns
Frequency: 9.98 MHz
Pin Numbers
Label |
Type |
Number |
Description |
Clock |
Input |
91 |
25Mhz external clock |
Reset |
Input |
28 |
Global Reset |
LCD_code(0) |
Output |
98 |
Instruction enable |
LCD_code(1) |
Output |
97 |
Least significant data bit |
LCD_code(2) |
Output |
95 |
2nd Data bit |
LCD_code(3) |
Output |
94 |
3rd Data bit |
LCD_code(4) |
Output |
88 |
4th Data bit |
LCD_code(5) |
Output |
87 |
5th Data bit |
LCD_code(6) |
Output |
86 |
6th Data bit |
LCD_code(7) |
Output |
84 |
7th Data bit |
LCD_code(8) |
Output |
83 |
Most significant data bit |
LCD_code(9) |
Output |
99 |
Register select pin |
LCD_code(10) |
Output |
100 |
Read/Write Pin |
LED(0) |
Output |
24 |
Digit 2 - segment g |
LED(1) |
Output |
23 |
Digit 2 - segment f |
LED(2) |
Output |
21 |
Digit 2 - segment e |
LED(3) |
Output |
20 |
Digit 2 - segment d |
LED(4) |
Output |
19 |
Digit 2 - segment c |
LED(5) |
Output |
18 |
Digit 2 - segment b |
LED(6) |
Output |
17 |
Digit 2 - segment a |
LED(7) |
Output |
13 |
Digit 1 - segment g |
LED(8) |
Output |
12 |
Digit 1 - segment f |
LED(9) |
Output |
11 |
Digit 1 - segment e |
LED(10) |
Output |
9 |
Digit 1 - segment d |
LED(11) |
Output |
8 |
Digit 1 - segment c |
LED(12) |
Output |
7 |
Digit 1 - segment b |
LED(13) |
Output |
6 |
Digit 1 - segment a |
Column(0) |
Output |
183 |
Drive line |
Column(1) |
Output |
185 |
Drive line |
Column(2) |
Output |
187 |
Drive line |
Column(3) |
Output |
190 |
Drive line |
Row(0) |
Input |
182 |
Sense line |
Row(1) |
Input |
184 |
Sense line |
Row(2) |
Input |
186 |
Sense line |
Row(3) |
Input |
188 |
Sense line |
Test Cases & Expected Results:
The simulation of the top level can be found in Appendix B. It shows normal operation of a 'hit' situation. There are several omissions due to simulation difficulty of the keypad inputs.
The keypad entity is tested to ensure that the correct key is being detected. The waveforms provided have several different outputs; each corresponding to the different buttons being pressed. The signals keydetected and LED are checked to ensure that they are being correctly outputted. The keypad entity is tested against several scenarios to ensure its correct operation. Simulating this entity also provided valuable insight in its operation. This was essential because Curtis Wickman designed this entity.
The control_in entity was simulated to ensure that the data was being loaded and cleared correctly. There are essentially only four scenarios to test for, those being hit, double, split and stand. To ensure that the data is being loaded correctly and that the LEDs are being set, a hand is inputted to control_in. To test for the four play scenarios different play codes are instantiated and all of the registers and flags are set appropriately. Three waveforms are included to display its correct operation. Only three waveforms are submitted because the play stand is set at the end of every hand.
The extended strategy was tested for every possible case that it could encounter, though not every bit combination it could receive. No exhaustive testing took place, as there would be well over 2000 tests if such were undertaken. There are aproxximatly 300 cases which combinations of the inputs could fall under. The two flags, extra_card_bit and dealt are tested individually, separate from the major cases. However, all test cases follow the order that the case appears in the file, extended.vhd.
There is not a truly exhaustive testing of the output that the LCD preforms. The only variables that change in the screen is the address of which the screen one held in ROM and whether the screen is a data screen. Each of these have been tested, but not with every single address that the character code can output. However, every address coming out of the character code component was tested.
Test 1: This test case tests the initialization commands of the LCD controller as well as a static screen (the betting factor is not printed).
Test 2: This test case tests the data screen (where the betting factor is printed).
Test 3: This tests the entire Component with a data screen.
Test 4: This tests the addresses and card dealt flag coming out of the character code component. It also tests the factor decoder.
Wickman, Curits. "Keypad.vhd" 1998.
http://www.ee.ualberta.ca/~elliott/ee552/studentAppNotes/98w/keypad/keypad.vhd .
Holden, Micheal. Mah, Milton. Scott, Korrey. "Using an LCD in Hardware Projects" 1998. http://www.ee.ualberta.ca/~elliott/ee552/studentAppNotes/98w/Liquid_Crystal_Display .
Uston, Ken. "Million Dollar Blackjack" 1992
Sharp LM16255 Manufacturer's Data sheets (LCD)
Ashton, Peter J. "The Student's Guide to VHDL" 1998
Strategy documentation