问题描述
我正在尝试使用推送/弹出信号编写一个深度为 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块中到处使用非阻塞赋值
- 出于某种原因,由于“索引
所以,这是我重新编写的代码:
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)