【问题标题】:VHDL code for Tic Tac Toe井字游戏的 VHDL 代码
【发布时间】:2017-11-24 05:36:36
【问题描述】:

我正在制作一个简单的井字游戏,但有问题。

显然,“玩家”信号从来都不是我想要的。我尝试将其声明为布尔值并将其初始化为真,但它从未进入 if 子句;但是,当我将其更改为 false 时,它​​也没有进入子句。然后,我尝试将其更改为位,是的..同样的问题

library ieee;
use ieee.std_logic_1164.all;

entity ticTacToe is
port(
    hex: OUT STD_LOGIC_VECTOR(0 TO 6);
    useless         : out bit           := '1';
    win_X           : out bit           := '1';
    win_O           : out bit           := '1';
    row0line0_in    :   in  std_logic   := 'U';
    row1line0_in    :   in  std_logic   := 'U';
    row2line0_in    :   in  std_logic   := 'U';
    row0line1_in    :   in  std_logic   := 'U';
    row1line1_in    :   in  std_logic   := 'U';
    row2line1_in    :   in  std_logic   := 'U';
    row0line2_in    :   in  std_logic   := 'U';
    row1line2_in    :   in  std_logic   := 'U';
    row2line2_in    :   in  std_logic   := 'U'
);
end ticTacToe;


architecture behaviour of ticTacToe is
    signal player           : bit; --X starts game
    shared variable wins    : boolean   := false;

    shared variable row0line0   :   std_logic   := 'U';
    shared variable row1line0   :   std_logic   := 'U';
    shared variable row2line0   :   std_logic   := 'U';
    shared variable row0line1   :   std_logic   := 'U';
    shared variable row1line1   :   std_logic   := 'U';
    shared variable row2line1   :   std_logic   := 'U';
    shared variable row0line2   :   std_logic   := 'U';
    shared variable row1line2   :   std_logic   := 'U';
    shared variable row2line2   :   std_logic   := 'U';


    function winner(row0line0, row0line1, row0line2, row1line0, row1line1,
        row1line2, row2line0, row2line1, row2line2:std_logic) return boolean is
    begin
        --check if X wins
        if(row0line0 = '1' and row0line1 = '1' and row0line2 = '1') then
            win_X <= '0';
        end if;
        if(row0line0 = '1' and row1line0 = '1' and row2line0 = '1') then
            win_X <= '0';
        end if;
        if(row0line0 = '1' and row1line1 = '1' and row2line2 = '1') then
            win_X <= '0';
        end if;
        if(row1line0 = '1' and row1line1 = '1' and row1line2 = '1') then
            win_X <= '0';
        end if;
        if(row2line0 = '1' and row2line1 = '1' and row2line2 = '1') then
            win_X <= '0';
        end if;
        if(row2line0 = '1' and row1line1 = '1' and row0line2 = '1') then
            win_X <= '0';
        end if;
        if(row0line1 = '1' and row1line1 = '1' and row2line1 = '1') then
            win_X <= '0';
        end if;
        if(row0line2 = '1' and row1line2 = '1' and row2line2 = '1') then
            win_X <= '0';
        end if;

        --check if O wins
        if(row0line0 = '0' and row0line1 = '0' and row0line2 = '0') then
            win_O <= '0';
        end if;
        if(row0line0 = '0' and row1line0 = '0' and row2line0 = '0') then
            win_O <= '0';
        end if;
        if(row0line0 = '0' and row1line1 = '0' and row2line2 = '0') then
            win_O <= '0';
        end if;
        if(row1line0 = '0' and row1line1 = '0' and row1line2 = '0') then
            win_O <= '0';
        end if;
        if(row2line0 = '0' and row2line1 = '0' and row2line2 = '0') then
            win_O <= '0';
        end if;
        if(row2line0 = '0' and row1line1 = '0' and row0line2 = '0') then
            win_O <= '0';
        end if;
        if(row0line1 = '0' and row1line1 = '0' and row2line1 = '0') then
            win_O <= '0';
        end if;
        if(row0line2 = '0' and row1line2 = '0' and row2line2 = '0') then
            win_O <= '0';
        end if;

    return false;   
    end winner;

