------------------------------------------------------------------ -- Controller_SM -- -- File Name: Controller_SM.Vhd -- -- Author: Kamesh Ramani. -- -- Function : This is the state machine part of the controller -- -- (The features are subject to change as the system evolves) -- -- Created: -- -- Last Updated on: 2/11/03 -- ------------------------------------------------------------------ -- IEEE Library LIBRARY ieee; USE ieee.std_logic_1164.all; use IEEE.std_logic_unsigned.all; ENTITY Controller_SM IS --Generic parameters generic (n: integer := 6); -- Number of players PORT( -- Global System Inputs Clk: IN STD_LOGIC; -- Global Clk Reset: IN STD_LOGIC; -- Global Reset -- Inputs from Control_SK module SK_PL: IN STD_LOGIC_VECTOR (n-1 downto 0);-- Bust for Players SK_Status: IN STD_LOGIC; -- Status is ready SK_Game_Over: IN STD_LOGIC; -- Current game over SK_Done: IN STD_LOGIC; -- End of 100 games/player's chip gets over -- Outputs to the Card_Gen module CG_Start: OUT STD_LOGIC; -- Start Generating Cards in -- Fixed sequence if 0 -- Random Sequence if 1 --Outputs to the House_Player module HP_Accept: out STD_LOGIC; -- House Player Start -- Inputs from House_Player module HP_Hit: IN STD_LOGIC; -- House Player Hit HP_Stand: IN STD_LOGIC; -- House Player Stand --Outputs to the Player module PL_Accept: OUT STD_LOGIC_VECTOR (n-1 downto 0); -- Start signals for n players -- Inputs from the Player modules PL_Hit: IN STD_LOGIC_VECTOR (n-1 downto 0); -- Player Hit Singals for n players PL_Stand: IN STD_LOGIC_VECTOR (n-1 downto 0); -- Player Stand signals for n players PL_Status: IN STD_LOGIC_VECTOR (n-1 downto 0) -- Player status - either in or out --Debug ); END Controller_SM; architecture Control1er_SM_arch of Controller_SM is signal Sequence:STD_LOGIC;-- Random or fixed sequence --Signals related to Status_Mux signal PL_Status_Mux: STD_LOGIC_VECTOR (n-1 downto 0); signal Status_Select: STD_LOGIC; --Signals related to Status_Reg signal PL_Status_Reg: STD_LOGIC_VECTOR (n-1 downto 0); signal Status_En: STD_LOGIC; --Signals related to PL_Status_Mux signal PL_Status_Sig : STD_LOGIC; --Signals related to PL_Hit_Mux signal PL_Hit_Sig : STD_LOGIC; --Signals related to PL_Stand_Mux signal PL_Stand_Sig : STD_LOGIC; --Signals related to Counter Hands -- Seven bits long since 100 in decimal needs 7 bits in Bin signal Hands, Hands_Sig: STD_LOGIC_VECTOR(6 downto 0); signal Hands_Inc, Hands_Clr: STD_LOGIC; --Signals related to Counter_Cnt -- Three bits long since n here is assumed 6 --n Dep signal Cnt, Count: STD_LOGIC_VECTOR (3 downto 0); signal Cnt_Inc, Cnt_Clr: STD_LOGIC; --Signals related to Counter_Two signal Two, Two_Cnt: STD_LOGIC_VECTOR(1 downto 0); signal Two_Inc, Two_Clr: STD_LOGIC; --Signals related to PL_Accept_Mux -- Three bits long since n here is assumed 6 --n Dep signal PL_Accept_Select: STD_LOGIC_VECTOR (3 downto 0); -- Controller FSM states type STATE_TYPE is (Idle, PL_card_init, HP_Card_Init, Black_Jack, PL_Play, HP_Play, Game_Over); signal CurrentState, NextState: STATE_TYPE; --Component declaration of Player_Mux --n Dep COMPONENT Player_Mux PORT( PL_Value : OUT STD_LOGIC; PL_Vector: IN STD_LOGIC_VECTOR (5 downto 0); PL_Select: IN STD_LOGIC_VECTOR (3 downto 0) ); END COMPONENT; begin --Player_Mux chooses the Status of the current player --Component instantiation of Player_Mux PL_Stat_Mux: Player_Mux PORT MAP ( PL_Value => PL_Status_Sig, PL_Vector => PL_Status_Reg, PL_Select => Cnt ); --PL_Hit_Mux chooses the Hit signal of the current player --Component instantiation of Player_Mux PL_Hit_Mux: Player_Mux PORT MAP ( PL_Value => PL_Hit_Sig, PL_Vector => PL_Hit, PL_Select => Cnt ); --PL_Hit_Mux chooses the Stand signal of the current player --Component instantiation of Player_Mux PL_Stand_Mux: Player_Mux PORT MAP ( PL_Value => PL_Stand_Sig, PL_Vector => PL_Stand, PL_Select => Cnt ); -- Debug -- Controller FSM State_machine: process(CurrentState, Hands, SK_Done, Cnt, PL_Status_Sig, Two_Cnt, SK_Status, Sequence, PL_Status_Sig, PL_Stand_Sig, PL_Hit_Sig) begin -- Default all outputs to FALSE CG_Start <= '0';Status_EN <= '0'; Cnt_Inc <= '0'; Cnt_Clr <= '0'; Two_Inc <= '0'; Two_Clr <= '0'; Hands_Inc <= '0'; Hands_Clr <= '0'; HP_Accept <= '0'; Status_Select <= '0'; case CurrentState is when Idle => -- End of game if either 100 hands played or chips get over if (Hands > X"64") then NextState <= Idle; elsif (Hands <= X"64") then if (SK_Done = '1')then Hands_Clr <= '1'; NextState <= Idle; elsif (SK_Done = '0')then Status_Select <= '0'; Status_En <= '1'; Hands_Inc <= '1'; NextState <= PL_Card_Init; -- Decide of what sequence to start if (Sequence = '0') then CG_Start <= '0'; else CG_Start <= '1'; end if; end if; end if; when PL_Card_Init => if (Cnt <= X"6") then --n Dep -- if player is in if (PL_Status_Sig = '0') then PL_Accept_Select <= X"7"; elsif (PL_Status_Sig = '1') then -- Give card to player PL_Accept_Select <= Cnt; end if; if (Cnt = X"6") then --n Dep Cnt_Clr <= '1'; NextState <= HP_Card_Init; else Cnt_Inc <= '1'; NextState <= PL_Card_Init; end if; elsif (Cnt > X"6") then --n Dep Cnt_Clr <= '1'; end if; when HP_Card_Init => PL_Accept_Select <= X"7"; -- give cards to house HP_Accept <= '1'; -- give two cards initially to both house and players if (Two_Cnt >= "01") then Two_clr <= '1'; NextState <= Black_Jack; elsif (Two_Cnt < "01") then Two_Inc <= '1'; NextState <= PL_Card_Init; end if; -- when black jack dont give cards to that player anymore when Black_Jack => case (SK_Status) is when '1' => Status_Select <= '1'; Status_En <= '1'; NextState <= PL_Play; when '0'=> NextState <= Black_Jack; when others => NextState <= Idle; end case; when PL_Play => if (Cnt <= X"6") then --n Dep -- if SK is not done with calculating status keep checking if (SK_Status = '0') then NextState <= PL_Play; --if the current player is out elsif (PL_Status_Sig = '0') then PL_Accept_Select <= X"7"; if (Cnt = X"6") then --n Dep Cnt_Clr <= '1'; NextState <= HP_Play; else Cnt_Inc <= '1'; NextState <= PL_Play; end if; elsif (PL_Status_Sig = '1') then -- if the player is not ready keep checking if ((PL_Hit_Sig = '0') AND (PL_Stand_Sig = '0')) then NextState <= PL_Play; -- if the player hits then send him a card elsif (PL_Hit_Sig = '1') then PL_Accept_Select <= Cnt; NextState <= PL_Play; -- if the player stands, move on to the next player elsif (PL_Stand_Sig = '1') then PL_Accept_Select <= X"7"; if (Cnt = X"6") then --n Dep Cnt_Clr <= '1'; NextState <= HP_Play; else Cnt_Inc <= '1'; NextState <= PL_Play; end if; end if; end if; elsif (Cnt > X"6") then --n Dep Cnt_Clr <= '1'; NextState <= Idle; end if; when HP_Play => -- if the HP is not ready keep checking if ((HP_Hit = '0') AND (HP_Stand = '0')) then NextState <= HP_Play; -- if he hits give him another card elsif (HP_Hit = '1') then HP_Accept <= '1'; NextState <= HP_Play; elsif (HP_Stand = '1') then HP_Accept <= '0'; NextState <= Game_Over; end if; when Game_Over => -- if the SK says game over go to the next game if (SK_Game_Over = '1') then Sequence <= '1'; NextState <= Idle; elsif (SK_Game_Over = '0') then NextState <= Game_Over; end if; when others => NextState <= Idle; end case; end process; -- To synchorinize the statemachine with Global Clk State_Sync:process (Clk, Reset) begin if (Reset='1') then CurrentState <= Idle; elsif (Clk'event and Clk = '1') then CurrentState <= NextState; end if; end process; -- Counter for Hands Counter_Hands:process (Clk, Reset) begin if (Reset='1') then Hands_Sig <= "0000000"; elsif (Clk'event and Clk = '1') then if (Hands_Clr = '1') then Hands_Sig <= "0000000"; elsif (Hands_Inc = '1') then Hands_Sig <= Hands_Sig + "0000001"; end if; end if; end process; Hands <= Hands_Sig; -- Counter for player's turn Counter_Cnt:process (Clk, Reset) begin if (Reset='1') then Count <= X"0"; elsif (Clk'event and Clk = '1') then if (Cnt_Clr = '1') then Count <= X"0"; elsif (Cnt_Inc = '1') then Count <= Count + X"1"; end if; end if; end process; Cnt <= Count; --Counter for giving cards twice initially Counter_Two:process (Clk, Reset) begin if (Reset='1') then Two <= "00"; elsif (Clk'event and Clk = '1') then if (Two_Clr = '1') then Two <= "00"; elsif (Two_Inc = '1') then Two <= Two + "01"; end if; end if; end process; Two_Cnt <= Two; -- Status Register -- This register stores the status of the players -- Initially the status is loaded when the palyers -- say they are in or out -- The status is changed again when the skore keeper -- says they are bust or black jack. Status_Reg: process (Clk, Reset, Status_En, PL_Status_Mux) begin if (Reset='1') then PL_Status_Reg <= (others => '0'); elsif (CLK'event and CLK='1') then if (Status_En = '1') then PL_Status_Reg <= PL_Status_Mux; elsif (Status_En = '0') then NULL; end if; end if; end process; --Status_Mux --This mux selects between the status signals from -- either the Player or the Score_Keeper. Status_Mux: process (Status_Select, PL_Status, SK_PL) begin case Status_Select is when '0' => PL_Status_Mux <= PL_Status; --Select status from player when '1' => PL_Status_Mux <= SK_PL; --Select status from SK when others => PL_Status_Mux <= (others => '0'); -- Default value end case; end process; --PL_Accept_Mux --This mux selects the given player's Accept signal PL_Accept_Mux: process (PL_Accept_Select) begin --n Dep case PL_Accept_Select is when X"1" => PL_Accept <= "000001"; when X"2" => PL_Accept <= "000010"; when X"3" => PL_Accept <= "000100"; when X"4" => PL_Accept <= "001000"; when X"5" => PL_Accept <= "010000"; when X"6" => PL_Accept <= "100000"; when others => PL_Accept <= (others => '0'); -- Default value end case; end process; end Control1er_SM_arch;