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

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

FPGAの部屋

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

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

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

今回は、ピクセルの読み込み、ピクセルの書き込みで memcpy() を使った実装を試してみた。まずは、if 文を使って、最初に1ライン分ピクセルを読み込んで、最後に1ライン分のラプラシアンフィルタ処理結果を書き出す方法でやってみる。lap_filter_axim() のみのC++ソースコードを示す。

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<3, 3, int> mbuf;
    int x, y;
    int val;
    int gray_pix;
    int i, j;
    const int lap_weight[3][3] = {{-1, -1, -1},{-1, 8, -1},{-1, -1, -1}};
#pragma HLS ARRAY_PARTITION variable=lap_weight complete dim=0
    int read_line[HORIZONTAL_PIXEL_WIDTH];
    int write_line[HORIZONTAL_PIXEL_WIDTH];

    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (x == 0) // 1 行 Read
                memcpy(read_line, (const int*)&cam_fb[y*(HORIZONTAL_PIXEL_WIDTH)], (HORIZONTAL_PIXEL_WIDTH)*sizeof(int));

            mbuf.shift_left();  // mbuf の列を1ビット左シフト
            mbuf.insert(linebuf(1,x), 2, 2);
            mbuf.insert(linebuf(0,x), 1, 2);
            gray_pix = conv_rgb2y(read_line[x]);
            mbuf.insert(gray_pix, 0, 2);

            // 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)
                write_line[x] = (val<<16)+(val<<8)+val ;
            else
                // x<2 || y<2 の場合はピクセルデータがまだ揃っていないので0にする
                write_line[x] = 0;
            // printf("x = %d  y = %d", x, y);

            if (x == (HORIZONTAL_PIXEL_WIDTH-1))
                memcpy((void *)&lap_fb[y*(HORIZONTAL_PIXEL_WIDTH)], (const int*)write_line, (HORIZONTAL_PIXEL_WIDTH)*sizeof(int));
        }
     }
     return(0);
}


if 文を使って、最初に1ライン分ピクセルを読み込んで、最後に1ライン分のラプラシアンフィルタ処理結果を書き出している。

HDLへ合成してみた。
LineBuffer_Window_27_160318.png

LineBuffer_Window_28_160318.png

Latency は 24587 ~ 688225 クロックだった。BRAM_18Kを2つ使っている。

Analysis表示にしてみた。
LineBuffer_Window_29_160318.png

C26 までで27ステートある。
リソース表示を示す。
LineBuffer_Window_30_160318.png

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

Latency は 253456 だった。
C/RTL コシミュレーション波形を示す。
LineBuffer_Window_32_160318.png

拡大した波形を示す。
LineBuffer_Window_33_160318.png

Read間隔を図ってみた。 52 us だった。
64 ピクセルでの値なので、1 ピクセル当たりどの位かかっているかを計算してみよう。52 us / 64 ピクセル = 0.8125 us = 812.5 ns だった。
動作周波数は 100 MHz なので、1週期は 10 ns だ。1 クロックで 1 ピクセル処理できると、10 ns で 1 ピクセルを処理できるはずなので、現在の結果はそれに比べて 81 倍程度、時間がかかっていることになる。

次に、内側の for ループに PIPELINE II=1 ディレクティブを追加してやってみる。
LineBuffer_Window_34_160318.png

HDLへ合成を行った。
LineBuffer_Window_35_160318.png

LineBuffer_Window_36_160318.png

Latency は 200977 に減った。BRAM_18K は 4 に増えた。DSP は何故か 9 から 5 に減った。FF と LUT は増えた。

Analysis 表示を示す。
LineBuffer_Window_37_160318.png

C154 で 155 ステートに激増した。これだと、LUT も FF も増えるはず。。。

リソース表示を示す。
LineBuffer_Window_38_160318.png

C/RTL コシミュレーションの波形を示す。
LineBuffer_Window_40_160318.png

拡大した波形を示す。
LineBuffer_Window_41_160318.png

Read間隔を図ってみた。 42 us だった。
64 ピクセルでの値なので、1 ピクセル当たりどの位かかっているかを計算してみよう。42 us / 64 ピクセル = 0.656 us = 65.6 ns だった。
動作周波数は 100 MHz なので、1週期は 10 ns だ。1 クロックで 1 ピクセル処理できると、最高の性能だと、10 ns で 1 ピクセルを処理できるはずなので、現在の結果はそれに比べて 65.6 倍時間がかかっていることになる。

今回の結果を見ると、このC++ソースコードは遅くて使えないかな?と思う。次回はまた違う実装を試してみよう。
  1. 2016年03月19日 08:17 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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