一个游戏程序.vhd
上传用户:easylife05
上传日期:2013-03-21
资源大小:42k
文件大小:19k
源码类别:

VHDL/FPGA/Verilog

开发平台:

C/C++

  1. -- 
  2. --   Copyright (c) 1993,1994 by Exemplar Logic, Inc.  All Rights Reserved.
  3. --
  4. -- This source file may be used and distributed without restriction    
  5. -- provided that this copyright statement is not removed from the file  
  6. -- and that any derivative work contains this copyright notice.         
  7. --
  8. -----------
  9. --
  10. --  This is a synthesizable description that implements an emulator 
  11. --  of the Mancala game (African beans game).
  12. --
  13. --  Description of the Hardware
  14. -------------------------------
  15. --
  16. --  The hardware for the game includes a number of displays, each with a button and
  17. --  a light, that each represent a 'bin' that can store marbles (beans). 
  18. --
  19. --  The display indicates the number of marbles in each bin at any given time. 
  20. --  The light indecates that the present bin is not empty and that pushing the 
  21. --  button is a valid move in the game.
  22. --
  23. --  The button for each display indicates that a player takes the marbles from 
  24. --  the selected bin, and takes them in his hand. The hand is represented by a 
  25. --  diplay itself (no button).
  26. --
  27. --  Each player has a home bin, located on opposite sides of the game. The home 
  28. --  bin is also represented by a display. There should not be a button on the 
  29. --  home bins, since the game does not allow the removal of marbles from the home
  30. --  bins.
  31. --
  32. --  Besides this, the game has a button to start the game, and a reset for power-up
  33. --  purposes.
  34. --
  35. --  Here is a picture that represents the hardware setup of the game :
  36. --
  37. --
  38. --  *  == Light for valid move or to indicate the player who is active
  39. --  O  == Button to make move
  40. --  _
  41. -- | | 
  42. --  -  == 7 - segment display
  43. -- |_|
  44. --
  45. --                           work bins
  46. --                  *   O     *   O     *   O     *   O
  47. --                  _   _     _   _     _   _     _   _
  48. --                 | | | |   | | | |   | | | |   | | | | 
  49. --                  -   -     -   -     -   -     -   -
  50. --       *         |_| |_|   |_| |_|   |_| |_|   |_| |_|         *
  51. --     _   _                                                   _   _
  52. --    | | | |                                                 | | | |
  53. --     -   -                                                   -   -
  54. --    |_| |_|                                                 |_| |_|
  55. --
  56. -- home bin LEFT                                           home bin right
  57. --                  *   O     *   O     *   O     *   O            
  58. --                  _   _     _   _     _   _     _   _
  59. --                 | | | |   | | | |   | | | |   | | | | 
  60. --                  -   -     -   -     -   -     -   -
  61. --                 |_| |_|   |_| |_|   |_| |_|   |_| |_|
  62. --
  63. --                            work bins
  64. --
  65. --     _   _
  66. --    | | | |
  67. --     -   -                                              O  Start Game
  68. --    |_| |_|
  69. --
  70. --    Hand bin
  71. --
  72. --
  73. -- The Rules of the game 
  74. ------------------------
  75. --
  76. --    At the start of the game, the left player is active and can make a move.
  77. --    The left player selects a bin (by pressing the corresponding button).
  78. --    The machine will move the marbles from the bin (display) to the hand (diplay)
  79. --    and drop one marble in each successive bin (clockwise) from the hand, 
  80. --    starting with the bin clock-wise adjecent to the selected bin.
  81. --    A marble is never dropped in a opponents home bin (will be skipped).
  82. --
  83. --    If the last marble from the hand is dropped in an empty bin, the players
  84. --    switch turns, and it is the other players turn to make a move.
  85. --
  86. --    If the last marble from the hand is dropped in the players home bin,
  87. --    the player can make another move.
  88. --
  89. --    If the last marble from the hand is dropped in a non-empty work bin,
  90. --    all the marbles from that bin will be moved back to the hand and the
  91.  --   game proceeds.
  92. --
  93. --    The game ends if there are no more marbles in any of the work bins.
  94. --
  95. --    The winner of the game is the player who has most marbles in his/her
  96. --    home bin at the end of the game.
  97. --
  98. --
  99. --
  100. --  About the design
  101. --------------------
  102. --
  103. --    The design contains a controller and a data path. The controller contains 
  104. --    a state machine that defines the overall state of the game (waiting for a
  105. --    move, end of the game, playing). 
  106. --    The controller also has a register that defines which bin is active at any
  107. --    point in time during active playing. 
  108. --
  109. --    The controller provides signals for the data path to decrement the hand 
  110. --    marble count, or load the hand with the selected work bin count, or indecate
  111. --    that the game is over and a winner should be defined etc.
  112. --
  113. --    The data path contains a register for each bin in the game. 
  114. --    The number of bins is easily programmable by setting a integer constant.
  115. --    The data path also contains counters to decrement the hand marble count
  116. --    or increment the bin marble counts.
  117. --
  118. --    The data path provides signals for the controller to indicate that the 
  119. --    hand bin is empty, or which of the work bins is empty.
  120. --   
  121. --    The work bin registers are loaded with a equal number of marbles at the start 
  122. --    of the game. The total number of marbles in the game is programmable by setting
  123. --    a generic in the top entity.
  124. --
  125. --    The data path also includes light drivers for the lights on each button that 
  126. --    indicate a valid move, and the lights that indicate which player is active.
  127. --    Two extra signals are generated by the data path that let the home bin 
  128. --    display of the winner of the game blink on and off (at the end of the game).
  129. --
  130. --    The design does not include a merry-go-round display driver. This is done
  131. --    outside this design, on the Aptix board. 
  132. --
  133. --    The design does also not include a 18 bit clock devider that provides a 
  134. --    vary slow ticking clock to let humans follow the moves of the machine 
  135. --    cycle by cycle.
  136. --
  137. --    
  138. library ieee ;
  139. use ieee.std_logic_1164.all ;
  140. package mancala_pack is
  141.    type boolean_array is array (natural range <>) of boolean ;
  142.    type player_t is (LEFT, RIGHT, BOTH, NEITHER) ;
  143.    -- Define the number of bins in the game here.
  144.    -- This include the two home bins
  145.    constant nr_of_bins : natural := 10 ; 
  146.    -- Define the indexes of the two home bins 
  147.    constant OUTER_LEFT : natural := 0 ;
  148.    constant OUTER_RIGHT : natural := nr_of_bins/2 ; 
  149.    -- Make a 'mask' constant that eliminates the home bins
  150.    constant not_home_bins : boolean_array (nr_of_bins-1 downto 0) := 
  151.        (OUTER_LEFT=>FALSE, OUTER_RIGHT=>FALSE, OTHERS=>TRUE) ;
  152.    -- Component Declaration of the controller of the game
  153.    component control 
  154.        generic (nr_of_bins : natural := 32) ;
  155.        port (start_game : in boolean ;
  156.            reset, clk : in std_logic ;
  157.            buttons : in boolean_array (nr_of_bins-1 downto 0) ;
  158.            empty_bins : in boolean_array (nr_of_bins-1 downto 0) ;
  159.            hand_is_empty : in boolean ; 
  160.          
  161.            active_bin : buffer boolean_array (nr_of_bins-1 downto 0) ;
  162.            decrement_hand : out boolean ;
  163.            load_hand_with_active_bin : out boolean ;
  164.      
  165.            the_player : out player_t ;
  166.            end_of_the_game : out boolean ;
  167.            waiting_for_move : out boolean
  168.        ) ;
  169.    end component ;
  170. end mancala_pack ;
  171. library ieee ;
  172. use ieee.std_logic_1164.all ;
  173. use work.mancala_pack.all ;
  174. entity control is
  175.    generic (nr_of_bins : natural := 10) ;
  176.    port (start_game : in boolean ;
  177.          reset, clk : in std_logic ;
  178.          buttons : in boolean_array (nr_of_bins-1 downto 0) ;
  179.          empty_bins : in boolean_array (nr_of_bins-1 downto 0) ;
  180.          hand_is_empty : in boolean ; 
  181.          
  182.          active_bin : buffer boolean_array (nr_of_bins-1 downto 0) ;
  183.          decrement_hand : out boolean ;
  184.          load_hand_with_active_bin : out boolean ;
  185.          the_player : out player_t ;
  186.          end_of_the_game : out boolean ;
  187.          waiting_for_move : out boolean 
  188.    ) ;
  189. end control ;
  190. architecture exemplar of control is 
  191.    type state_t is (PLAY, WAIT_FOR_MOVE, END_OF_GAME);
  192.    -- The state variables for the controller state machine
  193.    signal present_state, next_state : state_t ;
  194.    -- A separate register (one-hot) defines which bin is active
  195.    signal present_active_bin : boolean_array(nr_of_bins-1 downto 0) ;
  196.    signal player : player_t ;
  197.    signal switch_player : boolean ;
  198.    signal last_bin_was_empty, next_bin_is_empty : boolean ;
  199.    -- Shift routine to shift to the next bin.
  200.    function shift(sel : boolean_array) return boolean_array is
  201.    begin
  202.       -- shift this register to the right, roll over right bit to left
  203.       return sel(sel'right) & sel(sel'left downto sel'right+1); 
  204.    end ;
  205.    -- General routine to check if a boolean array contains all 'false' elements.
  206.    function is_empty (bins : boolean_array) return boolean is
  207.       constant empty : boolean_array (bins'range) := (others=>false) ;
  208.    begin 
  209.       return (bins = empty) ;
  210.    end ;
  211. begin
  212.    process (clk, reset)
  213.    begin
  214.        if (reset='1') then
  215.            present_state <= END_OF_GAME ;
  216.            last_bin_was_empty <= FALSE ;
  217.            present_active_bin <= (others=>false) ;
  218.        elsif (clk'event and clk='1') then
  219.            present_state <= next_state ;
  220.            last_bin_was_empty <= next_bin_is_empty ;
  221.            present_active_bin <= active_bin ;
  222.        end if ;
  223.    end process ;
  224.    process (start_game,present_state,hand_is_empty,empty_bins,buttons,
  225.             present_active_bin, last_bin_was_empty, player)
  226.        variable next_active_bin : boolean_array (present_active_bin'range) ;
  227.    begin
  228.        load_hand_with_active_bin <= FALSE ;
  229.        decrement_hand <= FALSE ;
  230.        switch_player <= FALSE ;
  231.        waiting_for_move <= FALSE ;
  232.        next_bin_is_empty <= FALSE ;
  233.        end_of_the_game <= FALSE ;
  234.        case present_state is
  235.          when PLAY =>
  236.            if (hand_is_empty) then
  237.                -- No more marbles in the hand.
  238.                if (is_empty (present_active_bin AND not_home_bins)) then
  239.                   -- Stop if we drop the last marble in our own bin
  240.                    next_state <= WAIT_FOR_MOVE ;
  241.                    active_bin <= (others=>false) ;
  242.                elsif (last_bin_was_empty) then
  243.                   -- Stop and switch players if we drop the last marble
  244.                   -- in an empty bin
  245.                    switch_player <= TRUE ;
  246.                    next_state <= WAIT_FOR_MOVE ;
  247.                    active_bin <= (others=>false) ;
  248.                else 
  249.                   -- Continue if last marble dropped in a non-empty bin.
  250.                   -- Re-load hand with the full bin contents.
  251.                    next_state <= PLAY ;
  252.                    active_bin <= present_active_bin ;
  253.                    load_hand_with_active_bin <= TRUE ;
  254.                end if ;
  255.            else 
  256.                -- Regular state to go to next bin during play
  257.                next_state <= PLAY ;
  258.                decrement_hand <= TRUE ;
  259.                -- go to the next bin
  260.                next_active_bin := shift(present_active_bin) ;
  261.                -- We dont have to drop a marble in the opponents bin :
  262.                -- shift one bin further if this is about to happen
  263.                if ((player=LEFT and next_active_bin(OUTER_RIGHT)) OR
  264.                    (player=RIGHT and next_active_bin(OUTER_LEFT))) then
  265.                    next_active_bin := shift (next_active_bin) ; 
  266.                end if ;
  267.                   
  268.                -- If the bin we go to is empty, flag that now, since
  269.                -- we need to do something different in the next cycle.
  270.                if (NOT is_empty (next_active_bin AND empty_bins)) then
  271.                    next_bin_is_empty <= TRUE ;
  272.                end if ;
  273.                active_bin <= next_active_bin ;
  274.            end if ;
  275.          when WAIT_FOR_MOVE =>
  276.            waiting_for_move <= TRUE ;
  277.            if (is_empty((NOT empty_bins) AND not_home_bins)) then 
  278.                -- Here, there are no more marbles in any of the 
  279.                -- play bins. This is the end of the game. 
  280.                next_state <= END_OF_GAME ;
  281.                active_bin <= (others=>FALSE) ;
  282.            elsif (is_empty(buttons AND (NOT empty_bins) AND not_home_bins)) then 
  283.                -- Here, No button was pushed that is valid (not 
  284.                -- selecting a empty bin and not selecting a home bin. 
  285.                next_state <= WAIT_FOR_MOVE ;
  286.                active_bin <= (others=>FALSE) ;
  287.            else 
  288.               -- Somebody pushed a button. Load the hand with selected 
  289.               -- bin and restart the play
  290.                next_state <= PLAY ;
  291.                load_hand_with_active_bin <= TRUE ;
  292.                active_bin <= buttons ; -- Should have only ONE bit set
  293.            end if ;
  294.          when END_OF_GAME =>
  295.            -- Let the datapath calculate who the winner is
  296.            end_of_the_game <= TRUE ;
  297.            active_bin <= (others=>false) ;
  298.            if (start_game) then
  299.                next_state <= WAIT_FOR_MOVE ;
  300.            else 
  301.                next_state <= END_OF_GAME ;
  302.            end if ;
  303.        end case ;
  304.    end process ;
  305.  -- 
  306.  -- Process that controls which player is on.
  307.  -- The state machine defines when players have to be switched
  308.  --
  309.    process (clk, reset)
  310.        procedure switch_players (signal pl : inout player_t) is
  311.        begin 
  312.            if (pl=LEFT) then
  313.                pl <= RIGHT ;
  314.            elsif (pl=RIGHT) then
  315.                pl <= LEFT ;
  316.            end if ;
  317.        end ;
  318.    begin
  319.        if (reset='1') then
  320.            player <= NEITHER ;
  321.        elsif (clk'event and clk='1') then
  322.            if (start_game) then
  323.                player <= LEFT ;
  324.            else
  325.                if (switch_player) then 
  326.                    switch_players (player) ;
  327.                end if ;
  328.            end if ;
  329.        end if ;
  330.    end process ;
  331.    the_player <= player ;
  332. end exemplar ;
  333. library ieee ;
  334. use ieee.std_logic_1164.all ;
  335. use work.mancala_pack.all ;
  336. entity mancala is
  337.    generic (max_marbles : natural := 32) ;
  338.    port (start_game              : boolean ;
  339.          active_bin_value        : buffer integer range 0 to max_marbles-1;
  340.          active_bin              : buffer  boolean_array(nr_of_bins-1 downto 0);
  341.          blink_right, blink_left : inout std_logic;
  342.          clk, reset              : in   std_logic;
  343.          buttons                 : in   boolean_array(nr_of_bins-1 downto 0);
  344.          button_lights           : out  boolean_array(nr_of_bins-1 downto 0);
  345.          l_player, r_player      : out  std_logic
  346.    ) ;
  347. end mancala ;
  348.   
  349. architecture exemplar of mancala is 
  350.    subtype bin_integer is integer range 0 to max_marbles-1 ; 
  351.    type bin_integer_array is array (nr_of_bins-1 downto 0) of bin_integer ;
  352.    -- The bins
  353.    signal bins : bin_integer_array ; 
  354.    signal incremented_bin_value : bin_integer ;
  355.    signal empty_bins : boolean_array (nr_of_bins-1 downto 0) ;
  356.   
  357.    -- The hand 
  358.    signal hand : bin_integer ;
  359.    signal load_hand_with_active_bin : boolean ; 
  360.    signal decrement_hand : boolean ;
  361.    signal hand_is_empty : boolean ;
  362.    -- Which player is playing / winning
  363.    signal player : player_t ;
  364.    signal winner : player_t ;   
  365.    signal waiting_for_move : boolean ;
  366.    signal end_of_the_game : boolean ;
  367. begin
  368.    c : control generic map ( nr_of_bins=>nr_of_bins) 
  369.                port map ( -- To controller :
  370.                           start_game=>start_game,
  371.                           clk=>clk, 
  372.                           reset=>reset,
  373.                           buttons=>buttons, 
  374.                           empty_bins=>empty_bins,
  375.                           hand_is_empty=>hand_is_empty,
  376.                           -- From controller :
  377.                           active_bin=>active_bin,
  378.                           decrement_hand=>decrement_hand,
  379.                           load_hand_with_active_bin=>load_hand_with_active_bin,
  380.                           the_player=>player,
  381.                           end_of_the_game=>end_of_the_game,
  382.                           waiting_for_move=>waiting_for_move
  383.                   ) ;
  384.  --
  385.  -- Process the amount of marbles in the hand
  386.  --
  387.    process (clk, reset) 
  388.    begin
  389.       if (reset='1') then 
  390.           hand <= 0 ;
  391.       elsif clk'event and clk='1' then
  392.           if (start_game) then
  393.               hand <= 0 ;
  394.           elsif (load_hand_with_active_bin) then
  395.               hand <= active_bin_value ;
  396.           elsif (decrement_hand and (not hand_is_empty)) then
  397.               hand <= hand - 1 ;
  398.           end if ;
  399.       end if ;
  400.    end process ; 
  401.    hand_is_empty <= (hand=0) ; 
  402.  --
  403.  -- Process the amount of marbles in each bin
  404.  --
  405.    bin_procs : for i in bins'range generate
  406.        process (reset, clk)
  407.        begin
  408.            if (reset='1') then
  409.                bins(i) <= 0 ;
  410.            elsif clk'event and clk='1' then
  411.                if (start_game) then
  412.                    -- Initialize the home bins to zero and the
  413.                    -- work bins to a number that guarantees that there
  414.                    -- will be max_marbles in the game. 
  415.                    if (i=OUTER_LEFT or i=OUTER_RIGHT) then
  416.                        bins(i) <= 0 ;
  417.                    else 
  418.                        bins(i) <= max_marbles/(nr_of_bins-2) ;
  419.                    end if ;
  420.                elsif (active_bin(i)) then
  421.                    if (load_hand_with_active_bin) then
  422.                        bins(i) <= 0 ;
  423.                    elsif (decrement_hand and (not hand_is_empty)) then
  424.                        bins(i) <= incremented_bin_value ; 
  425.                    end if ;
  426.                end if ;
  427.            end if ;
  428.        end process ;
  429.        empty_bins(i) <= bins(i) = 0 ;
  430.    end generate ; 
  431.  
  432.  -- 
  433.  -- Select the bin (from the bins register) that is presently active 
  434.  -- 
  435.    process (active_bin, bins) 
  436.    begin
  437.       active_bin_value <= 0 ;
  438.       for i in bins'range loop
  439.           if (active_bin(i)) then
  440.               active_bin_value <= bins(i) ;
  441.           end if ;
  442.       end loop ;
  443.    end process ;
  444.  --
  445.  -- Calculate the incremented value of the presently selected bin
  446.  --
  447.    incremented_bin_value <= active_bin_value + 1 ;
  448.  -- Generate the light signals for the player that is active
  449.    l_player <= '1' when player=LEFT else '0' ;
  450.    r_player <= '1' when player=RIGHT else '0' ;
  451.  --
  452.  -- Define the winner 
  453.  --
  454.    winner <= NEITHER when NOT end_of_the_game ELSE
  455.              BOTH when bins(OUTER_LEFT)=bins(OUTER_RIGHT) ELSE
  456.              LEFT when bins(OUTER_LEFT)>bins(OUTER_RIGHT) ELSE
  457.              RIGHT ;
  458.  -- 
  459.  -- Blink the display of the winner (on/off)
  460.  -- 
  461.    process (clk, reset)
  462.    begin
  463.       if (reset='1') then
  464.           -- Displays ON
  465.           blink_left <= '1' ;
  466.           blink_right <= '1' ;
  467.       elsif clk'event and clk='1' then
  468.           case winner is
  469.              when LEFT =>
  470.                 blink_left <= NOT blink_left ;
  471.                 blink_right <= '1' ;
  472.              when RIGHT =>
  473.                 blink_left <= '1' ;
  474.                 blink_right <= NOT blink_right ;
  475.              when BOTH => 
  476.                 blink_left <= NOT blink_left ;
  477.                 blink_right <= NOT blink_right ;
  478.              when OTHERS =>
  479.                 blink_left <= '1' ;
  480.                 blink_right <= '1' ;
  481.           end case ;
  482.       end if ;
  483.    end process ;
  484.    
  485.  --
  486.  -- Button lights 
  487.  -- Light on each button for possible move
  488.  --
  489.    lights : for i in button_lights'range generate
  490.        button_lights(i) <= TRUE when (waiting_for_move AND NOT empty_bins(i)) 
  491.                            else FALSE ;
  492.    end generate ; 
  493. end exemplar ;
  494.