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

ポップポインタを少し拡張します。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
于 2013-01-09T19:00:13.430 に答える