FC2カウンター FPGAの部屋 hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する3

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

FPGAの部屋

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

hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する3

hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する2”の続き。

今回は、conv_rgb2y() のインスタンス数を削減してどうなるか?を見てみたい。
C++ ソースコードをわずかながら書き換えた。lap_filter_axim() だけを示す。すべてのC++ ソースコードは”hls::LineBufferとhls::Windowでラプラシアンフィルタを実装する1”にある。

int lap_filter_axim(volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS INTERFACE s_axilite port=return

#pragma HLS INTERFACE m_axi depth=3072 port=cam_fb offset=slave bundle=cam_fb
#pragma HLS INTERFACE m_axi depth=3072 port=lap_fb offset=slave bundle=lap_fb

    hls::LineBuffer<2, HORIZONTAL_PIXEL_WIDTH, int> linebuf;
    hls::Window<33int> mbuf;
    int x, y;
    int val;
    int i, j;
    const int lap_weight[3][3] = {{-1, -1, -1},{-18, -1},{-1, -1, -1}};
#pragma HLS ARRAY_PARTITION variable=lap_weight complete dim=0
    int pix, gray_pix;

    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            // 1ピクセル読み出し
            pix = cam_fb[y*HORIZONTAL_PIXEL_WIDTH+x];
            gray_pix = conv_rgb2y(pix);

            mbuf.shift_left();  // mbuf の列を1ビット左シフト
            //mbuf.insert_left(colbuf); // mbuf の列に colbuf[] を代入
            mbuf.insert(linebuf(1,x), 22);
            mbuf.insert(linebuf(0,x), 12);
            mbuf.insert(gray_pix, 02);

            // LineBuffer の更新
            linebuf.shift_down(x);
            linebuf.insert_bottom(gray_pix, x);

            // ラプラシアンフィルタの演算
            for (j=0, val=0; j<3; j++){
                for (i=0; i<3; i++){
                    val += lap_weight[j][i] * mbuf(2-j,i);
                }
            }
            if (val<0// 飽和演算
                val = 0;
            else if (val>255)
                val = 255;

            // ラプラシアンフィルタ・データの書き込み
            if (x>1 && y>1)
                lap_fb[y*HORIZONTAL_PIXEL_WIDTH+x] = (val<<16)+(val<<8)+val ;
            else
                // x<2 || y<2 の場合はピクセルデータがまだ揃っていないので0にする
                lap_fb[y*HORIZONTAL_PIXEL_WIDTH+x] = 0;
            // printf("x = %d  y = %d", x, y);
        }
     }
     return(0);
}


変更点は、conv_rgb2y() の呼び出し位置をピクセルを読んできた時にしたことだ。これによって、ラインバッファに入るピクセルデータは白黒になる。今までは、ラプラシアンフィルタの演算で conv_rgb2y() を呼びまくっていたので、特にリソースは少なくなるかも?と言うことだ。
これで、HDLへの合成を行った。
LineBuffer_Window_15_160316.png

LineBuffer_Window_16_160316.png

特徴的なのは、BRAM_18K が 0 になった。前回と比較すると、DSP48E が 7 から 9 に増えた。FF は減って、LUT は微増だった。

Analysis 表示を示す。
LineBuffer_Window_17_160316.png

C21 までで、1 つステートが増えている。

C/RTL コシミュレーションを行った。
LineBuffer_Window_18_160316.png

Latency は 274,507 で、前回よりも大きい。

C/RTL コシミュレーションの波形を表示した。
LineBuffer_Window_19_160316.png

LineBuffer_Window_20_160316.png

やはり、前回同様、Read は 64 バーストだが、Write はシングル転送となっている。

次に、PIPELINE II=1 ディレクティブを入れてみた。
LineBuffer_Window_21_160317.png

HDL への合成結果を示す。やはり、Latency と Interval は何故か?前回よりも 1 ずつ多い。
LineBuffer_Window_22_160317.png

LineBuffer_Window_23_160317.png

前回と比較すると、BRAM_18K はやはり 0 で、DSP_48E は 28 が 5 だった。やはり、リソースを節約することができている。FF は 2250 に対して、1736 でだいぶ減っている。LUT は 2076 に対して、2101 で微増だった。

C/RTL コシミュレーションを行った。
LineBuffer_Window_24_160317.png

こちらは、前回と同じ Latency の値だった。

C/RTL コシミュレーション波形を見てみよう。
LineBuffer_Window_25_160317.png

LineBuffer_Window_26_160317.png

こちらも前回同様に、Read、Write 共にシングル転送だった。

やはり、特にパイプラインにした時の使用リソースが顕著に減っていたと思う。
  1. 2016年03月17日 05:21 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3420-ca93866b
この記事にトラックバックする(FC2ブログユーザー)