📄 һ
字号:
next_state <= PLAY ; active_bin <= present_active_bin ; load_hand_with_active_bin <= TRUE ; end if ; else -- Regular state to go to next bin during play next_state <= PLAY ; decrement_hand <= TRUE ; -- go to the next bin next_active_bin := shift(present_active_bin) ; -- We dont have to drop a marble in the opponents bin : -- shift one bin further if this is about to happen if ((player=LEFT and next_active_bin(OUTER_RIGHT)) OR (player=RIGHT and next_active_bin(OUTER_LEFT))) then next_active_bin := shift (next_active_bin) ; end if ; -- If the bin we go to is empty, flag that now, since -- we need to do something different in the next cycle. if (NOT is_empty (next_active_bin AND empty_bins)) then next_bin_is_empty <= TRUE ; end if ; active_bin <= next_active_bin ; end if ; when WAIT_FOR_MOVE => waiting_for_move <= TRUE ; if (is_empty((NOT empty_bins) AND not_home_bins)) then -- Here, there are no more marbles in any of the -- play bins. This is the end of the game. next_state <= END_OF_GAME ; active_bin <= (others=>FALSE) ; elsif (is_empty(buttons AND (NOT empty_bins) AND not_home_bins)) then -- Here, No button was pushed that is valid (not -- selecting a empty bin and not selecting a home bin. next_state <= WAIT_FOR_MOVE ; active_bin <= (others=>FALSE) ; else -- Somebody pushed a button. Load the hand with selected -- bin and restart the play next_state <= PLAY ; load_hand_with_active_bin <= TRUE ; active_bin <= buttons ; -- Should have only ONE bit set end if ; when END_OF_GAME => -- Let the datapath calculate who the winner is end_of_the_game <= TRUE ; active_bin <= (others=>false) ; if (start_game) then next_state <= WAIT_FOR_MOVE ; else next_state <= END_OF_GAME ; end if ; end case ; end process ; -- -- Process that controls which player is on. -- The state machine defines when players have to be switched -- process (clk, reset) procedure switch_players (signal pl : inout player_t) is begin if (pl=LEFT) then pl <= RIGHT ; elsif (pl=RIGHT) then pl <= LEFT ; end if ; end ; begin if (reset='1') then player <= NEITHER ; elsif (clk'event and clk='1') then if (start_game) then player <= LEFT ; else if (switch_player) then switch_players (player) ; end if ; end if ; end if ; end process ; the_player <= player ;end exemplar ;library ieee ;use ieee.std_logic_1164.all ;use work.mancala_pack.all ;entity mancala is generic (max_marbles : natural := 32) ; port (start_game : boolean ; active_bin_value : buffer integer range 0 to max_marbles-1; active_bin : buffer boolean_array(nr_of_bins-1 downto 0); blink_right, blink_left : inout std_logic; clk, reset : in std_logic; buttons : in boolean_array(nr_of_bins-1 downto 0); button_lights : out boolean_array(nr_of_bins-1 downto 0); l_player, r_player : out std_logic ) ;end mancala ; architecture exemplar of mancala is subtype bin_integer is integer range 0 to max_marbles-1 ; type bin_integer_array is array (nr_of_bins-1 downto 0) of bin_integer ; -- The bins signal bins : bin_integer_array ; signal incremented_bin_value : bin_integer ; signal empty_bins : boolean_array (nr_of_bins-1 downto 0) ; -- The hand signal hand : bin_integer ; signal load_hand_with_active_bin : boolean ; signal decrement_hand : boolean ; signal hand_is_empty : boolean ; -- Which player is playing / winning signal player : player_t ; signal winner : player_t ; signal waiting_for_move : boolean ; signal end_of_the_game : boolean ;begin c : control generic map ( nr_of_bins=>nr_of_bins) port map ( -- To controller : start_game=>start_game, clk=>clk, reset=>reset, buttons=>buttons, empty_bins=>empty_bins, hand_is_empty=>hand_is_empty, -- From controller : active_bin=>active_bin, decrement_hand=>decrement_hand, load_hand_with_active_bin=>load_hand_with_active_bin, the_player=>player, end_of_the_game=>end_of_the_game, waiting_for_move=>waiting_for_move ) ; -- -- Process the amount of marbles in the hand -- process (clk, reset) begin if (reset='1') then hand <= 0 ; elsif clk'event and clk='1' then if (start_game) then hand <= 0 ; elsif (load_hand_with_active_bin) then hand <= active_bin_value ; elsif (decrement_hand and (not hand_is_empty)) then hand <= hand - 1 ; end if ; end if ; end process ; hand_is_empty <= (hand=0) ; -- -- Process the amount of marbles in each bin -- bin_procs : for i in bins'range generate process (reset, clk) begin if (reset='1') then bins(i) <= 0 ; elsif clk'event and clk='1' then if (start_game) then -- Initialize the home bins to zero and the -- work bins to a number that guarantees that there -- will be max_marbles in the game. if (i=OUTER_LEFT or i=OUTER_RIGHT) then bins(i) <= 0 ; else bins(i) <= max_marbles/(nr_of_bins-2) ; end if ; elsif (active_bin(i)) then if (load_hand_with_active_bin) then bins(i) <= 0 ; elsif (decrement_hand and (not hand_is_empty)) then bins(i) <= incremented_bin_value ; end if ; end if ; end if ; end process ; empty_bins(i) <= bins(i) = 0 ; end generate ; -- -- Select the bin (from the bins register) that is presently active -- process (active_bin, bins) begin active_bin_value <= 0 ; for i in bins'range loop if (active_bin(i)) then active_bin_value <= bins(i) ; end if ; end loop ; end process ; -- -- Calculate the incremented value of the presently selected bin -- incremented_bin_value <= active_bin_value + 1 ; -- Generate the light signals for the player that is active l_player <= '1' when player=LEFT else '0' ; r_player <= '1' when player=RIGHT else '0' ; -- -- Define the winner -- winner <= NEITHER when NOT end_of_the_game ELSE BOTH when bins(OUTER_LEFT)=bins(OUTER_RIGHT) ELSE LEFT when bins(OUTER_LEFT)>bins(OUTER_RIGHT) ELSE RIGHT ; -- -- Blink the display of the winner (on/off) -- process (clk, reset) begin if (reset='1') then -- Displays ON blink_left <= '1' ; blink_right <= '1' ; elsif clk'event and clk='1' then case winner is when LEFT => blink_left <= NOT blink_left ; blink_right <= '1' ; when RIGHT => blink_left <= '1' ; blink_right <= NOT blink_right ; when BOTH => blink_left <= NOT blink_left ; blink_right <= NOT blink_right ; when OTHERS => blink_left <= '1' ; blink_right <= '1' ; end case ; end if ; end process ; -- -- Button lights -- Light on each button for possible move -- lights : for i in button_lights'range generate button_lights(i) <= TRUE when (waiting_for_move AND NOT empty_bins(i)) else FALSE ; end generate ; end exemplar ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -