我正在做一个简单的tic tac toe游戏,但有问题。
显然,"播放器"信号永远不是我想要的。我尝试将它声明为布尔值并将其初始化为true,但它从未进入if子句;但是,当我把它改为假时,它也没有进入该条款。然后,我尝试将其更改为位,是的..同样的问题
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;
如果有人知道问题可能是什么,我会很感激!
答案 0 :(得分:2)
我在这里看到几个主要问题。
您的设计没有时钟信号。它试图在所有输入上进行边沿触发(例如,gradle.properties
),这不太可能合成到工作逻辑。
你需要一个时钟信号。如果你不熟悉这个概念,那么现在是时候回到书本上阅读如何设计顺序逻辑了。
您的设计正在尝试将// Hypothetical code, does not actually compile:
val a: Int? = 1 // A boxed Int (java.lang.Integer)
val b: Long? = a // implicit conversion yields a boxed Long (java.lang.Long)
print(a == b) // Surprise! This prints "false" as Long's equals()
// check for other part to be Long as well
用作row0line0_in
信号的值。该值仅在模拟中有意义,它用于表示未初始化的值;在综合中,这些信号都将以任意值(可能为0)进行初始化。如果您确实想要存储三个不同的值,则需要使用多位类型。
第一个进程中的表达式'U'
与任何事件都没有关联。这将在模拟中出现意外行为(当任何输入的值发生变化时,值可能会发生变化,从0到1或反之亦然),并且它将无法合成(因为没有合理的触发方式)这个逻辑在多个时钟的两个边缘上。)
答案 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
。