我的堆栈(LIFO)内存溢出并阻止进一步读取内存

时间:2012-12-24 19:04:50

标签: stack verilog fpga

我一直致力于编写简单的堆栈内存。它有4个地址位,因此可以存储16个元素。一切正常,但问题是,当所有16个内存元素都被写入时,跟踪内存位置的计数器溢出并将其重置为0000.我无法找到原因。我的所有寄存器都是正确的宽度。

reg_pushreg_pop一起递增和递减,这些是跟踪内存位置的寄存器。

这是显示溢出的模拟。 stack simulation

以下是代码:

module stack # (parameter dbits = 3, abits = 4)(
input clock,
input reset,
input push,
input pop,
input [dbits-1:0] din,
output [dbits-1:0] dout,
output full,
output empty
);

reg [dbits-1:0] regarray[2**abits-1:0]; //number of words in fifo = 2^(number of address bits)
reg [abits-1:0] reg_push, reg_pop, next_push, next_pop;
reg full_reg, empty_reg, full_next, empty_next;
reg [dbits-1:0] out;
wire wr_en;

wire db_push, db_pop;
reg dffpop1, dffpop2, dffpush1, dffpush2;

always @ (posedge clock) dffpush1 <= push; 
always @ (posedge clock) dffpush2 <= dffpush1;

assign db_push = ~dffpush2 & dffpush1; //monostable multivibrator to detect only one pulse of the button

always @ (posedge clock) dffpop1 <= pop;
always @ (posedge clock) dffpop2 <= dffpop1;

assign db_pop = ~dffpop2 & dffpop1; //monostable multivibrator to detect only one pulse of the button

assign wr_en = db_push & ~full; //only push if write signal is high and stack is not full

//always block for write operation
always @ (posedge clock)
    if(wr_en) regarray[reg_push] = din;

//always block for read operation   
always @ (posedge clock)
begin
    if(db_pop)
        out <= regarray[reg_pop];
end


always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin
            full_reg <= 0;
            empty_reg <= 1;
            reg_push <= 0;
            reg_pop <= 0;
        end
    else
        begin
            full_reg <= full_next;//created the next registers to avoid the error of mixing blocking and non blocking assignment to the same signal
            empty_reg <= empty_next;
            reg_push <= next_push;
            reg_pop <= next_pop;
        end
end

always @ (*)
begin
    full_next = full_reg; //default values stay the same
    empty_next = empty_reg;
    next_push = reg_push;
    next_pop = reg_pop;

    if(db_push)
    begin
        if(~full) //if stack is not full continue
        begin
            empty_next = 0;
            next_push = reg_push + 1;
            next_pop = reg_pop + 1;
            if(reg_push == (2**abits - 1)) full_next = 1; //all registers have been written to
        end
    end

    else if (db_pop)
    begin
        if(~empty) //if stack is not empty continue
        begin
            full_next = 0;
            next_pop = reg_pop - 1;
            next_push = reg_push - 1;
            if(reg_pop == 0) empty_next = 1; //all data has been read
        end
    end
end


assign full = full_reg;
assign empty = empty_reg;
assign dout = out;

endmodule

现在如果我使用此堆栈而不使其达到其全部容量,它将完美地工作。只有在我将所有16个元素存储到其中时才会出现问题。

1 个答案:

答案 0 :(得分:1)

将弹出指针延长一点。 一个4位寄存器只能存储一个0到15的值。任何高于该值的值都将忽略高位,有效地执行mod 16.因此,赋值16将导致0。

选项1:扩展为5位寄存器:

尝试更改:

reg [abits-1:0] reg_push, reg_pop, next_push, next_pop;

要:

reg [abits:0] reg_push, reg_pop, next_push, next_pop;

选项2:使用full_reg是评估中的第5位:

变化:

if(reg_push == (2**abits - 1)) full_next = 1; //all registers have been written to
...
if(reg_pop == 0) empty_next = 1; //all data has been read

要:

if({full_reg,reg_push} >= (2**abits - 1)) full_next = 1; //all registers have been written to
...
if({full_reg,reg_pop} == 0) empty_next = 1; //all data has been read