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
并没有像您预期的那样工作。我的建议是忘记带符号的算术而只做无符号的。
其他问题:
- 您应该只使用一个 always 块来进行重置和非重置工作。
- 你应该在你的 always @posedge 块
中的任何地方使用非阻塞赋值
- 出于某种原因,由于 'index < 6'.
,您没有在堆栈 (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)
我正在尝试使用 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
并没有像您预期的那样工作。我的建议是忘记带符号的算术而只做无符号的。
其他问题:
- 您应该只使用一个 always 块来进行重置和非重置工作。
- 你应该在你的 always @posedge 块 中的任何地方使用非阻塞赋值
- 出于某种原因,由于 'index < 6'. ,您没有在堆栈 (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)