begin
    --variable becomes '0' for player O and '1' for player X
    process(row0line0_in, row0line1_in, row0line2_in, row1line0_in, row1line1_in,
        row1line2_in, row2line0_in, row2line1_in, row2line2_in)is
    begin
        if(row0line0_in'event and row0line0_in = '1')then
            if(player = '0')then
                row0line0 := '1';
            else
                useless <= '0';
                row0line0 := '0';
            end if;
        end if;

        if(row0line1_in'event and row0line1_in = '1')then
            if(player = '0')then
                row0line1 := '1';
            else
                row0line1 := '0';
            end if;
        end if;

        if(row0line2_in'event and row0line2_in = '1')then
            if(player = '0')then
                row0line2 := '1';
            else
                row0line2 := '0';
            end if;
        end if;

        if(row1line0_in'event and row1line0_in = '1')then
            if(player = '0')then
                row1line0 := '1';
            else
                row1line0 := '0';
            end if;
        end if;

        if(row1line1_in'event and row1line1_in = '1')then
            if(player = '0')then
                row1line1 := '1';
            else
                row1line1 := '0';
            end if;
        end if;

        if(row1line2_in'event and row1line2_in = '1')then
            if(player = '0')then
                row1line2 := '1';
            else
                row1line2 := '0';
            end if;
        end if;

        if(row2line0_in'event and row2line0_in = '1')then
            if(player = '0')then
                row2line0 := '1';
            else
                row2line0 := '0';
            end if;
        end if;

        if(row2line1_in'event and row2line1_in = '1')then
            if(player = '0')then
                row2line1 := '1';
            else
                row2line1 := '0';
            end if;
        end if;

        if(row2line2_in'event and row2line2_in = '1') then 
            if(player = '0')then
                row2line2 := '1';
            else
                row2line2 := '0';
            end if;
        end if;
        player <= not player;
    end process;

    --check winner
    process(player)is
    begin
        wins    :=  winner(row0line0, row0line1, row0line2, row1line0, row1line1,
        row1line2, row2line0, row2line1, row2line2);
    end process;
end behaviour;

如果有人知道问题可能是什么,我将不胜感激!

【问题讨论】:

  • 如果您查看FPGA Tic Tac Toe,您会发现游戏板由多色 LED 组成,一个玩家为红色,另一个玩家为绿色。这意味着游戏板在 3x3 网格上的每个位置都有两个位。请注意,它使用时钟(和重置)。还要注意它在两条对角线上的得分。

标签: vhdl fpga tic-tac-toe


【解决方案1】:

我在这里看到了几个主要问题。

  1. 您的设计没有时钟信号。它正在尝试对所有的输入(例如row0line0_in)进行边沿触发,这不太可能合成到工作逻辑中。

    您需要一个时钟信号。如果您不熟悉这个概念,是时候回到书本上,了解如何设计时序逻辑了。

  2. 您的设计正在尝试使用'U' 作为std_logic 信号的值。该值仅在模拟中有意义,用于表示未初始化值;在综合中,这些信号都将被初始化为一个任意值(可能为 0)。如果您确实想存储三个不同的值,则需要为此使用多位类型。

  3. 第一个进程中的表达式player &lt;= not player 与任何事件都没有关联。这将在模拟中出现意外行为(只要任何输入的值发生变化,该值可能会发生变化,从 0 到 1,反之亦然),并且它根本无法合成(因为没有明智的触发方式这个逻辑在多个时钟的两个边沿上)。

【讨论】:

    【解决方案2】:

    duskwuff 的回答中指出的所有问题都是正确的,可能会解决您的问题。不过,我想补充几个 VHDL 不好的问题:

    我强烈建议您立即停止使用bit 类型。如果您想表达逻辑,请仅使用std_logic。原因可以在here找到。我会争辩说,95% 的时间(绝对是你的情况),同样的论点也适用于 boolean 类型的使用。

    另外,请不要使用shared variable。这是VHDL。它是硬件描述,而不是程序代码。 VHDL 没有定义当变量访问发生冲突时会发生什么。 VHDL 中的共享变量有非常少且非常具体的用例。你似乎是一个初学者,所以我的建议是:忘记这个概念的存在。它不太可能为您产生良好的代码或编码实践。仅使用信号。

    在您的情况下,变量声明也碰巧完全没有做任何事情。你的函数声明包含所有变量的声明,而VHDL一般使用最局部的声明。您的架构全局共享变量永远不会被使用。仅分配了wins 变量,但它永远不会分配给输出或读回,因此它也是无用的。您应该将wins 声明为signal wins : std_logic 并删除其他共享变量。

    最后,一个更高级的方面。你非常热衷于初始化你的输入、输出、信号和变量。也许那是因为您已经学会了作为编码人员这样做,也许那是因为您应该在某个地方阅读。但是请注意,不能保证这些初始化是可综合的。在不从 ROM 加载配置比特流的 ASIC 或基于闪存的 FPGA 上,这些初始化很可能不起作用。这可能并且将导致时髦的未定义行为,其中一个批次的芯片将在室温下可靠地初始化为 0,而另一个芯片将可靠地初始化为 1(我在 Microsemi FPGA 上看到过这种情况)。如果你按照duskwuff 的建议进行操作并初始化为'1''0',则存在模拟不匹配的风险(即,使用这些初始化的模拟与实际硬件的工作方式不同)。 考虑不要在声明时初始化信号,而是在复位时初始化它们。这样,如果您忘记重置信号并知道有问题,您将在模拟器中看到状态 U

    【讨论】:

    • 我同意你最后的 3 个建议,但不同意第一个。请不要使用std_logic 代替bit。在不需要时使用已解析类型是非常糟糕的做法并且容易出错。如果您真的不想使用bit,请使用std_ulogic。而boolean 绝对可以表达条件。 VHDL 是一种高级 语言。不要无缘无故地听从那些让你回到低级编程的建议。
    • 我大多不同意。第一:我认为你是对的,std_ulogic 可以说是更好且不易出错的选择。我使用std_logic 的唯一原因是习惯,并且认为在实践中,由于分辨率导致的错误很少发生在我身上,因为我对自己的信号很小心——这根本不是一个好点。 但是,如果你同意我关于初始化的最后一点,你不能说bit 是一个很好的类型。 bit 信号总是被初始化,而你没有办法找到一个被遗忘的初始化,因为你使用了bit。这是一个真正的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 2015-06-12
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    相关资源
    最近更新 更多