【问题标题】:Tic-tac-toe in VHDLVHDL 中的井字游戏
【发布时间】:2016-04-19 09:13:42
【问题描述】:

我正在编写井字游戏的 VHDL 代码。在我的代码中,获胜状态会延迟一圈。

(P.S. 我对时钟不是很熟悉,所以我必须设置 p1_playp2_play 值,即 1 或 0 在波形中使用强制)。有人可以建议我是什么让我的程序延迟一圈。

谢谢。

(可点击)

        library IEEE;   
    use IEEE.STD_LOGIC_1164.ALL;  
    entity tttt1 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; 
       p1_play : in STD_LOGIC;
       p2_play : in STD_LOGIC;
   p1_win : out STD_LOGIC;
       p2_win : out STD_LOGIC;
   out_11 : out  STD_LOGIC;   
       out_12 : out  STD_LOGIC;   
       out_13 : out  STD_LOGIC;   
       out_21 : out  STD_LOGIC;   
       out_22 : out  STD_LOGIC;   
       out_23 : out  STD_LOGIC;   
       out_31 : out  STD_LOGIC;   
       out_32 : out  STD_LOGIC;  
       out_33 : out  STD_LOGIC);

    end entity tttt1;
    architecture Behavioral of tttt1 is
    signal temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29 :std_logic :='0';   
    signal p1win,p2win :std_logic :='0'; 
    signal o11,o12,o13,o21,o22,o23,o31,o32,o33:std_logic :='0';

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

-----------Start Player 1 Play-------------

if(p1_play ='1' and p2_play='0') then
if (in1= '1') then   
temp11 <='1';
temp21 <='0';
o11<='1';   

elsif(in2= '1') then   
temp12 <='1';
temp22 <='0';  
o12<='1';  

elsif(in3= '1') then
temp13 <='1';
temp23 <='0';
o13<='1';

elsif(in4= '1') then
temp14 <='1';
temp24 <='0';
o21<='1';

elsif(in5= '1') then
temp15 <='1';
temp25 <='0';
o22<='1';

elsif(in6= '1') then
temp16 <='1';
temp26 <='0';
o23<='1';

elsif(in7= '1') then
temp17 <='1';
temp27 <='0';
o31<='1';

elsif(in8= '1') then
temp18 <='1';
temp28 <='0';
o32<='1';

elsif(in9= '1') then
temp19 <='1';
temp29 <='0';  
o33<='1';
end if;
end if; 
if ((temp11='1' and temp12='1' and temp13='1') or (temp14='1' and temp15='1' and temp16='1') or (temp17='1' and temp18='1' and temp19='1')
or (temp11='1' and temp14='1' and temp17='1') or (temp12='1' and temp15='1' and temp18='1') or (temp13='1' and temp16='1' and temp19='1')
or (temp11='1' and temp15='1' and temp19='1') or (temp13='1' and temp15='1' and temp17='1')) then
p1win<='1';
end if;
---------------End Player 1 Play---------------
--------------Start Player 2 Play--------------                 

if(p2_play ='1' and p1_play='0') then   
if (in1= '1')then
temp21 <='1';
temp11 <='0';  
o11<='1'; 

elsif(in2= '1') then   
temp22 <='1';
temp12 <='0';
o12<='1';   

elsif(in3= '1') then
temp23 <='1';
temp13 <='0';
o13<='1';

elsif(in4= '1') then
temp24 <='1';
temp14 <='0';
o21<='1';

elsif(in5= '1') then
temp25 <='1';
temp15 <='0';
o22<='1';

elsif(in6= '1') then
temp26 <='1';
temp16 <='0';
o23<='1';

elsif(in7= '1') then
temp27 <='1';
temp17 <='0';
o31<='1';

elsif(in8= '1') then
temp28 <='1';
temp18 <='0';
o32<='1';

elsif(in9= '1') then
temp29 <='1';
temp19 <='0';  
o33<='1';
end if;
end if;

if(  (temp21='1' and temp22='1' and temp23='1') or (temp24='1' and temp25='1' and temp26='1') or (temp27='1' and temp28='1' and temp29='1')
or (temp21='1' and temp24='1' and temp27='1') or (temp22='1' and temp25='1' and temp28='1') or (temp23='1' and temp26='1' and temp29='1')
or (temp21='1' and temp25='1' and temp29='1') or (temp23='1' and temp25='1' and temp27='1')) then
    p2win<='1';

end if;

---------------End Player 2 Play---------------
end process;

p1_win <= p1win;
p2_win <= p2win;
out_11 <= o11;
out_12 <= o12;   
out_13 <= o13;   
out_21 <= o21;   
out_22 <= o22;   
out_23 <= o23;   
out_31 <= o31;   
out_32 <= o32;   
out_33 <= o33;

end Behavioral;

【问题讨论】:

  • 请缩进你的代码,这样我们就可以阅读它,而不用计算打开和关闭 if/end-if-statements...顺便说一句:你的 VHDL 根本没有时钟信号。
  • 请注意波形上的红色图例错误地将 p2_win 识别为 p1_win。

