Tic tac toe游戏的VHDL代码?

时间:2014-03-27 17:59:36

标签: vhdl fpga tic-tac-toe

我有18个输出和9个按钮开关可以使用,一个LED作为输出,每次按下按钮时都会改变其状态,以自动化两个玩家的机会。我的代码不起作用,请帮助 我的代码是...预期的行为是当瞬间in1开关为高时,play_to_play应该在输入的每个事件上切换,并根据play_to_play状态和in1高,ou11或ou21应该变高,即一个玩家已经发挥了他的机会并且自动在接下来的比赛中,球员有2次机会

library IEEE;   
use IEEE.STD_LOGIC_1164.ALL;  
entity TicTac is     
    Port ( in1 : in  STD_LOGIC;  
           in2 : in  STD_LOGIC;  
           in3 : in  STD_LOGIC;   
           in4 : in  STD_LOGIC;  
           in5 : in  STD_LOGIC;  
           in6 : in  STD_LOGIC;  
           in7 : in  STD_LOGIC;   
           in8 : in  STD_LOGIC;   
           in9 : in  STD_LOGIC;   
              reset : in  STD_LOGIC;  
            p_to_play : out STD_Logic;   
           p1_win : out  STD_LOGIC;   
           p2_win : out  STD_LOGIC;   
           ou11 : out  STD_LOGIC;   
           ou12 : out  STD_LOGIC;   
           ou13 : out  STD_LOGIC;   
           ou14 : out  STD_LOGIC;   
           ou15 : out  STD_LOGIC;   
           ou16 : out  STD_LOGIC;   
           ou17 : out  STD_LOGIC;   
           ou18 : out  STD_LOGIC;   
           ou19 : out  STD_LOGIC;   
           ou21 : out  STD_LOGIC;   
           ou22 : out  STD_LOGIC;   
           ou23 : out  STD_LOGIC;   
           ou24 : out  STD_LOGIC;   
           ou25 : out  STD_LOGIC;  
           ou26 : out  STD_LOGIC;  
           ou27 : out  STD_LOGIC;   
           ou28 : out  STD_LOGIC;   
           ou29 : out  STD_LOGIC);   
