0

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

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

这是显示溢出的模拟。 堆栈模拟

这是代码:

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 个元素都存储到其中时,才会出现问题。

4

1 回答 1

1

Extend your pop pointer an extra bit. A 4-bit register can only store the a value 0 through 15. Any value above that will ignore the upper bits, effectively doing a mod 16. Hence assigning 16 will result in 0.

Option 1: expand to a 5-bit register:

Try changing:

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

To:

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

Option 2: Use full_reg are the 5th bit in evaluations:

Change:

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

To:

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
于 2013-01-09T19:00:13.430 回答