FC2カウンター FPGAの部屋 CORE Generatorで作った分散RAMの同期FIFOのシミュレーション
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

CORE Generatorで作った分散RAMの同期FIFOのシミュレーション

CORE Generatorで分散RAM(SLICEM)の同期FIFOを生成1”、”CORE Generatorで分散RAM(SLICEM)の同期FIFOを生成2”で作った同期FIFOをシミュレーションして、どのような動作をするのかを確かめてみた。

まずは、テストベンチを下に示す。

`timescale 100ps / 1ps
module cmd_sync_fifo_tb;

    parameter CLK_PERIOD = 150;

    // Inputs
    reg clk;
    reg srst;
    reg [31:0] din;
    reg wr_en;
    reg rd_en;

    // Outputs
    wire [31:0] dout;
    wire full;
    wire almost_full;
    wire overflow;
    wire empty;
    wire almost_empty;
    wire underflow;
    wire [3:0] data_count;

    integer i;
    
    // Instantiate the Unit Under Test (UUT)
    cmd_sync_fifo uut (
        .clk(clk), 
        .srst(srst), 
        .din(din), 
        .wr_en(wr_en), 
        .rd_en(rd_en), 
        .dout(dout), 
        .full(full), 
        .almost_full(almost_full), 
        .overflow(overflow), 
        .empty(empty), 
        .almost_empty(almost_empty), 
        .underflow(underflow), 
        .data_count(data_count)
    );

    initial begin
        // Initialize Inputs
        srst = 0;
        din = 0;
        wr_en = 0;
        rd_en = 0;

        // Wait 100 ns for global reset to finish
        #1000     srst = 1; // reset
        #1000     srst = 0;
        
        @(posedge clk); 
        #10        rd_en = 1; // なにもFIFOに入っていない時にrd_en=1をしているので、UNDERFLOWが出るはず
        @(posedge clk);
        #10        rd_en = 0;
        @(posedge clk); // 3クロック分Wait
        @(posedge clk);
        @(posedge clk);
        #10        srst = 1; // UNDERFLOW をreset;
        @(posedge clk);
        #10        srst = 0;
        @(posedge clk);
        #10        wr_en = 1; din = 32'h12345678; // 1データ書き込み
        @(posedge clk);
        #10        din = 32'h11223344; // もう1つデータを書き込み
        @(posedge clk);
        #10        wr_en = 0; // 書き込み終了
        @(posedge clk); 
        #10;
        @(posedge clk);
        #10        rd_en = 1; // 1個のデータをRead
        @(posedge clk);
        #10        rd_en = 0;
        @(posedge clk);
        @(posedge clk);
        #10        wr_en = 1; // wr_en を1にして、16個書くとOVERFLOWが出るはず
        for (i=0; i<16; i=i+1) begin
            din <= din +32'h1;
            @(posedge clk);
            #10;
        end

        #1000    $stop;
    end
    
    always begin
       #(CLK_PERIOD/2)    clk = 1'b1 ;
       #(CLK_PERIOD/2)    clk = 1'b0 ;
    end
      
endmodule


最初にemptyの時にrd_enを入れて、Underflowを出そうとしている。リセットしてから、2つデータをWriteしてから、1つReadする。その後で、16回Writeして、Overflowを出させるつもり。
さて、Veritakでプロジェクトを作製してコンパイルし、シミュレーションを走らせる。その結果の波形を下に示す。
sync_fifo_2_100122.png

同期FIFOにデータがないのにrd_enを1にすると、Underflowが1クロック期間1となった(黒いカーソルの所)。emptyが0になったときにデータが出ているのが確認できる。rd_enを1クロック期間1にすると、次のデータが出力される。Overflowを出すために、ひたすらWriteしていくと、data_countが+1されて、データがWriteされる。驚いたことに0x12でfullが1になった。16深度のはずなのに18深度なの?次のクロックでもWriteするとOverflowが1となった。

次に、First-Word Fall-ThroughでないStandard FIFOを選んだ時の同じテストベンチでのシミュレーション結果を下に示す。Standard FIFOは、data_countが最大4ビットとなった。
sync_fifo_1_100121.png

こちらはUnderflowは同じだが、fullはWriteしていくと、data_countが0xfから0になって、その時にfullが1になる。16深度ならば、言わば合理的な仕様かな?次にOverflowが出るので、本当に16深度のようだ。

2つの分散メモリ使用の同期FIFOをシミュレーションしてみて、こんなに違うとは夢にも思わなかった。やはりシミュレーションしてみるもんだと思った。
  1. 2010年01月22日 04:53 |
  2. Core Generator
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/1361-d290dd74
この記事にトラックバックする(FC2ブログユーザー)