-- CardGenerator -- -- Description: Generates cards from four simulated decks. -- Reshuffles at the beginning of each hand. -- -- comments: -- lfsb info: http://homepage.mac.com/afj/taplist.html -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity card_generator is port( in_clock : in std_logic; in_reset : in std_logic; -- reset to new game in_issue : in std_logic; -- request a new card in_bist : in std_logic; -- test mode (standard cards) main_reset : in std_logic; -- New signals to be implemented------------- cgIssue : IN STD_LOGIC; cgNewHand : IN STD_LOGIC; cgBist : IN STD_LOGIC; cgIssueHP : IN STD_LOGIC; issued : OUT STD_LOGIC; issuedHP : OUT STD_LOGIC; --------------------------------------------- shuffle : in std_logic; dealttotal_out : in std_logic_vector(7 downto 0); in_num_twos : in std_logic_vector(4 downto 0); in_num_threes : in std_logic_vector(4 downto 0); in_num_fours : in std_logic_vector(4 downto 0); in_num_fives : in std_logic_vector(4 downto 0); in_num_sixes : in std_logic_vector(4 downto 0); in_num_sevens : in std_logic_vector(4 downto 0); in_num_eights : in std_logic_vector(4 downto 0); in_num_nines : in std_logic_vector(4 downto 0); in_num_tens : in std_logic_vector(4 downto 0); in_num_jacks : in std_logic_vector(4 downto 0); in_num_kings : in std_logic_vector(4 downto 0); in_num_queens : in std_logic_vector(4 downto 0); in_num_aces : in std_logic_vector(4 downto 0); out_card : out std_logic_vector(3 downto 0); -- card output on issue out_house : out std_logic_vector(3 downto 0); -- dealer card on reset out_issued : out std_logic; -- signals out_card is ready (pulse high) over_reset : out std_logic; ccard:out std_logic_vector(3 downto 0); house_card_dealt : out std_logic ); end card_generator; architecture card_generator_arch of card_generator is signal tmp_card_check : std_logic_vector(3 downto 0) ; begin process(in_clock, in_issue, in_reset) variable startup_flag : std_logic ; -- flag for startup variable dealt_house_flag : std_logic ; -- flag for having dealt house card variable random_seed : std_logic_vector(15 downto 0); -- seed for lfsb variable intern :std_logic_vector(15 downto 0); variable lfsr : std_logic_vector(15 downto 0) ; -- linear feedback shift register variable lfsr_next_bit : std_logic ; -- linear feedback shift register next bit variable card : std_logic_vector(3 downto 0) ; -- card bits that are verified and output variable tmp_card : std_logic_vector(3 downto 0) ; variable sequence : natural range 0 to 10; -- cyclic sequence used for correcting bad cards variable sum_of_played : std_logic_vector(4 downto 0) ; -- sum of played cards (from stats) -- memory for output variable var_out_card : std_logic_vector(3 downto 0) ; variable var_out_house : std_logic_vector(3 downto 0) ; variable var_out_issued : std_logic ; variable over_reset_in : std_logic ; variable house_card_dealt_in : std_logic; variable startup_bist :std_logic ; begin --begin clocked statement for free-running clock and reset if ( main_reset ='1') then startup_flag := '0'; dealt_house_flag := '0'; random_seed :="0001110100000000"; intern :="0001110100000000"; lfsr := (others=>'0'); lfsr_next_bit := '0'; card := (others=>'0'); tmp_card := (others=>'0'); sum_of_played := (others=>'0'); var_out_card := (others=>'0'); var_out_house := (others=>'0'); var_out_issued := '0'; over_reset_in := '0'; house_card_dealt_in :='0'; startup_bist :='0'; issuedHP <= '0'; else if(in_clock'event and in_clock = '1') then -- random_seed generated by counter. random reset captures a counter state random_seed := random_seed + 1; end if; house_card_dealt_in :='0'; over_reset_in :='0'; house_card_dealt <= house_card_dealt_in; if ( in_reset'event and in_reset = '0') then --reset signal starts new shuffle --get random seed at boot-up or at end of bist if( in_bist = '0' AND startup_flag = '0' ) then --make sure lfsr doesn't get stuck w/ all 0's if( random_seed = "0000000000000000" ) then lfsr := (others=>'1'); else lfsr := random_seed; end if; startup_flag := '1'; elsif( in_bist = '1' AND startup_bist ='0') then -- in bist, use non-random lfsb state sequence := 1; startup_flag := '0'; if (startup_bist ='0') then lfsr := "1110010100011100"; intern :=lfsr; end if; startup_bist := '1'; end if; -- if neither boot nor bist, let lfsr do its thing dealt_house_flag := '0'; end if; -- card generation is clocked on the in_issue signal if( (in_issue'event and in_issue = '1') OR dealt_house_flag = '0')then over_reset_in :='0'; -- update cyclic sequence if( sequence = 10 ) then sequence := 1; else sequence := sequence + 1; end if; -- build potential card value from lfsr (0 to 12 range) for i in 1 to 4 loop card(i-1) := lfsr(15); lfsr_next_bit := lfsr(15) XOR lfsr(14) XOR lfsr(12) XOR lfsr(3); lfsr(15 downto 1) := lfsr(14 downto 0); lfsr(0) := lfsr_next_bit; if( in_bist = '0' ) then if (lfsr ="0000000000000000") then if( random_seed = "0000000000000000" ) then lfsr := (others=>'1'); else lfsr := random_seed; end if; end if; elsif( in_bist = '1' ) then if (lfsr ="0000000000000000") then if( intern = "0000000000000000" ) then lfsr :=(others=>'1'); intern := intern+7561; else lfsr:=intern; intern := intern+7561; end if; end if; end if; end loop; -- check for non-card values and generate a card from the non-card (0 to 12 range) if( card > 12 ) then card := (14 - card) + sequence; -- (14-card) = [0,2] and sequence=[0,10] end if; -- adjust to (1 to 13) scale card := card + 1; -- check for validity of card (i.e. decks haven't been exhausted) and correct -- loop through stats until finding a legal card (does nothing if already legal) -- this is unnecessary for the house card since it is the first card if( dealt_house_flag = '0' ) then var_out_house := card; --deal house card dealt_house_flag := '1'; var_out_issued := '0'; house_card_dealt_in :='1'; else tmp_card := card; for i in 1 to 13 loop case tmp_card is when "0001" => sum_of_played := in_num_aces; when "0010" => sum_of_played := in_num_twos; when "0011" => sum_of_played := in_num_threes; when "0100" => sum_of_played := in_num_fours; when "0101" => sum_of_played := in_num_fives; when "0110" => sum_of_played := in_num_sixes; when "0111" => sum_of_played := in_num_sevens; when "1000" => sum_of_played := in_num_eights; when "1001" => sum_of_played := in_num_nines; when "1010" => sum_of_played := in_num_tens; when "1011" => sum_of_played := in_num_jacks; when "1100" => sum_of_played := in_num_queens; when "1101" => sum_of_played := in_num_kings; when others => sum_of_played := in_num_fives; end case; if( sum_of_played >= "10000" ) then tmp_card_check <=tmp_card; if( tmp_card = "1101" ) then tmp_card :="0001"; else tmp_card := tmp_card+'1'; end if; if (dealttotal_out ="11010000") then over_reset_in :='1'; end if; tmp_card_check <=tmp_card; else card := tmp_card; end if; end loop; -- we issue a 'issuedHP' to inform the controller that the currntly issued card is Hidden card for the house player -- in response to the controller signal cgissueHP if (cgIssueHP = '1' ) then issuedHP <='1'; else issuedHP <='0'; end if; var_out_card := card; -- deal player card var_out_issued := '1'; end if; end if; -- end in_issue clock if (house_card_dealt_in ='1' ) then ccard <= var_out_house; end if; if ( in_issue ='1' )then ccard <= var_out_card; end if; -- out_issued should go low after in_issue goes low if( in_issue'event and in_issue = '0' ) then var_out_issued := '0'; end if; --assign all outputs every cycle out_card <= var_out_card; out_house <= var_out_house; out_issued <= var_out_issued; over_reset <= ( over_reset_in or shuffle ); house_card_dealt <= house_card_dealt_in; end if; end process; end card_generator_arch;