------------------------------------------------------------------ -- Score Keeper -- -- File Name : score_keeper.vhd -- -- Author : Gabriel Chereches -- -- Function : This Block Keeps track of all the scores for -- -- the Blackjack. -- -- (The features are subject to change as the system evolves) -- ------------------------------------------------------------------ -- IEEE Library LIBRARY ieee; USE ieee.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; ENTITY score_keeper IS -- Generic parameters GENERIC (n :INTEGER := 2); -- Number of players PORT( Clk :IN STD_LOGIC; -- Global Clk Reset :IN STD_LOGIC; -- Global Reset -- from Card Keeper Card :IN STD_LOGIC_VECTOR (3 downto 0); -- Card Value -- form controller PL_Accept :IN STD_LOGIC_VECTOR (n-1 downto 0);--output form controller HP_Accept :IN STD_LOGIC; Two :IN STD_LOGIC_VECTOR(1 downto 0); SK_Status :OUT STD_LOGIC; SK_PL :OUT STD_LOGIC_VECTOR (n-1 downto 0); SK_Game_Over :BUFFER STD_LOGIC; -- from the Player modules PL_Stand :IN STD_LOGIC_VECTOR (n-1 downto 0);-- Player Stand signals PL_Ace :IN STD_LOGIC_VECTOR(n-1 downto 0); PL1_Bet :IN STD_LOGIC_VECTOR (7 downto 0);-- Number of chips bet by player1 PL2_Bet :IN STD_LOGIC_VECTOR (7 downto 0);-- Number of chips bet by player2 -- Inputs from House_Player module HP_Stand :IN STD_LOGIC; -- House Player Stand HP_Ace :IN STD_LOGIC; -- General Outputs Total1 :BUFFER STD_LOGIC_VECTOR (9 downto 0);-- Total Number of chips Total2 :BUFFER STD_LOGIC_VECTOR (9 downto 0); Chips1 :OUT STD_LOGIC_VECTOR (9 downto 0);-- Chips received after each game Chips2 :OUT STD_LOGIC_VECTOR (9 downto 0); PL1_Sum :BUFFER STD_LOGIC_VECTOR (4 downto 0);--signal PL2_Sum :BUFFER STD_LOGIC_VECTOR (4 downto 0);--signal HP_Sum :BUFFER STD_LOGIC_VECTOR (4 downto 0);--signal BlackJack :BUFFER STD_LOGIC_VECTOR(n-1 downto 0); Win :BUFFER STD_LOGIC_VECTOR(n-1 downto 0); Push :BUFFER STD_LOGIC_VECTOR(n-1 downto 0); Lose :BUFFER STD_LOGIC_VECTOR(n-1 downto 0); PL_Out :BUFFER STD_LOGIC_VECTOR(n-1 downto 0); End_BJ :BUFFER STD_LOGIC ); END score_keeper; ARCHITECTURE behavior OF score_keeper IS signal Bet1 : STD_LOGIC_VECTOR (7 downto 0); signal Bet2 : STD_LOGIC_VECTOR (7 downto 0); signal LoadCard : STD_LOGIC_VECTOR (3 downto 0); signal CardValue : STD_LOGIC_VECTOR (3 downto 0); signal Accept : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_BJ : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_Less : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_EQ : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_Equal : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_Greater : STD_LOGIC_VECTOR(n-1 downto 0); signal Outa : STD_LOGIC_VECTOR(n-1 downto 0); signal Outb : STD_LOGIC_VECTOR(n-1 downto 0); signal PL_Stop : STD_LOGIC_VECTOR(n-1 downto 0); signal Count : STD_LOGIC_VECTOR (6 downto 0); signal HP_Stop : STD_LOGIC; signal HP_Greater : STD_LOGIC; signal HP_Equal : STD_LOGIC; signal HP_Less : STD_LOGIC; signal HP_EQ : STD_LOGIC; signal HP_BJ : STD_LOGIC; signal TwoSig : STD_LOGIC; signal TwoS : STD_LOGIC; signal G : STD_LOGIC; signal Score : STD_LOGIC; signal Ace : STD_LOGIC; signal End_Game : STD_LOGIC; begin -------------------------------- -- Take Bets From Each Player -- -------------------------------- -- Player 1 process (Clk, Reset, SK_Game_Over, PL1_Bet) Begin if ((Reset = '1') OR (SK_Game_Over = '1')) then Bet1 <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (PL1_Bet > "00000000") then Bet1 <= PL1_Bet; else Bet1 <= "00000000"; end if; end if; end process; -- Player 2 process (Clk, Reset, SK_Game_Over, PL2_Bet) Begin if ((Reset = '1') OR (SK_Game_Over = '1')) then Bet2 <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (PL2_Bet > "00000000") then Bet2 <= PL2_Bet; else Bet2 <= "00000000"; end if; end if; end process; -- Delay PL_Accept and HP_Accept by one clock cycle process (Clk, Reset, PL_Accept, HP_Accept) Begin if (Reset = '1') then Accept <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (PL_Accept(0) = '1') then Accept <= "01"; elsif (PL_Accept(1) = '1') then Accept <= "10"; elsif (HP_Accept = '1') then Accept <= "11"; else Accept <= "00"; end if; end if; end process; -- Delay Card value by one clock cycle process (Clk, Reset, SK_Game_Over, Card, HP_Stop) Begin if ((Reset = '1') OR (SK_Game_Over = '1')) then LoadCard <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (HP_Stop = '0') then LoadCard <= Card; else LoadCard <= "0000"; end if; end if; end process; -- second card being played -- the Input signal Two is high as long as the players are accepting the -- second card. This signal is delayed by two clock cycles to be able to -- identify the case of a BlackJack for House Player process (Clk, Reset, SK_Game_Over, Two) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then TwoS <= '0'; elsif (Clk'event and Clk = '1') then if (Two = "01") then TwoS <= '1'; else TwoS <= '0'; end if; end if; end process; process (Clk, Reset, SK_Game_Over, TwoS) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then TwoSig <= '0'; elsif (Clk'event and Clk = '1') then if (TwoS = '1') then TwoSig <= '1'; else TwoSig <= '0'; end if; end if; end process; process (Reset, SK_Game_Over, TwoSig) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then SK_Status <= '0'; elsif (TwoSig'event and TwoSig = '0') then SK_Status <= '1'; end if; end process; process(Clk, Reset, SK_Game_Over, LoadCard, HP_Ace, PL_Ace) begin if (SK_Game_Over = '1') then Ace <= '0'; else if (LoadCard = "0001") then if (Accept = "11") then if (HP_Ace = '1') then Ace <= '1'; else Ace <= '0'; end if; end if; if (Accept = "01") then if (PL_Ace(0) = '1') then Ace <= '1'; else Ace <= '0'; end if; end if; if (Accept = "10") then if (PL_Ace(1) = '1') then Ace <= '1'; else Ace <= '0'; end if; end if; else Ace <= '0'; end if; end if; end process; -- When card = Ace, the Players have to sellect Card value 1 or 11 Compare11: process (LoadCard, Ace) begin if (LoadCard = "0001") then if (Ace = '1') then CardValue <= "1011"; -- 1011(bin) = 11(dec) else CardValue <= "0001"; end if; else CardValue <= LoadCard; end if; end process; ---------------------------------- -- Sum of Cards for each Player -- ---------------------------------- -- House process (Clk, Reset, SK_Game_Over, Accept, CardValue, HP_Sum) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then HP_Sum <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (Accept = "11") then HP_Sum <= HP_Sum + CardValue; else HP_Sum <= HP_Sum; end if; end if; end process; -- Player 1 process (Clk, Reset, SK_Game_Over, Accept, CardValue, PL1_Sum) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL1_Sum <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (Accept = "01") then PL1_Sum <= PL1_Sum + CardValue; else PL1_Sum <= PL1_Sum; end if; end if; end process; -- Player 2 process (Clk, Reset, SK_Game_Over, Accept, CardValue, PL2_Sum) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL2_Sum <= (OTHERS => '0'); elsif (Clk'event and Clk = '1') then if (Accept = "10") then PL2_Sum <= PL2_Sum + CardValue; else PL2_Sum <= PL2_Sum; end if; end if; end process; -------------------------- -- Compare Sum of Cards -- -------------------------- -- Equal to 21 process (SK_Game_Over, HP_Sum, PL1_Sum, PL2_Sum) begin if (SK_Game_Over = '1') then HP_EQ <= '0'; PL_EQ <= (OTHERS => '0'); else -- House if (HP_Sum = "10101") then HP_EQ <= '1'; else HP_EQ <= '0'; end if; -- Player 1 if (PL1_Sum = "10101") then PL_EQ(0) <= '1'; else PL_EQ(0) <= '0'; end if; -- Player 2 if (PL2_Sum = "10101") then PL_EQ(1) <= '1'; else PL_EQ(1) <= '0'; end if; end if; end process; -- Equal to 21 with 2 cards => BlackJack -- House process(Clk, Reset, SK_Game_Over, HP_EQ, TwoSig, Two) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then HP_BJ <= '0'; elsif (Clk'event and Clk = '1') then -- the Case statement is replaced by the if statement because the Top Module -- delays the outputs of the scores by one clock cycle and the blackjack for -- the House is not recognized. if ((Two = "01") OR (TwoSig = '1')) then -- Case TwoSig is -- when '1' => if (HP_EQ = '1') then if (HP_EQ = '1') then HP_BJ <= '1'; end if; -- when others => NULL; -- end case; end if; end if; end process; -- Player 1 process(Clk, Reset, SK_Game_Over, PL_EQ(0), TwoSig) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL_BJ(0) <= '0'; elsif (Clk'event and Clk = '1') then Case TwoSig is when '1' => if (PL_EQ(0) = '1') then PL_BJ(0) <= '1'; end if; when others => NULL; end case; end if; end process; -- Player 2 process(Clk, Reset, SK_Game_Over, PL_EQ(1), TwoSig) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL_BJ(1) <= '0'; elsif (Clk'event and Clk = '1') then Case TwoSig is when '1' => if (PL_EQ(1) = '1') then PL_BJ(1) <= '1'; end if; when others => NULL; end case; end if; end process; -- Equal to 21 with more than two card -- ----------------------------------------- -- House process (SK_Game_Over, HP_BJ, HP_EQ) begin if (SK_Game_Over = '1') then HP_Equal <= '0'; else if (HP_EQ = '1') then case HP_BJ is when '1' => HP_Equal <= '0'; when '0' => HP_Equal <= '1'; when others => NULL; end case; else HP_Equal <= '0'; end if; end if; end process; -- Player 1 process (SK_Game_Over, PL_BJ(0), PL_EQ(0)) begin if (SK_Game_Over = '1') then PL_Equal(0) <= '0'; else if (PL_EQ(0) = '1') then case PL_BJ(0) is when '1' => PL_Equal(0) <= '0'; when '0' => PL_Equal(0) <= '1'; when others => NULL; end case; else PL_Equal(0) <= '0'; end if; end if; end process; -- Player 2 process (SK_Game_Over, PL_BJ(1), PL_EQ(1)) begin if (SK_Game_Over = '1') then PL_Equal(1) <= '0'; else if (PL_EQ(1) = '1') then case PL_BJ(1) is when '1' => PL_Equal(1) <= '0'; when '0' => PL_Equal(1) <= '1'; when others => NULL; end case; else PL_Equal(1) <= '0'; end if; end if; end process; -- Greater then 21 ------------------ process (SK_Game_Over, HP_Sum, PL1_Sum, PL2_Sum) begin if (SK_Game_Over = '1') then HP_Greater <= '0'; PL_Greater <= (OTHERS => '0'); else -- House if (HP_Sum > "10101") then HP_Greater <= '1'; else HP_Greater <= '0'; end if; -- Player 1 if (PL1_Sum > "10101") then PL_Greater(0) <= '1'; else PL_Greater(0) <= '0'; end if; -- Player 2 if (PL2_Sum > "10101") then PL_Greater(1) <= '1'; else PL_Greater(1) <= '0'; end if; end if; end process; -- Less than 21 - Depends on Stand Signal -- -------------------------------------------- process (SK_Game_Over, HP_Stand, PL_Stand, HP_Sum, PL1_Sum, PL2_Sum) begin if (SK_Game_Over = '1') then HP_Less <= '0'; PL_Less <= (OTHERS => '0'); else -- House if ((HP_Stand = '1') AND (HP_Sum < "10101")) then HP_Less <= '1'; else HP_Less <= '0'; end if; -- Player 1 if ((PL_Stand(0) = '1') AND (PL1_Sum < "10101")) then PL_Less(0) <= '1'; else PL_Less(0) <= '0'; end if; -- Player 2 if ((PL_Stand(1) = '1') AND (PL2_Sum < "10101")) then PL_Less(1) <= '1'; else PL_Less(1) <= '0'; end if; end if; end process; ------------------------------- -- Stop From Accepting Cards -- ------------------------------- -- House process (Clk, Reset, SK_Game_Over, HP_Sum, HP_EQ, HP_Greater, HP_Less) begin if ((Reset = '1') OR (SK_Game_Over = '1'))then HP_Stop <= '0'; elsif (Clk'event and Clk = '1') then if (HP_Sum > "00000") then if ((HP_Greater = '1') OR (HP_Less = '1') OR (HP_EQ = '1')) then if (TwoSig = '0') then HP_Stop <= '1'; end if; else HP_Stop <= '0'; end if; end if; end if; end process; -- Player 1 process (Clk, Reset, SK_Game_Over, PL1_Sum, PL_EQ(0), PL_Greater(0), PL_Less(0)) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL_Stop(0) <= '0'; SK_PL(0) <= '1'; elsif (Clk'event and Clk = '1') then if (PL1_Sum > "00000") then if ((PL_Greater(0) = '1') OR (PL_Less(0) = '1') OR (PL_EQ(0) = '1')) then PL_Stop(0) <= '1'; SK_PL(0) <= '0'; else PL_Stop(0) <= '0'; SK_PL(0) <= '1'; end if; end if; end if; end process; -- Player 2 process (Clk, Reset, SK_Game_Over, PL2_Sum, PL_EQ(1), PL_Greater(1), PL_Less(1)) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then PL_Stop(1) <= '0'; SK_PL(1) <= '0'; elsif (Clk'event and Clk = '1') then if (PL2_Sum > "00000") then if ((PL_Greater(1) = '1') OR (PL_Less(1) = '1') OR (PL_EQ(1) = '1')) then PL_Stop(1) <= '1'; SK_PL(1) <= '0'; else PL_Stop(1) <= '0'; SK_PL(1) <= '1'; end if; end if; end if; end process; ------------------------------------------------------- -- Find Blackjack, Win, Push or Lose For Each Player -- ------------------------------------------------------- process ( SK_Game_Over, HP_Stop, HP_Sum, HP_BJ, HP_Equal, HP_Less, HP_Greater, PL1_Sum, PL2_Sum, PL_BJ, PL_Equal, PL_Less, PL_Greater) begin if (SK_Game_Over = '1') then BlackJack <= (OTHERS => '0'); Win <= (OTHERS => '0'); Push <= (OTHERS => '0'); Lose <= (OTHERS => '0'); else if (HP_Stop = '1') then -- Case when House Equals BlackJack if (HP_BJ = '1') then -- Player 1 case PL_BJ(0) is when '1' => Push(0) <= '1'; when '0' => Lose(0) <= '1'; when others => NULL; end case; -- Player 2 case PL_BJ(1) is when '1' => Push(1) <= '1'; when '0' => Lose(1) <= '1'; when others => NULL; end case; elsif (HP_BJ = '0') then if (PL_BJ(0) = '1') then BlackJack(0) <= '1'; end if;-- Player 1 if (PL_BJ(1) = '1') then BlackJack(1) <= '1'; end if;-- Player 2 -- Case when House Equals 21 if (HP_Equal = '1') then -- Player 1 case PL_Equal(0) is when '1' => Push(0) <= '1'; when '0' => if (PL_BJ(0) = '0') then Lose(0) <= '1'; end if; when others => NULL; end case; -- Player 2 case PL_Equal(1) is when '1' => Push(1) <= '1'; when '0' => if (PL_BJ(1) = '0') then Lose(1) <= '1'; end if; when others => NULL; end case; elsif (HP_Equal = '0') then if (PL_Equal(0) = '1') then Win(0) <= '1'; end if;-- Player 1 if (PL_Equal(1) = '1') then Win(1) <= '1'; end if;-- Player 2 end if; end if; -- Case when House is Smaller then 21 if (HP_Less = '1') then -- Player 1 if (PL_Less(0) = '1') then if (HP_Sum > PL1_Sum) then Lose(0) <= '1'; elsif (HP_Sum = PL1_Sum) then Push(0) <= '1'; elsif (HP_Sum < PL1_Sum) then Win(0) <= '1'; end if; end if; -- Player 2 if (PL_Less(1) = '1') then if (HP_Sum > PL2_Sum) then Lose(1) <= '1'; elsif (HP_Sum = PL2_Sum) then Push(1) <= '1'; elsif (HP_Sum < PL2_Sum) then Win(1) <= '1'; end if; end if; end if; -- Case when House Greater then 21 if (HP_Greater = '1') then -- Player 1 if (PL_Greater(0) = '1') then Push(0) <= '1'; else Win(0) <= '1'; end if; -- Player 2 if (PL_Greater(1) = '1') then Push(1) <= '1'; else Win(1) <= '1'; end if; elsif (HP_Greater = '0') then if (PL_Greater(0) = '1') then Lose(0) <= '1'; end if; -- Player 1 if (PL_Greater(1) = '1') then Lose(1) <= '1'; end if; -- Player 2 end if; else BlackJack <= (OTHERS => '0'); Win <= (OTHERS => '0'); Push <= (OTHERS => '0'); Lose <= (OTHERS => '0'); end if; end if; end process; --------------------------- -- Handling Total Scores -- --------------------------- process (Clk, Reset, SK_Game_Over, HP_Stop) begin if ((Reset = '1') OR (SK_Game_Over = '1')) then G <= '0'; elsif (Clk'EVENT and Clk = '1') then case HP_Stop is when '1' => G <= '1'; when others => NULL; end case; end if; end process; process(HP_Stop, G) begin if (HP_Stop = '1') then Score <= '1'; else Score <= '0'; end if; if (G = '1') then Score <= '0'; end if; end process; -- Player 1 process (Clk, Reset, Bet1, Score) begin if (Reset = '1') then Total1 <= "0000110010"; Chips1 <= "0000000000"; Outa(0) <= '0'; elsif (Clk'EVENT and Clk = '1') then case Score is when '1' => -- Case when Player = BlackJack if (BlackJack(0) = '1') then Total1 <= ("10" * Bet1) + Total1; Chips1 <= "11" * Bet1; -- Case when Player = Win elsif (Win(0) = '1') then Total1 <= Bet1 + Total1; Chips1 <= "10" * Bet1; -- Case when Player = Push elsif (Push(0) = '1') then Total1 <= Total1; Chips1 <= "01" * Bet1; -- Case when Player = Lose elsif (Lose(0) = '1') then if (Total1 >= Bet1) then Total1 <= Total1 - Bet1; Chips1 <= "0000000000"; else Total1 <= "0000000000"; Outa(0) <= '1'; -- N depend end if; end if; when others => NULL; end case; end if; end process; -- Player 2 process (Clk, Reset, Bet2, Score)--, Chips1, Total1) begin if (Reset = '1') then Total2 <= "0000110010"; Chips2 <= "0000000000"; Outa(1) <= '0'; elsif (Clk'EVENT and Clk = '1') then case Score is when '1' => -- Case when Player = BlackJack if (BlackJack(1) = '1') then Total2 <= ("10" * Bet2) + Total2; Chips2 <= "11" * Bet2; -- Case when Player = Win elsif (Win(1) = '1') then Total2 <= Bet2 + Total2; Chips2 <= "10" * Bet2; -- Case when Player = Push elsif (Push(1) = '1') then Total2 <= Total2; Chips2 <= "01" * Bet2; -- Case when Player = Lose elsif (Lose(1) = '1') then if (Total2 >= Bet2) then Total2 <= Total2 - Bet2; Chips2 <= "0000000000"; else Total2 <= "0000000000"; Outa(1) <= '1'; end if; end if; when others => NULL; end case; end if; end process; process(Total1, Total2) begin -- Player 1 Finish the chips if (Total1 = "0000000000") then Outb(0) <= '1'; else Outb(0) <='0'; end if; -- Player 2 Finish the chips if (Total2 = "0000000000") then Outb(1) <= '1'; else Outb(1) <='0'; end if; end process; process(Outa, Outb) begin -- Player 1 Finish the chips if ((Outa(0) = '1') OR (Outb(0) = '1')) then PL_Out(0) <= '1'; else PL_Out(0) <= '0'; end if; -- Player 2 Finish the chips if ((Outa(1) = '1') OR (Outb(1) = '1')) then PL_Out(1) <= '1'; else PL_Out(1) <= '0'; end if; end process; ---------------------------------------------- -- Set End_Game to high after each end game -- ---------------------------------------------- process(Clk, Reset, Score) begin if (Reset = '1') then End_Game <= '0'; elsif (Clk'EVENT and Clk = '1') then if (Score = '1') then End_Game <= '1'; else End_Game <= '0'; end if; end if; end process; -- OUTPUT Game_Over for the Controller -- process(Clk, Reset, End_Game, End_BJ) begin if (Reset = '1') then SK_Game_Over <= '0'; elsif (Clk'EVENT and Clk = '1') then if ((End_Game = '1') OR (End_BJ = '1')) then SK_Game_Over <= '1'; else SK_Game_Over <= '0'; end if; end if; end process; ----------------------------------------------------------------- -- End after 100 Games or after all Players finish their Chips -- ----------------------------------------------------------------- process (Clk, Reset, End_Game) begin if (Reset = '1') then Count <= "0000000"; elsif (Clk'EVENT and Clk = '1') then if (End_Game = '1') then Count <= Count + '1'; else Count <= Count; end if; end if; end process; process (Clk, Reset, PL_Out, Count) begin if (Reset = '1') then End_BJ <= '0'; elsif (Clk'EVENT and Clk = '1') then if (Count = "1100100") OR (PL_Out = "11") then End_BJ <= '1'; else End_BJ <= '0'; end if; end if; end process; END behavior;