-------------------------------------------------------------------------- -- control_in.vhd -- -- -- -- Project: Blackjack Card Counter -- -- Rishi Kapoor 355655 -- -- Matthew Remington 364463 -- -- Denise Garvey xxxxxx -- -------------------------------------------------------------------------- -- this file is used to store all the data recevied from the keypad.vhd-- -- file. All of the data recevied is processed and then outputted to -- -- both basic strategy and the LCD logic. This file is annotated -- -- throughout to explain its functions. -- -------------------------------------------------------------------------- library ieee; library work; use work.control_bits.all; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity control_in is port ( clk : in std_logic; reset : in std_logic; KeyDetected : in std_logic; play_valid : in std_logic; play_code : in std_logic_vector(play_bits downto 0); KeyData : in std_logic_vector(keydata_bits downto 0); led_in : in std_logic_vector(ledin_bits downto 0); LED : out std_logic_vector(LED_bits downto 0); decimal : out std_logic_vector(play_bits downto 0); dealer_data : out std_logic_vector(card_bits downto 0); player_card1: out std_logic_vector(card_bits downto 0); player_card2: out std_logic_vector(card_bits downto 0); card_total : buffer std_logic_vector(total_bits downto 0); bet : out std_logic_vector(bet_bits downto 0); done : out std_logic; use_total : out std_logic; Continue : out std_logic ); end control_in; architecture control of control_in is type state_type is (nothing, keypressed, secondkey, getcard, dealt, nil, getenter, gamma, decode1, decode2, player1, player2, dealer, hit, total_reset, dealtcard, stand, double, split, split_code, count, check, delay, delay1, delay2, delay3); signal state : state_type; signal Drive : state_type; signal valid_code, split_count, counter : std_logic_vector(4 downto 0); signal card, player1_data, player2_data : std_logic_vector(3 downto 0); signal dealer_flag, player1_flag, player2_flag, clear : std_logic; signal hold1, hold2 : std_logic_vector(3 downto 0); signal played : std_logic_vector(8 downto 0); signal total_card2 : std_logic_vector(3 downto 0); begin -- this process is used to analyze the data received to determine what type of button is pressed. -- it converts that into a signal called play code. the bits in the play code are as follow -- N_P_R_C_D which correspond to number, player, reset, count and dealer. this process reduces -- the number of if statements required in the FSM analyze: process(clk) begin if falling_edge(clk) then if KeyDetected = '1' then case KeyData is when "1100" => valid_code <= "01000"; when "1101" => valid_code <= "00100"; when "1010" => valid_code <= "00010"; when "1110" => valid_code <= "00010"; when "1011" => valid_code <= "00010"; when "1111" => valid_code <= "00001"; when "0000" => valid_code <= "10000"; when "0001" => valid_code <= "10000"; when "0010" => valid_code <= "10000"; when "0011" => valid_code <= "10000"; when "0100" => valid_code <= "10000"; when "0101" => valid_code <= "10000"; when "0110" => valid_code <= "10000"; when "0111" => valid_code <= "10000"; when "1000" => valid_code <= "10000"; when "1001" => valid_code <= "10000"; when others => valid_code <= "10000"; end case; card <= KeyData; end if; end if; end process analyze; FSM : process(clk) begin -- asynchronous reset if reset = '0' then state <= keypressed; Drive <= total_reset; decimal <= "11"; elsif rising_edge(clk) then -- keypad reset -- if KeyDetected = '1' then if valid_code = "00100" and KeyDetected = '1' then state <= delay; Drive <= nil; Continue <= '1'; LED <= "11111101111110"; dealer_flag <= '0'; player1_flag <= '0'; player2_flag <= '0'; -- end if; else case state is -- this state puts the ace in player1 data if an ace has been dealt when check => if player2_data = "0001" then player2_data <= player1_data; total_card2 <= total_card2 + player1_data; player1_data <= "0001"; else total_card2 <= total_card2 + player2_data; end if; state <= dealt; Drive <= dealtcard; -- done <= '1'; -- this state checks to see if the hand has bee dealt when nothing => if dealer_flag = '1' then if player1_flag = '1' then if player2_flag = '1' then state <= check; --dealt; Drive <= nil; --dealtcard; else state <= keypressed; Drive <= nil; end if; else state <= keypressed; Drive <= nil; end if; else state <= keypressed; Drive <= nil; end if; Continue <= '0'; -- this state operates the countinue flag and operates the same as all the delay states when delay => if KeyDetected = '0' then Continue <= '0'; state <= keypressed; Drive <= nil; end if; -- this state recieves the data from the first state when keypressed => if KeyDetected = '1' then if valid_code = "10000" then state <= delay1; Drive <= decode1; Continue <= '1'; elsif valid_code = "00010" then state <= count; Drive <= nil; Continue <= '1'; else Drive <= nil; state <= delay; Continue <= '1'; end if; end if; when delay1 => if KeyDetected = '0' then Continue <= '0'; state <= getenter; Drive <= nil; done <= '0'; end if; -- this state waits for the enter when getenter => if KeyDetected = '1' then if Valid_code = "01000" then Continue <= '1'; state <= delay2; Drive <= gamma; else Drive <= nil; state <= delay1; Continue <= '1'; end if; end if; when delay2 => if KeyDetected = '0' then Continue <= '0'; state <= secondkey; Drive <= nil; end if; -- this state gets the second key when secondkey => if KeyDetected = '1' then if valid_code = "10000" then state <= delay3; Drive <= decode2; Continue <= '1'; else Drive <= nil; state <= delay2; Continue <= '1'; end if; end if; when delay3 => if KeyDetected = '0' then Continue <= '0'; state <= getcard; Drive <= nil; end if; -- this state finds out who the card belongs to when getcard => if KeyDetected = '1' then if Valid_code = "01000" then if player1_flag = '0' then Drive <= player1; state <= nothing; Continue <= '1'; elsif player2_flag = '0' then Drive <= player2; state <= nothing; player2_flag <= '1'; Continue <= '1'; end if; elsif Valid_code = "00001" then if dealer_flag = '0' then Drive <= dealer; state <= nothing; dealer_flag <= '1'; Continue <= '1'; end if; else Drive <= nil; state <= delay3; Continue <= '1'; end if; end if; -- this state waits for the play code when dealt => if play_valid = '1' then decimal(1) <= '0'; if play_code = "01" then state <= delay; Drive <= hit; elsif play_code = "10" then state <= delay; Drive <= stand; elsif play_code = "00" then if split_count = "00000" then state <= delay; Drive <= stand; else Drive <= split; state <= delay; end if; elsif play_code = "11" then Drive <= split_code; state <= delay; else Drive <= nil; state <= dealt; end if; end if; -- this state handles the count and the number of cards played when count => if card = "1010" then counter <= counter - 1; state <= delay; played <= played + 1; Drive <= nil; LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; Continue <= '1'; elsif card = "1011" then counter <= counter + 1; state <= delay; played <= played + 1; Drive <= nil; LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; Continue <= '1'; elsif card = "1110" then played <= played + 1; state <= delay; Drive <= nil; LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; Continue <= '1'; else state <= delay; Drive <= nil; Continue <= '1'; end if; when others => state <= keypressed; Drive <= stand; end case; end if; case Drive is when nil => -- do nothing -- this state outputs the LED when gamma => LED(6 downto 0) <= led_in; -- this state latchs the data and sets the LED's when decode1 => hold1 <= card; LED(13 downto 7) <= led_in; LED(6 downto 0) <= "1111111"; -- this state latchs the data and sets the LED's when decode2 => hold2 <= card; LED(6 downto 0) <= led_in; -- this state puts the card value into the registers and adds to the total when player1 => LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; if hold1 = "0000" then player1_data <= hold2; card_total(3 downto 0) <= hold2; card_total(4) <= '0'; else player1_data <= hold2 + 10; card_total <= "01010"; end if; player1_flag <= '1'; -- this state puts the card value into the registers and adds to the total when player2 => LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; if hold1 = "0000" then player2_data <= hold2; card_total <= card_total + hold2; else player2_data <= hold2 + 10; card_total <= card_total + 10; end if; -- this state assigns the card value to the dealer register when dealer => LED(13 downto 7) <= "1111111"; LED(6 downto 0) <= led_in; if hold1 = "0000" then dealer_data <= hold2; else dealer_data <= hold2 + 10; end if; -- this state processes all the data and outputs to both strategy and LCD when dealtcard => if played < 5 then bet <= "01111"; elsif counter(4) = '0' then if counter(3 downto 0) > 9 then bet <= "01001"; else bet(4) <= '0'; bet(3 downto 0) <= counter(3 downto 0); end if; else if counter(3 downto 0) > 6 then bet(4) <= '1'; bet(3 downto 0) <= not(counter(3 downto 0)) + 1; else bet <= "11001"; end if; end if; if total_card2 > "1010" then use_total <= '1'; else player_card1 <= player1_data; player_card2 <= total_card2; end if; done <= '1'; decimal(0) <= '0'; -- this state clears registers when the play is a hit when hit => player2_flag <= '0'; player2_data <= ( others => '0' ); -- this state clears all registers not associated with count when stand => -- reset_out <= '1'; clear <= '1'; dealer_flag <= '0'; player1_flag <= '0'; player2_flag <= '0'; card_total <= "00000"; LED <= "11111101111110"; player1_data <= (others => '0'); player2_data <= (others => '0'); dealer_data <= (others => '0'); -- done <= '0'; player_card1 <= (others => '0'); player_card2 <= (others => '0'); hold1 <= (others => '0'); hold2 <= (others => '0'); total_card2 <= ( others => '0' ); use_total <= '0'; -- this state clears all registers when total_reset => clear <= '1'; total_card2 <= ( others => '0' ); dealer_flag <= '0'; player1_flag <= '0'; player2_flag <= '0'; card_total <= "00000"; LED <= "11111101111110"; player1_data <= (others => '0'); player2_data <= (others => '0'); dealer_data <= (others => '0'); done <= '0'; player_card1 <= (others => '0'); player_card2 <= (others => '0'); hold1 <= (others => '0'); hold2 <= (others => '0'); use_total <= '0'; played <= (others => '0'); counter <= (others => '0'); bet <= (others => '0'); -- this state is when the play is a split when split_code => total_card2 <= ( others => '0' ); card_total(3 downto 0) <= player1_data; card_total(4) <= '0'; split_count <= split_count + 1; player2_flag <= '0'; player2_data <= ( others => '0' ); -- this state is when the play is stand but there still remains a hand because of the split when split => total_card2 <= ( others => '0' ); card_total(3 downto 0) <= player1_data; card_total(4) <= '0'; split_count <= split_count - 1; player2_flag <= '0'; player2_data <= ( others => '0' ); when others => LED <= "11111101111110"; end case; end if; end process FSM; end control;