論理回路デザイン
ArchiTek home page
SRAMを使用したFIFO

先行したデータ取得

コード(RTL)

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2011, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

module fifo (
        iVld,
        iStall,
        iData,

        oVld,
        oStall,
        oData,

        reset,
        clk

        );

// ************************ PARAMETER DECLARATIONS *****************************

        parameter               W       = 32;           // Data Length
        parameter               DR      = 2;            // Depth Radix

        parameter               D       = 1<<DR;

// *************************** I/O DECLARATIONS ********************************

        input                   iVld;
        output                  iStall;
        input   [W-1:0]         iData;

        output                  oVld;
        input                   oStall;
        output  [W-1:0]         oData;

        input                   reset;
        input                   clk;

// ************************** LOCAL DECLARATIONS *******************************

        reg                     iStall;
        wire                    iStallD;

        reg                     oVld;
        wire                    oVldD;

        reg     [DR:0]          iPtr;
        wire    [DR:0]          iPtrD;

        reg     [DR:0]          oPtr;
        wire    [DR:0]          oPtrD;

        reg     [W-1:0]         oData;
        reg     [W-1:0]         lData;
        reg                     ramHD;

        // SRAMポートを定義、SRAMをモジュール外に置く場合は外部ポートに変更
        wire                    ramWE;
        wire    [DR-1:0]        ramWA;
        wire    [W-1:0]         ramWD;
        wire                    ramRE;
        wire    [DR-1:0]        ramRA;
        wire    [W-1:0]         ramRD;

        wire                    iAlloc          = iVld & !iStall;
        wire                    oAlloc          = oVld & !oStall;

// ****************************** MODULE BODY **********************************

// -----------------------------------------------------------------------------
// Data FIFO
// FIFOが空の場合は入力データが直接、そうでない場合はポインタの衝突信号を見てラッチ
always @(posedge clk)
        if (iAlloc & (iPtr[DR-1:0] == oPtrD[DR-1:0]))
                oData           <= #1 iData;
        else if (!oStall)
                oData           <= #1 ramHD ? ramRD : lData;

// 入力データを一旦FF受け(衝突時のみ)
always @(posedge clk)
        if (!ramRE)
                lData           <= #1 iData;

// ポインタの非衝突を保持
always @(posedge clk)
        if (reset)
                ramHD           <= #1 1'b0;
        else
                ramHD           <= #1 ramRE;

assign ramWE            = iAlloc;
assign ramWA            = iPtr[DR-1:0];
assign ramWD            = iData;
// Read Enableが非衝突を示し、衝突時はReadをしない
// 衝突はFIFOが空の場合にしか発生しないので、SRAMに格納しなくても取りこぼしはない
assign ramRE            = !ramWE | (ramWA != ramRA);
// ポインタを1つ先行してReadする
assign ramRA            = oPtrD[DR-1:0] + 1'b1;

// 2ポートSRAMをコール、モジュール名は説明のため簡単化
dualSRAM #(W, DR) sram_0 (
        .WE             (ramWE),
        .WA             (ramWA),
        .WD             (ramWD),
        .RE             (ramRE),
        .RA             (ramRA),
        .RD             (ramRD),
        .CK             (clk)
        );

// -----------------------------------------------------------------------------
// Data FIFO Pointer
// これ以降の記述は従来と変わらず
always @(posedge clk)
        if (reset) begin
                iStall          <= #1 1'b0;
                oVld            <= #1 1'b0;
        end
        else begin
                iStall          <= #1 iStallD;
                oVld            <= #1 oVldD;
        end

always @(posedge clk)
        if (reset) begin
                iPtr            <= #1 {DR+1{1'b0}};
                oPtr            <= #1 {DR+1{1'b0}};
        end
        else begin
                iPtr            <= #1 iPtrD;
                oPtr            <= #1 oPtrD;
        end

assign iStallD          = (iPtrD[DR] != oPtrD[DR])
                        & (iPtrD[DR-1:0] == oPtrD[DR-1:0]);

assign oVldD            = (iPtrD != oPtrD);

assign iPtrD            = iPtr + iAlloc;
assign oPtrD            = oPtr + oAlloc;

// ************************** FUNCTIONS and TASKS ******************************

endmodule

// *****************************************************************************
          

回路デザイン > 設計例 [FIFO] > >SRAMを使用したFIFO    次のページ(非同期FIFO)   このページのTOP ▲

[1]
2ポートSRAMモデルを参照して下さい。
[2]
排他的なアクセスが約束されている、もしくは1/2にスループットが落ちてもいいならSingleポートSRAMも使えます。