Verilog if语句不一致

Verilog if statement inconsistency

我正在尝试使用 push/pop 信号编写一个深度为 8 的简单 4 位堆栈,但它的行为方式非常奇怪。我的一个 if 语句工作正常,而另一个根本没有 运行。这是我的代码:

module Stack_8x4(
    input wire clk,
    input wire reset,
    input wire push,
    input wire pop,
    input wire [3:0] data_in,
    output reg [3:0] data_out,
    output reg empty,
    output reg full
    );
    
    reg [3:0] index;
    reg [3:0] stack [7:0];
    
    always @(posedge reset) begin
        index <= -1;
        data_out = 4'd0;
        empty = 1;
        full = 0;
    end
    always @(posedge clk) begin
        if (push & !pop) begin
            empty = 0;
            if(!full) begin
                index = index + 1;
                stack[index] = data_in;
                if(index > 6) full = 1;
            end
        end
        if (pop & !push) begin
            full = 0;
            if(!empty) begin
                data_out = stack[index];
                index = index - 1;
                if(index < 0) empty= 1;
            end else data_out = 0;
        end
    end
endmodule

可以看到,push和pop的逻辑几乎是一样的。我的问题是为什么 if(index < 0) empty= 1; 行不工作而 if(index > 6) full = 1; 工作得很好?

这里有一个测试平台和模拟来了解更多细节:

module sim();

reg clk;
reg reset;
reg push;
reg pop;
reg [3:0] data_in;
wire [3:0] data_out;
wire full;
wire empty;
//wire [3:0]i;

always begin
clk = 0;
#5
clk = 1;
#5
clk = 0;
end

initial begin
// setup
reset = 1;
push = 0;
pop = 0;
data_in = 0;
#10
reset = 0;

// idle
#20

// push 1, 2, 3, 4, 5, 6, 7, 8, 9 to fill the module and test for idling at full
push = 1;
data_in = 1;
#10
data_in = 2;
#10
data_in = 3;
#10
data_in = 4;
#10
data_in = 5;
#10
data_in = 6;
#10
data_in = 7;
#10
data_in = 8;
#10
data_in = 9;
#10
data_in = 10;
#10
data_in = 11;
#10
pop = 1;
#10
push = 0;
#30
pop = 0;
push = 1;
#30
push = 0;
#20
pop = 1;
// pop
//pop = 1;

end

Stack_8x4 S (
    .clk(clk),
    .push(push),
    .pop(pop),
    .reset(reset),
    .data_in(data_in),
    .data_out(data_out),
    .full(full),
    .empty(empty)
);

endmodule

您的主要问题是尝试将带符号的数据与无符号变量一起使用。因此, index <= -1;index < 0 并没有像您预期的那样工作。我的建议是忘记带符号的算术而只做无符号的。

其他问题:

  1. 您应该只使用一个 always 块来进行重置和非重置工作。
  2. 你应该在你的 always @posedge
  3. 中的任何地方使用非阻塞赋值
  4. 出于某种原因,由于 'index < 6'.
  5. ,您没有在堆栈 (6, 7) 中使用 2 个元素

所以,这是我重新编写的代码:

   always @(posedge clk) begin
      if (reset) begin
         index <= 0;
         data_out <= 4'd0;
         empty <= 1;
         full <= 0;
      end      
      else if (push & !pop) begin
          if(index < 8) begin
            full<= 0;
            stack[index] <= data_in;
            index <= index + 1;
         end
         else 
           full <= 1;
      end
      else if (pop & !push) begin
         if(index == 0) begin
            empty <= 1;
            data_out <= 0;
         end
         else begin
            empty <= 0;
            index <= index - 1;
            data_out <= stack[index];
         end
      end // if (pop & !push)
   end // always @ (posedge clk)