📄 vhdl design game .txt
字号:
-- Continue if last marble dropped in a non-empty bin.
-- Re-load hand with the full bin contents.
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 + -