FC2カウンター FPGAの部屋 2017年02月15日

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

FPGAの部屋

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

Vivado HLS 2016.4 における assert() 文の効果4(自分で定義した固定小数点)

Vivado HLS 2016.4 における assert() 文の効果3”の続き。

これまでは、任意精度固定小数点型で assert() 文で変数の変域を指定するリソース使用量の低減効果を見てきたが、今回は、任意精度固定小数点型を使用しない自分で定義した固定小数点演算との比較をしてみた。

最初にC ソースコードを示す。これは、int 型を使用して、PRECISION の 6 ビット左シフトを行って小数桁を確保している。最後には 6 ビット右シフトして整数に戻す。

// unsharp_mask_axis.cpp
// 2015/09/24 by marsee
// assertテスト用

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "unsharp_mask_axis.h"

// アンシャープマスキング・フィルタ
// x0y0 x1y0 x2y0 -k   -j  -k
// x0y1 x1y1 x2y1 -k  9+8k -k x 1/9
// x0y2 x1y2 x2y2 -k   -k  -k
//
// k : 鮮鋭化の強さ(固定小数点) , k != 0
// num_adec_k : Kの小数点の位置
// 2015/09/27 : 演算の小数部は num_adec_k*2 ビットとする。
//

#define PRECISION    6    // 小数点以下の桁数、精度(1以上)

int unsharp_masking(int pix_mat[3][3], int k, int num_adec_k)
{
    int y;
    int xy[3][3];
    int result=0;
    int z;

    int x1y1 = (9<<(PRECISION+num_adec_k))/k + (8<<PRECISION);

    for (int i=0; i<=16; i += 8){
        for (int j=0; j<3; j++){
            for (int k=0; k<3; k++){
                xy[j][k] = (pix_mat[j][k] >> i) & 0xff; // RGBのいずれかを抽出
            }
        }

        y = -(xy[0][0]<<PRECISION) -(xy[0][1]<<PRECISION) -(xy[0][2]<<PRECISION)
            -(xy[1][0]<<PRECISION) +x1y1*xy[1][1]         -(xy[1][2]<<PRECISION)
            -(xy[2][0]<<PRECISION) -(xy[2][1]<<PRECISION) -(xy[2][2]<<PRECISION);

        y = ((k * y)/9) >> num_adec_k; // k は num_adc_k だけ左シフトされているので戻す

        z = y + (1<<(PRECISION-1)); // 四捨五入 +0.5
        z = z >> PRECISION; // 小数点以下切り捨て

        if (z<0// 飽和演算
            z = 0;
        else if (z>255)
            z = 255;

        result += z<<i; // i=0 : blue, i=8 : green, i=16 : red
    }

    return(result);
}


プロジェクトを示す。
assert_26_170215.png

C コードの合成結果を示す。
assert_27_170215.png

任意精度固定小数点型で実装したときの assert() 無しに比べて、int 型を使用してシフトで小数を表した時のほうがリソース使用量が多い。それにLatency も長い。

Analysis 結果を示す。
assert_28_170215.png

こちらも、58 ステートで任意精度固定小数点型の38 ステートよりも多い。

次に assert.h をインクルードして、適当な assert() を入れてみた。
assert_29_170215.png

C コードlの合成を行った。
assert_30_170215.png

ものすごくリソース使用量が減った。やはり、assert() が効いているようだ。

Analysis 結果を示す。
assert_31_170215.png

4 ステートになってしまった。

最後に、まともに変域を考えて指定した。
assert_32_170215.png

C コードlの合成を行った。
assert_33_170215.png

元の合成結果と比べて、1353 個が 1291 個に減った。

Analysis 結果を示す。
assert_34_170215.png

58ステートになった。元と変化が無かった。

結果として、自分で定義した固定小数点演算をするよりも任意精度固定小数点型を使ったほうが、リソース使用量が少なかった。更に assert() を使うとリソース使用量が削減できるので、固定小数点を使うときは任意精度固定小数点型を使ったほうが良いと思う。
  1. 2017年02月15日 07:05 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0