end TicTac;   
architecture Behavioral of TicTac is   
Signal temp1, temp2, temp3, temp4, temp5, temp6,temp7, temp8, temp9,p1_play :std_logic :='0';    
signal o11,o12,o13,o14,o15,o16,o17,o18,o19,o21,o22,o23,o24,o25,o26,o27,o28,o29 :std_logic :='0';    
signal p1win,p2win :std_logic :='0';    
begin   
process(in1,in2,in3,in4,in5,in6,in7,in8,in9,reset)
begin  

   if ((in1'event or in2'event or in3'event or in4'event or in5'event or in6'event or in7'event or in8'event or in9'event) and
    (in1='1' or in2 ='1' or in3='1' or in4='1' or in5='1' or in6='1' or in7='1' or in8='1' or in9='1')) then     
      p1_play <= not(p1_play);    
if(reset'event and reset= '1') then  
temp1 <='0';    
temp2 <='0';   
temp3 <='0';   
temp4 <='0';   
temp5 <='0';   
temp6 <='0';   
temp7 <='0';   
temp8 <='0';  
temp9 <='0';   
p1_play <= '0';  
p1win <='0';    
p2win <='0';    
o11 <='0';    
o12 <='0';   
o13 <='0';   
o14 <='0';   
o15 <='0';   
o16 <='0';   
o17 <='0';   
o18 <='0';   
o19 <='0';   
o21 <='0';   
o22 <='0';   
o23 <='0';   
o24 <='0';   
o25 <='0';   
o26 <='0';   
o27 <='0';   
o28 <='0';   
o29 <='0';   
end if;     
if(in1= '1') then   
temp1 <='1';   
end if;  
if(in2= '1') then   
temp2 <='1';   
end if;   
if(in3= '1') then
temp3 <='1';
end if;
if(in4= '1') then
temp1 <='1';
end if;
if(in5= '1') then
temp5 <='1';
end if;
if(in6= '1') then
temp6 <='1';
end if;
if(in7= '1') then
temp7 <='1';
end if;
if(in8= '1') then
temp8 <='1';
end if;
if(in9= '1') then
temp9 <='1';  
end if;    
if(p1_play='0' and temp1='1') then    
o11 <= '1';    
end if;    
if(p1_play='0' and temp2='1') then   
o12 <= '1';    
end if;    
if(p1_play='0' and temp3='1') then
o13 <= '1';    
end if;   
if(p1_play='0' and temp4='1') then
o14 <= '1';   
end if;    
if(p1_play='0' and temp5='1') then
o15 <= '1';    
end if;    
if(p1_play='0' and temp6='1') then
o16 <= '1';    
end if;    
if(p1_play='0' and temp7='1') then
o17 <= '1';   
end if;    
if(p1_play='0' and temp8='1') then
o18 <= '1';    
end if;    
if(p1_play='0' and temp9='1') then
o19 <= '1';    
end if;     
if(p1_play='1' and temp1='1') then
o21 <= '1';    
end if;   
if(p1_play='1' and temp2='1') then
o22 <= '1';    
end if;    
if(p1_play='1' and temp3='1') then
o23 <= '1';    
end if;    
if(p1_play='1' and temp4='1') then
o24 <= '1';    
end if;    
if(p1_play='1' and temp5='1') then
o25 <= '1';    
end if;    
if(p1_play='1' and temp6='1') then
o26 <= '1';    
end if;    
if(p1_play='1' and temp7='1') then
o27 <= '1';    
end if;    
if(p1_play='1' and temp8='1') then
o28 <= '1';    
end if;    
if(p1_play='1' and temp9='1') then
o29 <= '1';    
end if;    
if((o11='1' and o12='1' and o13='1') or (o14='1' and o15='1' and o16='1') or (o17='1' and o18='1' and o19='1')
or (o11='1' and o14='1' and o17='1') or (o12='1' and o15='1' and o18='1') or (o13='1' and o16='1' and o19='1')
or (o11='1' and o15='1' and o19='1') or (o13='1' and o15='1' and o17='1')) then
p1win <='1';    
end if;     
if((o21='1' and o22='1' and o23='1') or (o24='1' and o25='1' and o26='1') or (o27='1' and o28='1' and o29='1')
or (o21='1' and o24='1' and o27='1') or (o22='1' and o25='1' and o28='1') or (o23='1' and o26='1' and o29='1')
or (o21='1' and o25='1' and o29='1') or (o23='1' and o25='1' and o27='1')) then
p2win <='1';     
end if;   
end if;   
end process;   
ou11 <= o11;   
ou12 <= o12;   
ou13 <= o13;   
ou14 <= o14;   
ou15 <= o15;   
ou16 <= o16;   
ou17 <= o17;   

    ou18 <= o18;   
    ou19 <= o19;   
    ou21 <= o21;  
    ou22 <= o22;   
    ou23 <= o23;   
    ou24 <= o24;  
    ou25 <= o25;   
    ou26 <= o26;   
    ou27 <= o27;   
    ou28 <= o28;   
    ou29 <= o29;   
    p_to_play <= p1_play;   
    p1_win <= p1win;   
    p2_win <= p2win;   
    end Behavior

al;      

3 个答案:

答案 0 :(得分:0)

VHDL中的进程与常规编程语言上的进程相同。过程中的所有信号分配实际上在过程完成时发生(实际上是后来的增量时间,基本上是0时间差)。由于您尝试使用刚刚在过程中分配的临时值,但它尚未实际编写,因此在下次运行该过程之前,您不会触发if语句。

顺便说一句,我没有注意到任何阻止玩家在他们或他们的对手已经玩过的空间中玩的机制。

编辑:另外,你打算用这个做什么?如果你想把它放在带有真正开关的真实FPGA上,它可能会因为一个称为开关弹跳的机电现象而无法工作,这使得每次按下一个开关对硬件看起来很多。

EDIT2:为了解决这个问题(仍然没有修复开关弹跳)你可能想要完全废弃温度(用&#34; in&#34;信号替换它)并放入过程的全部内容,除了复位之外,在if语句中检测in信号的上升沿。

EDIT3:这是一个4x4 tic-tac-toe板的VHDL模型,您的硬件设置扩展到4x4板的16个方块。看看你是否能理解做了什么以及为什么做,然后将它改编成3x3板。

library IEEE;   
use IEEE.STD_LOGIC_1164.ALL;  
entity TicTac is   
    Port (button : in  std_logic_vector(16 downto 1);  
          reset : in  std_logic;  
          p_to_play : out std_logic;   
          p1_win : out  std_logic := '0';   
          p2_win : out  std_logic := '0';   
          ou1 : out std_logic_vector(16 downto 1);    
          ou2 : out std_logic_vector(16 downto 1));   
end TicTac;   
architecture Behavioral of TicTac is    

    signal o1 : std_logic_vector(16 downto 1) := (others => '0');    
    signal o2 : std_logic_vector(16 downto 1) := (others => '0'); 
    signal o  : std_logic_vector(16 downto 1) := (others => '0');
    signal p  : std_logic;
    signal win  : std_logic;
    signal win1 : std_logic;
    signal win2 : std_logic; 

begin   
    ou1 <= o1;
    ou2 <= o2;
    p_to_play <= p;
    p1_win <= win1;
    p2_win <= win2;
    win <= win1 or win2;

    gen_spots : for i in 1 to 16 generate --3 flip flops share a clock (button) for every space on the board
        process(button(i), reset)
        begin
            if(reset = '1') then
                o(i)  <= '0';
                o1(i) <= '0';
                o2(i) <= '0';
            elsif(button(i)'event and button(i)='1' and o(i)='0' and win='0') then
                o(i) <= '1';
                if (p = '0') then
                    o1(i) <= '1';
                else
                    o2(i) <= '1';
                end if;
            end if;
        end process;
    end generate gen_spots;

    process(o) --determines current player by xoring the o values together.
        variable ot : std_logic;
    begin
        ot := '0';
        for i in 1 to 16 loop
            ot := ot xor o(i);
        end loop;
        p <= ot;
    end process;

    process(o1) --checks if player 1 wins
    begin
        win1 <= '0'; --only happens if none of the win1 <= '1' statements occur
        for i in 0 to 3 loop
            if (o1(1+i*4)='1' and o1(2+i*4)='1' and o1(3+i*4)='1' and o1(4+i*4)='1') then --rows
                win1 <= '1';
            end if;
            if (o1(1+i)='1' and o1(5+i)='1' and o1(9+i)='1' and o1(13+i)='1') then --columns
                win1 <= '1';
            end if;
        end loop;
        if (o1(1)='1' and o1(6)='1' and o1(11)='1' and o1(16)='1') or (o1(4)='1' and o1(7)='1' and o1(10)='1' and o1(13)='1') then --diagonals
            win1 <= '1';
        end if;
    end process;

    process(o2) --checks if player 2 wins
    begin
        win2 <= '0'; --only happens if none of the win2 <= '1' statements occur
        for i in 0 to 3 loop
            if (o2(1+i*4)='1' and o2(2+i*4)='1' and o2(3+i*4)='1' and o2(4+i*4)='1') then --rows
                win2 <= '1';
            end if;
            if (o2(1+i)='1' and o2(5+i)='1' and o2(9+i)='1' and o2(13+i)='1') then --columns
                win2 <= '1';
            end if;
        end loop;
        if (o2(1)='1' and o2(6)='1' and o2(11)='1' and o2(16)='1') or (o2(4)='1' and o2(7)='1' and o2(10)='1' and o2(13)='1') then --diagonals
            win2 <= '1';
        end if;
    end process;

end Behavioral; 

我还没有进行详尽的测试,但这可以编译并适用于几个测试用例。

如果它解决了您的问题,请记得将此标记为正确答案。

答案 1 :(得分:0)

----------------------------------------------------------------------------------
-----------------------------   TICTAC TOE GAME ------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity cs_main is
    Port ( in1 : in  STD_LOGIC;
            in2 : in  STD_LOGIC;
              in3 : in  STD_LOGIC;
                  in4 : in  STD_LOGIC;
              in5 : in  STD_LOGIC;
              in6 : in  STD_LOGIC;
              in7 : in  STD_LOGIC;
              in8 : in  STD_LOGIC;
              in9 : in  STD_LOGIC;
           output1 : out  STD_LOGIC_VECTOR (8 downto 0);
              output2 : out  STD_LOGIC_VECTOR (8 downto 0);
              chance_real : out  STD_LOGIC;
              wing : out  STD_LOGIC;
              winr : out  STD_LOGIC;
           reset : in  STD_LOGIC);
end cs_main;

architecture Behavioral of cs_main is
signal temp1,out1,out2,out11,out22 :std_logic_vector (8 downto 0):= "000000000";
signal chance : std_logic := '0';
signal wing1,winr1 : std_logic := '0';
begin

tictac :process(in1,in2,in3,in4,in5,in6,in7,in8,in9)
begin

if rising_edge (reset) then
  out1 <= "000000000";
  out2 <= "000000000";
  chance <= '0';
  wing1 <= '0';
  winr1 <= '0';
else
 if (wing1 = '0' and winr1 = '0') then 
  if rising_edge (in1) then
   if (chance = '0') then
     out1 <= "000000001";
   elsif(chance = '1') then
     out2 <= "000000001";
   end if;
   chance <= not chance ;
  elsif rising_edge(in2) then
   if (chance = '0') then
     out1 <= "000000010";
   elsif(chance = '1') then
     out2 <= "000000010";
   end if;
   chance <= not chance ;
  elsif rising_edge(in3) then
   if (chance = '0') then
     out1 <= "000000100";
   elsif(chance = '1') then
     out2 <= "000000100";
   end if;
  chance <= not chance ;
 elsif rising_edge(in4) then
  if (chance = '0') then
    out1 <= "000001000";
  elsif(chance = '1') then
    out2 <= "000001000";
  end if;
  chance <= not chance ;
 elsif rising_edge(in5) then
  if (chance = '0') then
    out1 <= "000010000";
  elsif(chance = '1') then
    out2 <= "000010000";
  end if;
  chance <= not chance ;
 elsif rising_edge(in6) then
  if (chance = '0') then
    out1 <= "000100000";
  elsif(chance = '1') then
    out2 <= "000100000";
  end if;
  chance <= not chance ;
 elsif rising_edge(in7) then
  if (chance = '0') then
    out1 <= "001000000";
  elsif(chance = '1') then
    out2 <= "001000000";
  end if;
  chance <= not chance ;
 elsif rising_edge(in8) then
  if (chance = '0') then
    out1 <= "010000000";
  elsif(chance = '1') then
    out2 <= "010000000";
  end if;
  chance <= not chance ;
 elsif rising_edge(in9) then
  if (chance = '0') then
    out1 <= "100000000";
  elsif(chance = '1') then
    out2 <= "100000000";
  end if;
  chance <= not chance ;
 end if;
end if;

  out11 <= out11 or out1;
  out22 <= out22 or out2;

 if(((out11 = "000000111" or out11 = "000111000" or out11 = "111000000" or
    out11 = "001001001" or out11 = "010010010" or out11 = "100100100" or
    out11 = "100010001" or out11 = "001010100" ) and chance ='0') or
    ((out22 = "000000111" or out22 = "000111000" or out22 = "111000000" or
    out22 = "001001001" or out22 = "010010010" or out22 = "100100100" or
    out22 = "100010001" or out22 = "001010100" ) and chance = '1')) then
   if (chance = '0')then
    wing1 <= '1';
    winr1 <= '0';
   elsif (chance = '1') then
    wing1 <= '0';
    winr1 <= '1';
   end if;
 else
    wing1 <= '0';
    winr1 <= '0';
 end if;
end if;

end process tictac;

  output1 <= out11 ;
  output2 <= out22 ;  
  chance_real <=  chance;
  wing <= wing1;
  winr <= winr1;

end Behavioral;

答案 2 :(得分:0)

在我的QUARTUS II版本15软件上编译时没有错误的代码。我在我的ALTERA DE2 FPGA板上编程,但它没有显示在显示器上。谁能告诉我该怎么办

library IEEE;   
use IEEE.STD_LOGIC_1164.ALL;  
entity TicTac is   
    Port (button : in  std_logic_vector(16 downto 1);  
          reset : in  std_logic;  
          p_to_play : out std_logic;   
          p1_win : out  std_logic := '0';   
          p2_win : out  std_logic := '0';   
          ou1 : out std_logic_vector(16 downto 1);    
          ou2 : out std_logic_vector(16 downto 1));   
end TicTac;   
architecture Behavioral of TicTac is    

    signal o1 : std_logic_vector(16 downto 1) := (others => '0');    
    signal o2 : std_logic_vector(16 downto 1) := (others => '0'); 
    signal o  : std_logic_vector(16 downto 1) := (others => '0');
    signal p  : std_logic;
    signal win  : std_logic;
    signal win1 : std_logic;
    signal win2 : std_logic; 

begin   
    ou1 <= o1;
    ou2 <= o2;
    p_to_play <= p;
    p1_win <= win1;
    p2_win <= win2;
    win <= win1 or win2;

    gen_spots : for i in 1 to 16 generate --3 flip flops share a clock (button) for every space on the board
        process(button(i), reset)
        begin
            if(reset = '1') then
                o(i)  <= '0';
                o1(i) <= '0';
                o2(i) <= '0';
            elsif(button(i)'event and button(i)='1' and o(i)='0' and win='0') then
                o(i) <= '1';
                if (p = '0') then
                    o1(i) <= '1';
                else
                    o2(i) <= '1';
                end if;
            end if;
        end process;
    end generate gen_spots;

    process(o) --determines current player by xoring the o values together.
        variable ot : std_logic;
    begin
        ot := '0';
        for i in 1 to 16 loop
            ot := ot xor o(i);
        end loop;
        p <= ot;
    end process;

    process(o1) --checks if player 1 wins
    begin
        win1 <= '0'; --only happens if none of the win1 <= '1' statements occur
        for i in 0 to 3 loop
            if (o1(1+i*4)='1' and o1(2+i*4)='1' and o1(3+i*4)='1' and o1(4+i*4)='1') then --rows
                win1 <= '1';
            end if;
            if (o1(1+i)='1' and o1(5+i)='1' and o1(9+i)='1' and o1(13+i)='1') then --columns
                win1 <= '1';
            end if;
        end loop;
        if (o1(1)='1' and o1(6)='1' and o1(11)='1' and o1(16)='1') or (o1(4)='1' and o1(7)='1' and o1(10)='1' and o1(13)='1') then --diagonals
            win1 <= '1';
        end if;
    end process;

    process(o2) --checks if player 2 wins
    begin
        win2 <= '0'; --only happens if none of the win2 <= '1' statements occur
        for i in 0 to 3 loop
            if (o2(1+i*4)='1' and o2(2+i*4)='1' and o2(3+i*4)='1' and o2(4+i*4)='1') then --rows
                win2 <= '1';
            end if;
            if (o2(1+i)='1' and o2(5+i)='1' and o2(9+i)='1' and o2(13+i)='1') then --columns
                win2 <= '1';
            end if;
        end loop;
        if (o2(1)='1' and o2(6)='1' and o2(11)='1' and o2(16)='1') or (o2(4)='1' and o2(7)='1' and o2(10)='1' and o2(13)='1') then --diagonals
            win2 <= '1';
        end if;
    end process;

end Behavioral;