FC2カウンター FPGAの部屋 Vivado HLS 2016.4 でUNROLL指示子を試してみた

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

FPGAの部屋

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

Vivado HLS 2016.4 でUNROLL指示子を試してみた

Vivado HLS 2016.4 でUNROLL指示子を試してみた。

UNROLL指示子については、Vivado HLS のユーザーズガイド、”高位合成 UG902 (v2016.4) 2016 年 11 月 30 日”の 133 ページの”最適なループ展開によるパイ プ ラ イ ンの改善”を参考にした。

まずは、134 ページの”図 1‐60: ループの展開”がUNROLL指示子の説明の図となっている。その図を引用する。引用した図にわかりやすいように軸を付け加えさせて頂いた。
unroll_test_1_170218.png

ラプラシアンフィルタの実装による UNROLL 指示子の効果について調べてみよう。まずは、すべての要素を足し算するだけの簡単な 3 x 3 のフィルタを AXI4-Stream で実装した。その unroll_test.cpp を示す。

// unroll_test.cpp
// 2017/02/17 by marsee
//

#include <hls_stream.h>

#define HORIZONTAL_PIXEL_WIDTH 5
#define VERTICAL_PIXEL_WIDTH 5

int unroll_test(hls::stream<int>& ins, hls::stream<int>& outs){
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE axis register both port=outs
#pragma HLS INTERFACE axis register both port=ins
    int pix;
    int usm;

    int line_buf[2][HORIZONTAL_PIXEL_WIDTH];
#pragma HLS array_partition variable=line_buf block factor=2 dim=1
#pragma HLS resource variable=line_buf core=RAM_2P

    int pix_mat[3][3];
#pragma HLS array_partition variable=pix_mat complete

    Loop_y : for (int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        Loop_x : for (int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
//#pragma HLS PIPELINE II=1
            ins >> pix;

            Loop_i : for (int i=0; i<3; i++){
//#pragma HLS UNROLL factor=3
                Loop_j : for (int j=0; j<2; j++){
//#pragma HLS UNROLL factor=2
                    pix_mat[i][j] = pix_mat[i][j+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];

            pix_mat[2][2] = pix;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = pix;
        }
        usm = pix_mat[0][0] + pix_mat[0][1] + pix_mat[0][2]
            + pix_mat[1][0] + pix_mat[1][1] + pix_mat[1][2]
            + pix_mat[2][0] + pix_mat[2][1] + pix_mat[2][2];

        outs << usm;
    }
    return(0);
}


Vivado HLS 2016.4 の unroll_test プロジェクトを示す。
unroll_test_2_170218.png

合成結果を示す(図A)。
unroll_test_3_170218.png

Latency が 416 クロックかかっている。内訳はLoop に示されている。Loop_y, Loop_x, Loop_i, Loop_j が表示されていて、UNROLL されいていないのがわかる。

次に、Loop_j の「#pragma HLS UNROLL factor=2」を生かした。
どうも、Vivado HLS 2016.4 では、factor を書かないとまずいようだ。ディレクティブ・エディタで修正できない。不正だと言われてしまう。
unroll_test_6_170218.png

合成結果を示す(図B)。
unroll_test_7_170218.png

UNROLL指示子を全く入れていない時(図A)に比べてLatency が 416 クロックのところ、191 クロックに縮小した。Loop を見ると Loop_j が展開されて無くなっている。

次に、Loop_i の「#pragma HLS UNROLL factor=3」を生かした。
unroll_test_8_170218.png

合成結果を示す(図C)。
unroll_test_9_170218.png

Loop_j も無くなって、Latency が図B の 191 クロックから 66 クロックに縮小した。Loop を見ると、Loop_j も無くなっている。

Loop_x にPIPELINE 指示子の「#pragma HLS PIPELINE II=1」を入れた。
unroll_test_10_170218.png

合成結果を示す(図D)。
unroll_test_11_170218.png

Latency が 29 クロックに縮小した。Loop を見ても Loop_y_Loop_x になっている。

最後に、Loop_j と Loop_i の UNROLL 指示子をコメントアウトした。
unroll_test_12_170218.png

合成結果を示す(図E)
unroll_test_13_170218.png

図D と同じになった。

つまり、この状況では、PIPELINE 指示子を入れれば下の for ループが展開されるようだ。つまり、PIPELINE 指示子の下にはUNROLL指示子は要らないということになる。
  1. 2017年02月18日 15:20 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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