If statement 如果Else语句产生不正确的结果,请重置

If statement 如果Else语句产生不正确的结果,请重置,if-statement,verilog,If Statement,Verilog,我一直在尝试调试这段代码,但找不到其中的错误。然而,它并没有产生我所期望的结果。代码如下: module countAdd( btn, reset, thousands, hundreds, tens, ones, led); //Port Assignments input [2:0] btn; input reset; output [0:7] thousands, hundreds, tens, ones; output reg led; //Internal

我一直在尝试调试这段代码,但找不到其中的错误。然而,它并没有产生我所期望的结果。代码如下:

module countAdd( btn, reset, thousands, hundreds, tens, ones, led);

  //Port Assignments
  input [2:0] btn;
  input reset;

  output [0:7] thousands, hundreds, tens, ones;
  output reg led;

  //Internal Port Assignments
  reg [15:0] sum;
  wire [15:0] sumBCD;
  reg [15:0] inc;

  //Add some stuff
  always @(btn or reset)
    begin

        //Determine which button is active
        case(btn)
            3'b110: inc <= 1;
            3'b101: inc <= 10;
            3'b011: inc <= 100;
            default: inc <= 0;
        endcase

        //Add
        sum <= sum + inc;

        //Should we reset?
        if(reset)
            begin
                sum <= 0;
                led <= 1;
            end
        else
            begin
                led <= 0;
            end

    end

  //translate sum to sumBCD
  binToBCD translate (sum, sumBCD[15:12], sumBCD[11:8], sumBCD[7:4], sumBCD[3:0]);

  //display results on SS display
  ssFromBCD seg0 (sumBCD[3:0], ones);
  ssFromBCD seg1 (sumBCD[7:4], tens);
  ssFromBCD seg2 (sumBCD[11:8], hundreds);
  ssFromBCD seg3 (sumBCD[15:12], thousands);
endmodule


module binToBCD(sum, thousands, hundreds, tens, ones);
  //Port Assignments
  input [15:0] sum;
  output reg [3:0] thousands;
  output reg [3:0] hundreds;
  output reg [3:0] tens;
  output reg [3:0] ones;

  //Begin conversion
  integer i;
  always @(sum)
    begin
        //set 1000's, 100's, 10's, and 1's to 0
        thousands = 4'd0;
        hundreds = 4'd0;
        tens = 4'd0;
        ones = 4'd0;

        for(i = 15; i >= 0; i=i-1)
            begin
                //Add 3 to columns >= 5
                if(thousands >= 5)
                    thousands = thousands + 3;
                if(hundreds >= 5)
                    hundreds = hundreds + 3;
                if(tens >= 5)
                    tens = tens + 3;
                if(ones >= 5)
                    ones = ones + 3;

                //Shift left ones
                thousands = thousands << 1;
                thousands[0] = hundreds[3];
                hundreds = hundreds << 1;
                hundreds[0] = tens[3];
                tens = tens << 1;
                tens[0] = ones[3];
                ones = ones << 1;
                ones[0] = sum[i];   
            end

    end 
endmodule

module ssFromBCD(in, ssOut);
  //Port Assignments
  input [3:0] in;
  output reg [0:7] ssOut;

  always @(in)
    begin
        case(in)
            4'b0000: ssOut = 8'b00000011;
            4'b0001: ssOut = 8'b10011111;
            4'b0010: ssOut = 8'b00100101;
            4'b0011: ssOut = 8'b00001101;
            4'b0100: ssOut = 8'b10011001;
            4'b0101: ssOut = 8'b01001001;
            4'b0110: ssOut = 8'b01000001;
            4'b0111: ssOut = 8'b00011111;
            4'b1000: ssOut = 8'b00000001;
            4'b1001: ssOut = 8'b00011001;
            default: ssOut = 8'b11111111;
        endcase
    end
endmodule
模块计数添加(btn、复位、千、百、十、一、led);
//港口分配
输入[2:0]btn;
输入复位;
输出[0:7]千、百、十、一;
输出reg led;
//内部端口分配
注册[15:0]和;
电线[15:0]sumBCD;
注册[15:0]公司;
//加些东西
始终@(btn或重置)
开始
//确定哪个按钮处于活动状态
案例(btn)

3'b110:inc这取决于您希望从以下行中得到什么:

always @(btn or reset)
组合逻辑还是顺序(触发器)

组合如果支持SystemVerilog,则使用
始终@*
始终梳
。自动灵敏度列表的作用与组合硬件一样,可以减少模拟不匹配

也可以使用
=
阻塞分配进行组合运算

顺序使用类似于
始终@(posedge clk或negedge rst)
的方法,并使用

此代码没有测试台

首先:创建一个测试台!这并不困难(您甚至可以做到),对于逻辑错误,在模拟中调试要比在真实硬件上迭代快得多

第二:代码中没有时钟。这是顶层吗?FPGA不太擅长异步设计,尤其是当您试图存储状态时(在本例中为
sum
)。现在还不清楚Quartus会推断出什么——它可能已经将您的一个输入连接到了一个时钟网络。您应该在RTL查看器中检查综合设计,并查看综合日志

但是,当我尝试使用三个按钮中的任何一个来增加总和时,会添加一个随机数

您是否正在取消开关输入的抖动?如果你没有,那么很可能每次按下按钮都会得到随机数目的切换

请注意,您的敏感度列表在此不正确-它还应包括
sum

always @(btn or reset)

具有讽刺意味的是(鉴于我的开场白),这不会影响合成,但会改变模拟中的行为。您最好使用
始终梳
(或
始终(*)如果您一直使用Verilog)。

显示一个随机数,因为
总和
不断递增,而
btn
正在改变状态。清晰的起点和终点必须明确

尝试使用时钟对btn进行采样。在组合块中,分配
inc
。如果
pass_btn
等于
btn
,则将
inc
赋值为零<代码>总和
应在时钟块中分配

alwasy @* begin
 if (past_btn == btn) inc = 'b0;
 else begin
   // case(btn) ...
 end
end

always @(posedge clk) begin
  past_btn <= btn;
  if (!reset)  sum <= 'b0;
  else         sum <= sum + inc;
end
alwasy@*开始
如果(过去的时间==btn)inc='b0;
否则开始
//案例(btn)。。。
终止
终止
始终@(posedge clk)开始

过去的时间应该是连续的。我最初有一个
sum=sum+inc
,但当时也不起作用。我切换它只是为了看看它是否有任何影响。最终,这个项目将有一个时钟。事实上,它应该每秒钟递增一次,只要按钮和它的关联值处于活动状态。在我加上一个时钟之前,我一直想让它工作。不过我会试试你的建议。这块板上的按钮已经脱落了。我试试加一个钟。
always @(btn or reset)
alwasy @* begin
 if (past_btn == btn) inc = 'b0;
 else begin
   // case(btn) ...
 end
end

always @(posedge clk) begin
  past_btn <= btn;
  if (!reset)  sum <= 'b0;
  else         sum <= sum + inc;
end
alwasy @* begin
 if (past_btn == sync_btn) inc = 'b0;
 else begin
   // case(sync_btn) ...
 end
end

always @(posedge clk) begin
  sync_btn <= btn;
  past_btn <= sync_btn;
  if (!reset)  sum <= 'b0;
  else         sum <= sum + inc;
end