--Hi,
-- Please look at the controller entity. It has the signals that are required for
--communication between the controller and the respective modules. The state
--machine part of the controller is attached with this mail and is called
--Controller_SM.Vhd.
--
-- Kamesh Ramani
-- - Controller group
------------------------------------------------------------------
-- 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) --
------------------------------------------------------------------
-- 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_HP: IN STD_LOGIC; -- Bust for House
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 6 players
-- Inputs from the Player modules
PL_Hit: IN STD_LOGIC_VECTOR (n-1 downto 0); -- Player Hit Singals for 6 players
PL_Stand: IN STD_LOGIC_VECTOR (n-1 downto 0); -- Player Stand signals for 6 players
PL_Status: IN STD_LOGIC_VECTOR (n-1 downto 0) -- Player status - either in or out
);
END Controller_SM;
architecture Control1er_SM_arch of Controller_SM is
--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_Sig: STD_LOGIC_VECTOR (n-1 downto 0);
signal Status_En: STD_LOGIC;
-- 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;
begin
-- Continous assignments
-- Controller FSM
State_machine: process(CurrentState, Clk)
variable Cnt: integer range -1 to n-1; -- Total number of players including idle players - a temp var
variable Two: integer range 0 to 2; -- Counter for first two card iteration
variable Sequence: integer range 0 to 1;-- Random or fixed sequence
variable Hands : integer range -1 to 100; -- Calcualte the total number of hands played
begin
-- Default all outputs to FALSE
Status_En <= '0'; Status_Select <= '0'; CG_Start <= '0';
CG_Start <= '0'; HP_Accept <= '0'; PL_Accept <= (others => '0');
case CurrentState is
when Idle =>
-- End of game if either 100 hands played or chips get over
if ((SK_Done = '1') OR (Hands = 100))then
NextState <= Idle;
else
Hands := Hands + 1;
Status_Select <= '0';
Status_En <= '1';
-- Decide of what sequence to start
if (Sequence = 0) then
CG_Start <= '0';
Sequence := 1;
NextState <= PL_Card_Init;
elsif (Sequence = 1) then
CG_Start <= '1';
NextState <= PL_Card_Init;
end if;
end if;
when PL_Card_Init =>
-- if all players have been given cards give to house player
if (Cnt < 0) then
Cnt := n-1;
NextState <= HP_Card_Init;
elsif (Cnt < n) then
-- if player is in
if (PL_Status_Sig(Cnt) = '0') then
PL_Accept(Cnt) <= '0';
NextState <= PL_Card_Init;
elsif (PL_Status_Sig(Cnt) = '1') then
PL_Accept(Cnt) <= '1';
Cnt := Cnt - 1;
NextState <= PL_Card_Init;
end if;
end if;
when HP_Card_Init =>
-- give cards to house
HP_Accept <= '1';
-- give two cards initially to both house and players
if (Two = 0) then
NextState <= Black_Jack;
else
Two := Two -1;
NextState <= PL_Card_Init;
end if;
-- when black jack dont give cards to him anymore
when Black_Jack =>
if (SK_Status = '1') then
Status_Select <= '1';
Status_En <= '1';
NextState <= PL_Play;
elsif (SK_Status = '0') then
NextState <= Black_Jack;
end if;
when PL_Play =>
-- if all players are done playing(Stand/Bust) then let HP play
if (Cnt < 0) then
Cnt := n-1;
NextState <= HP_Play;
elsif (Cnt < n) then
-- 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(Cnt) = '0') then
PL_Accept(Cnt) <= '0';
Cnt := Cnt - 1;
NextState <= PL_Play;
elsif (PL_Status_Sig(Cnt) = '1') then
-- if the player is not ready keep checking
if (PL_Hit(Cnt) = '0') then
NextState <= PL_Play;
-- if the player hits then send him a card
elsif (PL_Hit(Cnt) = '1') then
PL_Accept(Cnt) <= '1';
NextState <= PL_Play;
end if;
-- if the player is not yet decided then keep checking
if (PL_Stand(Cnt) = '0') then
NextState <= PL_Play;
-- if the player stands move on to the next player
elsif (PL_Stand(Cnt) = '1') then
PL_Accept(Cnt) <= '0';
Cnt := Cnt - 1;
NextState <= PL_Play;
end if;
end if;
end if;
when HP_Play =>
-- if the HP is not ready keep checking
if (HP_Hit = '0') then
NextState <= HP_Play;
-- if he hits give him another card
elsif (HP_Hit = '1') then
HP_Accept <= '1';
NextState <= HP_Play;
end if;
-- if the HP stands the game is over
if (HP_Stand = '0') then
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
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;
-- 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)
begin
if (Reset='1') then
PL_Status_Sig <= (others => '0');
elsif (CLK'event and CLK='1') then
if (Status_En = '1') then
PL_Status_Sig <= 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;
end Control1er_SM_arch;