FC2カウンター FPGAの部屋 Vivado HLS によるアンシャープマスクキング・フィルタの作製10(ap_int 型による固定小数点)

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

FPGAの部屋

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

Vivado HLS によるアンシャープマスクキング・フィルタの作製10(ap_int 型による固定小数点)

間に関連の記事は入っているが、一応、”Vivado HLS によるアンシャープマスクキング・フィルタの作製9(C++ の任意精度固定小数点型3)”の続き。

Vivado HLS によるアンシャープマスクキング・フィルタの作製8(C++ の任意精度固定小数点型2)”で、int 型で予め左シフトして小数を整数にして演算するコードを書いた。
今回は、ap_int 型で桁を制限してリソース使用量の低減を図ろうと思う。使用しているVivado HLS のバージョンは、2014.4。

ZYBOのプロジェクトを作って、unsharp_mask_axis.cpp と unsharp_mask_axis.h を ap_int 型に修正した。

unsharp_masking() と unsharp_mask_axis.h を示す。
まずは、unsharp_masking() から。

// アンシャープマスキング・フィルタ
// 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 ビットとする。
// 2015/10/14 : ap_int に変更して、演算のビット幅を最適化する
//

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

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

    y_td 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 = (((y_td)k * y)/(y_td)9) >> num_adec_k; // k は num_adc_k だけ左シフトされているので戻す

        y = y + (y_td)(1<<(PRECISION-1)); // 四捨五入 +0.5
        z = y >> 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);
}


unsharp_mask_axis.h を示す。

// unsharp_mask_axis.h
// 2015/09/26 by marsee

#ifndef __UNSHARP_MASK_AXIS_H_
#define __UNSHARP_MASK_AXIS_H_

//#define HORIZONTAL_PIXEL_WIDTH    1280
//#define VERTICAL_PIXEL_WIDTH    720

#define HORIZONTAL_PIXEL_WIDTH    64
#define VERTICAL_PIXEL_WIDTH    48

#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define PRECISION    6    // 小数点以下の桁数、精度(0 以上の数を指定する)
#define K_BITLEN    4    // k のビット長
#define NUM_ADC_K    2    // k の小数点の位置

typedef ap_int<6+PRECISION+NUM_ADC_K+8+3> y_td;

#endif


これで、C シミュレーションを行った。
unsharp_mask_75_151014.png

平均2乗誤差も int 型で予め左シフトして小数を整数にして演算した時と同じだ。

次に、C++ から HDL へ合成を行った。結果を示す。
unsharp_mask_76_151014.png

unsharp_mask_77_151014.png

BRAM_18K は 4 個、DSP48E は 24 個、FF は 1489 個、LUT は 1812 個のリソースを消費した。

Vivado HLS によるアンシャープマスクキング・フィルタの作製8(C++ の任意精度固定小数点型2)”で、int 型で予め左シフトして小数を整数にして演算した時のリソース使用量は、
BRAM_18K は 4 個、DSP48E は 18 個、FF は 1462 個、LUT は 1849 個だったので、
LUT は37 個減ったが、FF が 27 個、DSP48E は 6 個増えてしまった。

う~ん。これでは int 型を使ったほうが良さそうだ。
  1. 2015年10月14日 03:57 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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