Verilog wires被设置为X而不是1
我目前正在用verilog编写一个21点游戏,包括游戏逻辑和计分等几个模块。我的项目的目标是通过VGA和nexys3 FPGA板在屏幕上显示21点游戏。在设置VGA之前,我需要确保我的游戏逻辑正常工作,并正确设置玩家手牌和玩家分数。不幸的是,玩家的手牌设置不正确,显示的X值应该是1。下面是我所有的模块和代码,底部是我正在运行的模拟: 这是调用我的其他模块的主模块Verilog wires被设置为X而不是1,verilog,Verilog,我目前正在用verilog编写一个21点游戏,包括游戏逻辑和计分等几个模块。我的项目的目标是通过VGA和nexys3 FPGA板在屏幕上显示21点游戏。在设置VGA之前,我需要确保我的游戏逻辑正常工作,并正确设置玩家手牌和玩家分数。不幸的是,玩家的手牌设置不正确,显示的X值应该是1。下面是我所有的模块和代码,底部是我正在运行的模拟: 这是调用我的其他模块的主模块 module blackJack( input clk, input btnhit, //deal card to
module blackJack(
input clk,
input btnhit, //deal card to player
input btnpass, //stay for player/pass to dealer
input btnreset, //reset game to 0 and redeal
output Hsync,
output Vsync,
output reg [2:0] vgaRed,
output reg [2:0] vgaGreen,
output reg [1:0] vgaBlue
);
wire [7:0] plscore;
wire [7:0] dlscore;
wire [7:0] plhand;
wire [7:0] dlhand;
wire [2:0] state;
wire [7:0] plcard;
wire [7:0] dlcard;
wire plbust;
wire dlbust;
wire plbj;
wire dlbj;
wire plhit;
wire dlhit;
wire plwin;
wire pllose;
reg vgaclk;
wire trigger;
clock vclk(
.clk(clk),
.vgaclk(vgaclk)
);
wire hit;
debouncer hitD(
.clk(clk),
.button_in(btnhit),
.button_out(hit)
);
wire pass;
debouncer passD(
.clk(clk),
.button_in(btnpass),
.button_out(pass)
);
wire reset;
debouncer resetD(
.clk(clk),
.button_in(btnreset),
.button_out(reset)
);
controller cntrl(
.clk(clk),
.trigger(trigger),
.state(state),
.curPlHand(plhand),
.curDlHand(dlhand),
.dlhit(dlhit),
.plhit(plhit),
.plwin(plwin),
.pllose(pllose),
.plscore(plscore),
.dlscore(dlscore)
);
randomGen gen(
.clk(clk),
.card1(plcard),
.card2(dlcard)
);
player pl(
.clk(clk),
.addCard(plhit),
.card(plcard),
.hand(plhand)
);
player dl(
.clk(clk),
.addCard(dlhit),
.card(dlcard),
.hand(dlhand)
);
checkBust chkpl(
.clk(clk),
.handTotal(plhand),
.bust(plbust),
.blackJack(plbj)
);
checkBust chkdl(
.clk(clk),
.handTotal(dlhand),
.bust(dlbust),
.blackJack(dlbj)
);
stateMonitor sm(
.clk(clk),
.reset(reset),
.hit(hit),
.pass(pass),
.plwin(plwin),
.pllose(pllose),
.state(state),
.trigger(trigger)
);
endmodule
下面是每个单独的模块
module clock(
input clk,
output vgaclk
);
reg vgaclk;
reg [31:0] out = 0;
always @ (posedge clk) begin
if (out >= 3) begin
out <= 0;
end
if (out == 3) begin
vgaclk <= 1;
end
else begin
vgaclk <= 0;
end
out <= out + 1;
end
endmodule
以下是我的模拟图像,它仅通过向玩家分发2张卡和向庄家分发1张卡来测试游戏的初始设置:
从模拟中可以看到,当plhit=1时,卡6被添加到玩家手上(这是玩家模块中的addcard)。应在plhand中显示的正确值应为00000110,但1为X
我遇到的问题是,当我试图将一张牌添加到玩家的手牌总分(8位)时,应该是1的位被设置为X。我尝试将plscore重新设置为reg,并尝试了多次分配操作,但我没有运气。任何帮助都将不胜感激,如果有任何信息需要,我将很乐意迅速回复 注意:这不是问题所在。有关更多信息,请参阅其他答案/评论 在
player
模块中,您没有针对所有条件正确设置hand
。具体而言:
always @(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
end
您必须记住,verilog中的信号表示物理电路。我们将为有线信号设置值的东西称为驱动器。信号不允许有多个驱动器,因为这可能会导致短路(一个驱动器希望将Vdd放在导线上,而另一个驱动器将其接地) 在您的情况下,控制器和播放器都指定它们输出到
plhand
,这使它们都成为驱动程序。因此,当玩家想要将1
写入plhand
位时,控制器仍在写入0
,这会导致冲突。你应该得到一个错误或警告,信号有多个驱动程序,这会让你知道你有这种行为
简而言之,您可以在任意多个模块之间传递一条导线,但这些模块中只有一个可以向其输出。因此,考虑将<代码> CurpRoad <代码>从<代码>输出<代码>改为<代码>输入< /代码> .< /p> < p>问题:
用拳头打下头球。您正在混合ANSI和非ANSI标题样式。这是非法的语法。一些模拟器/合成器允许这样做,但这是一种糟糕的做法。我已经在“”和“”中更深入地回答了标题相关的问题,所以我只做总结;遵循ANSI或非ANSI,不要在同一模块中混合标题样式。您可以对不同的模块使用不同的标题样式,但建议保持一致。我喜欢ANSI风格
例如:
module clock(
input clk,
output vgaclk
);
reg vgaclk; // <-- this is mixing styles
...
module checkBust (
input clk,
input handTotal,
output bust,
output blackJack
);
wire [7:0] handTotal; // <-- these are mixing styles too
reg blackJack;
reg bust;
...
某些信号(例如vgaclk
)未初始化。您可以在内联或初始块中初始化它们,但是建议在“始终”块中重置它们。这样,您可以在不关闭设计电源的情况下恢复初始值。FPGA的异步复位触发器数量有限,因此只能使用同步复位。ASIC更喜欢使用异步复位触发器初始化所有值,并使用同步复位进行动态复位。例如:
always @(posedge clk) begin
if (reset) begin
hand <= 8'h0;
end
if (addCard == 1) begin
hand <= hand + card;
end
end
谢谢你的回复。我已经做了改变,但它仍然给我同样的问题。我不确定这是否是一个模块没有处理案例的问题,但我觉得这可能是我在多个模块中使用plhand的问题。这就是问题所在,还是说有多少模块使用同一根电线并不一定重要?对于时钟信号,假设它们在不改变的情况下保持其值,因此您不需要涵盖
else
情况。@wilcroft我已经有一段时间没有使用Verilog了(很遗憾),所以如果是这样,我的错。@DavidScheibe-如果您试图从两个不同的模块进行分配(即,在模块foo
和模块bar
中设置x[6]
),这将很重要。如果您在不同的模块中分配单个位(例如,在模块foo
中设置x[5]
,在模块bar
中设置x[6]
),我认为这无关紧要。@tonysdg拥有它可能不会有什么坏处,但没有它并不是这里的问题。当您尝试综合这一点时,检查错误日志中是否有关于“闩锁”或其他类似问题的消息。我没有看到任何“闩锁”错误/警告消息。我收到的唯一警告是关于“不允许重新声明ansi端口******”,其中****是我正在传递的许多变量。这些警告特别出现在各个模块中,如randomGen、player等,但根据iverilog
(很遗憾,我现在没有安装Xilinx工具),这些警告不在主21点模块中,看起来您没有将card1
和card2
都声明为randomGen
中的向量,并且checkBust
中的handTotal
也存在同样的问题。(换句话说,在模块中你说reg[7:0]xyz
,但在模块声明中你跳过了[7:0]
)。好的,我也会研究一下。在以前的项目中,我对这种语法没有任何问题,但是如果它删除了警告,我肯定它会帮助程序保持稳定。我有几个警告-这似乎是最相关的,但如果我有时间,我会玩它,看看我是否能提供更多帮助。祝你好运!!另一方面,如果您想要某种重置功能,最好在自己的modu中重置每个信号
module randomGen (
input clk,
output card1,
output card2
);
reg [7:0] card1;
reg [7:0] card2;
always @ (posedge clk) begin
card1 <= ({$random} % 51 >> 2) + 1;
card2 <= ({$random} % 51 >> 2) + 1;
end
endmodule
module checkBust (
input clk,
input handTotal,
output bust,
output blackJack
);
wire [7:0] handTotal;
reg blackJack;
reg bust;
always @(posedge clk) begin
if(handTotal == 8'd21) begin
bust <= 0;
blackJack <= 1;
end
else if(handTotal > 8'd21) begin
bust <= 1;
blackJack <= 0;
end
else begin
bust <= 0;
blackJack <= 0;
end
end
endmodule
module debouncer(
input clk,
input button_in,
output button_out
);
reg [1:0] button_buffer;
assign button_out = button_buffer[0];
always @(posedge clk or posedge button_in) begin
if (button_in)
button_buffer <= 2'b11;
else
button_buffer <= {1'b0, button_buffer[1]};
end
endmodule
module testBlackjack;
// Inputs
reg clk;
reg btnhit;
reg btnpass;
reg btnreset;
// Instantiate the Unit Under Test (UUT)
blackJack uut (
.clk(clk),
.btnhit(btnhit),
.btnpass(btnpass),
.btnreset(btnreset)
);
initial begin
// Initialize Inputs
clk = 0;
btnhit = 0;
btnpass = 0;
btnreset = 0;
// Wait 100 ns for global reset to finish
#1000;
$finish;
end
always #20 clk = ~clk;
endmodule
always @(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
end
always @(posedge clk) begin
if (addCard == 1)
hand <= hand + card;
else
hand <= hand;
end
module clock(
input clk,
output vgaclk
);
reg vgaclk; // <-- this is mixing styles
...
module checkBust (
input clk,
input handTotal,
output bust,
output blackJack
);
wire [7:0] handTotal; // <-- these are mixing styles too
reg blackJack;
reg bust;
...
module clock(
input clk, reset,
output reg vgaclk
);
...
module checkBust (
input clk,
input [7:0] handTotal,
output reg bust,
output reg blackJack
);
...
always @(posedge clk) begin
if (reset) begin
hand <= 8'h0;
end
if (addCard == 1) begin
hand <= hand + card;
end
end
always @(*) begin
if (plbust == 1)
pllose <= 1;
else if (plbj == 1)
plwin <= 1;
else if (dlbust == 1)
plwin <= 1;
end