同期FIFOの作り方

[] [] []


非同期FIFOを作る準備として、ライトとリードが同じクロックで動く同期FIFOを作る。

FPGAにはデュアルポートメモリ(DPM)が備わっているので、ライトとリードを2ポートに割り当てて1ワードをライト/リードする毎にライト/リードアドレス(wadr/radr)をカウントアップすればよい。さらに、リード側から見てデータかあるのか、ライト側から見て書き込む余地があるのかがわかるように、FIFOに溜まっているワード数を数えるカウンタを設ければよい。このとき、ライトとリードが同時に起きた場合を抜かさないことと、FIFOが満杯(full)になったときのためカウンタはアドレスより1ビット大きくしておくことに注意。

◇◇

同期FIFORTL記述は次のようになる。

/* 同期FIFO */

module fifo #(parameter WA=8,WD=16)

    (input  rst          // reset

    ,input  clk          // clock

    ,input  wen          // write enable

    ,input[WD-1:0] wdat  // write data

    ,input  ren          // read enable

    ,output reg[WD-1:0] rdat // read data

    ,output reg[WA:0] count // counter

    );

reg[WA-1:0] wadr;

reg[WA-1:0] radr;

reg[WD-1:0] ram[0:2**WA-1];

/* DPM */

always @(posedge clk) begin

    if(wen) ram[wadr] <= wdat;

    if(ren) rdat <= ram[radr];

end

/* write address */

always @(posedge clk or posedge rst) begin

    if(rst)

        wadr <= {WA{1'b0}};

    else if(wen)

        wadr <= wadr + 1'b1;

end

/* read address */

always @(posedge clk or posedge rst) begin

    if(rst)

        radr <= {WA{1'b0}};

    else if(ren)

        radr <= radr + 1'b1;

end

/* word count */

always @(posedge clk or posedge rst) begin

    if(rst)

        count <= {(WA+1){1'b0}};

    else

        case({wen,ren})

        2'b00: count <= count;

        2'b01: count <= count - 1'b1;

        2'b10: count <= count + 1'b1;

        2'b11: count <= count;

        endcase

end

endmodule


[] [] []