标签: vhdl delay clock tic-tac-toe


【解决方案1】:

延迟查看 p2_win 的原因是 temp11 到 temp13、temp21 到 temp 23 和 temp31 到 temp33 不在进程敏感度列表中(也不应该在)。 p1_win 或 p2_win 的更新只有在进程敏感度列表中出现信号事件时才会发生,在这种情况下是 in3 和 in9 上的转换。

将两个win输出分配给单独的并发信号分配可以获得正确的延迟:

修改后的代码(为了便于阅读而格式化)如下所示:

library ieee;
use ieee.std_logic_1164.all;

entity tttt1 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;
        p1_play:    in  std_logic;
        p2_play:    in  std_logic;
        p1_win:     out std_logic;
        p2_win:     out std_logic;
        out_11:     out std_logic;
        out_12:     out std_logic;
        out_13:     out std_logic;
        out_21:     out std_logic;
        out_22:     out std_logic;
        out_23:     out std_logic;
        out_31:     out std_logic;
        out_32:     out std_logic;
        out_33:     out std_logic
    );
end entity tttt1;

architecture behavioral of tttt1 is
    signal temp11, temp12,
           temp13, temp14,
           temp15, temp16,
           temp17, temp18,
           temp19, temp21,
           temp22, temp23,
           temp24, temp25,
           temp26, temp27,
           temp28, temp29:     std_logic := '0';
    signal p1win,p2win:        std_logic := '0';
    signal o11,o12,o13,o21,
           o22,o23,o31,o32,
           o33:                std_logic := '0';

begin

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

-----------Start Player 1 Play-------------

        if p1_play = '1' and p2_play = '0' then
            if in1 = '1' then
                temp11 <= '1';
                temp21 <= '0';
                o11 <= '1';

            elsif in2 = '1' then
                temp12 <= '1';
                temp22 <= '0';
                o12 <= '1';

            elsif in3 = '1' then
                temp13 <= '1';
                temp23 <= '0';
                o13 <= '1';

            elsif in4 = '1' then
                temp14 <= '1';
                temp24 <= '0';
                o21 <= '1';

            elsif in5 = '1' then
                temp15 <= '1';
                temp25 <= '0';
                o22 <= '1';

            elsif in6 = '1' then
                temp16 <= '1';
                temp26 <= '0';
                o23<= '1';

            elsif in7 = '1' then
                temp17 <= '1';
                temp27 <= '0';
                o31<= '1';

            elsif in8 = '1' then
                temp18 <= '1';
                temp28 <= '0';
                o32 <= '1';

            elsif in9 = '1' then
                temp19 <= '1';
                temp29 <= '0';
                o33 <= '1';
            end if;
        end if;

        -- if  (temp11 = '1' and temp12 = '1' and temp13 = '1') or
        --     (temp14 = '1' and temp15 = '1' and temp16 = '1') or
        --     (temp17 = '1' and temp18 = '1' and temp19 = '1') or
        --     (temp11 = '1' and temp14 = '1' and temp17 = '1') or
        --     (temp12 = '1' and temp15 = '1' and temp18 = '1') or
        --     (temp13 = '1' and temp16 = '1' and temp19 = '1') or
        --     (temp11 = '1' and temp15 = '1' and temp19 = '1') or
        --     (temp13 = '1' and temp15 = '1' and temp17 = '1') then
        --
        --     p1win <= '1';
        --
        -- end if;

---------------End Player 1 Play---------------

--------------Start Player 2 Play--------------

        if p2_play = '1' and p1_play = '0' then
            if in1 = '1' then
                temp21 <= '1';
                temp11 <= '0';
                o11 <= '1';

            elsif in2 = '1' then
                temp22 <= '1';
                temp12 <= '0';
                o12 <= '1';

            elsif in3 = '1' then
                temp23 <= '1';
                temp13 <= '0';
                o13 <= '1';

            elsif in4 = '1' then
                temp24 <= '1';
                temp14 <= '0';
                o21 <= '1';

            elsif in5 = '1' then
                temp25 <= '1';
                temp15 <= '0';
                o22 <= '1';

            elsif in6 = '1' then
                temp26 <= '1';
                temp16 <= '0';
                o23 <= '1';

            elsif in7 = '1' then
                temp27 <= '1';
                temp17 <= '0';
                o31 <= '1';

            elsif in8 = '1' then
                temp28 <= '1';
                temp18 <= '0';
                o32 <= '1';

            elsif in9 = '1' then
                temp29 <= '1';
                temp19 <= '0';
                o33 <= '1';
            end if;
        end if;

        -- if  (temp21 = '1' and temp22 = '1' and temp23 = '1') or
        --     (temp24 = '1' and temp25 = '1' and temp26 = '1') or
        --     (temp27 = '1' and temp28 = '1' and temp29 = '1') or
        --     (temp21 = '1' and temp24 = '1' and temp27 = '1') or
        --     (temp22 = '1' and temp25 = '1' and temp28 = '1') or
        --     (temp23 = '1' and temp26 = '1' and temp29 = '1') or
        --     (temp21 = '1' and temp25 = '1' and temp29 = '1') or
        --     (temp23 = '1' and temp25 = '1' and temp27 = '1') then
        --
        --     p2win <= '1';
        --
        -- end if;
