Verilog wires被设置为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

我目前正在用verilog编写一个21点游戏,包括游戏逻辑和计分等几个模块。我的项目的目标是通过VGA和nexys3 FPGA板在屏幕上显示21点游戏。在设置VGA之前,我需要确保我的游戏逻辑正常工作,并正确设置玩家手牌和玩家分数。不幸的是,玩家的手牌设置不正确,显示的X值应该是1。下面是我所有的模块和代码,底部是我正在运行的模拟:

这是调用我的其他模块的主模块

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