---------------End Player 2 Play---------------
    end process;

    p1win <= (temp11 and temp12 and temp13) or
             (temp14 and temp15 and temp16) or
             (temp17 and temp18 and temp19) or
             (temp11 and temp14 and temp17) or
             (temp12 and temp15 and temp18) or
             (temp13 and temp16 and temp19) or
             (temp11 and temp15 and temp19) or
             (temp13 and temp15 and temp17);

     p2win <= (temp21 and temp22 and temp23) or
              (temp24 and temp25 and temp26) or
              (temp27 and temp28 and temp29) or
              (temp21 and temp24 and temp27) or
              (temp22 and temp25 and temp28) or
              (temp23 and temp26 and temp29) or
              (temp21 and temp25 and temp29) or
              (temp23 and temp25 and temp27);

    p1_win <= p1win;
    p2_win <= p2win;
    out_11 <= o11;
    out_12 <= o12;
    out_13 <= o13;
    out_21 <= o21;
    out_22 <= o22;
    out_23 <= o23;
    out_31 <= o31;
    out_32 <= o32;
    out_33 <= o33;

end architecture behavioral;

功能更改仅限于使 win 输出分配并发信号分配语句。

使用测试台在您的链接波形中重现刺激:

library ieee;
use ieee.std_logic_1164.all;

entity tttt1_tb is
end entity;

architecture foo of tttt1_tb is
    signal in1:        std_logic := '0';
    signal in2:        std_logic := '0';
    signal in3:        std_logic := '0';
    signal in4:        std_logic := '0';
    signal in5:        std_logic := '0';
    signal in6:        std_logic := '0';
    signal in7:        std_logic := '0';
    signal in8:        std_logic := '0';
    signal in9:        std_logic := '0';
    signal p1_play:    std_logic := '0';
    signal p2_play:    std_logic := '0';

    signal p1_win:     std_logic;
    signal p2_win:     std_logic;
    signal out_11:     std_logic;
    signal out_12:     std_logic;
    signal out_13:     std_logic;
    signal out_21:     std_logic;
    signal out_22:     std_logic;
    signal out_23:     std_logic;
    signal out_31:     std_logic;
    signal out_32:     std_logic;
    signal out_33:     std_logic;

begin
DUT:
    entity work.tttt1
        port map (
            in1 => in1,
            in2 => in2,
            in3 => in3,
            in4 => in4,
            in5 => in5,
            in6 => in6,
            in7 => in7,
            in8 => in8,
            in9 => in9,
            p1_play => p1_play,
            p2_play => p2_play,

            p1_win => p1_win,
            p2_win => p2_win,
            out_11 => out_11,
            out_12 => out_12,
            out_13 => out_13,
            out_21 => out_21,
            out_22 => out_22,
            out_23 => out_23,
            out_31 => out_31,
            out_32 => out_32,
            out_33 => out_33
        );
STIMULI:
    process
    begin
        in1 <= '1';
        p1_play <= '1';
        wait for 100 ns; 
        in1 <= '0';
        in2 <= '1';
        p1_play <= '0';
        p2_play <= '1';
        wait for 100 ns;
        in2 <= '0';
        in9 <= '1';
        p1_play <= '1';
        p2_play <= '0';
        wait for 100 ns;
        in5 <= '1';
        in9 <= '0';
        p1_play <= '0';
        p2_play <= '1';
        wait for 100 ns;
        in5 <= '0';
        in7 <= '1';
        p1_play <= '1';
        p2_play <= '0';
        wait for 100 ns;
        in7 <= '0';
        in8 <= '1';
        p1_play <= '0';
        p2_play <= '1';
        wait for 100 ns;
        in3 <= '1';
        in8 <= '0';
        p1_play <= '1';
        p2_play <= '0';
        wait for 100 ns;
        wait;        

    end process;
end architecture;

缺少规则检查,不允许玩家不经意间占领方格。应该执行该规则以及清除游戏的方法。游戏状态保存在推断的锁存器中,如果锁存器是在由单个输入驱动的单独过程中描述的,则可能更符合综合条件。还期望输入被去抖动。

由于硬件期望在 p1_play 和 p2_play 的值稳定时发生输入,因此可以使用时钟并传递输入事件(持续一个时钟)。在硬件实现中异步描述这类游戏过去很常见(想想 70 年代和 80 年代)。

【讨论】:

  • 这非常有用。非常感谢你回答我的问题。我真的很感激你的好意。
猜你喜欢
  • 1970-01-01
  • 2015-06-12
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多