FC2カウンター FPGAの部屋 Vivado HLS によるアンシャープマスクキング・フィルタの作製3(固定小数点で実装してみた)

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

FPGAの部屋

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

Vivado HLS によるアンシャープマスクキング・フィルタの作製3(固定小数点で実装してみた)

Vivado HLS によるアンシャープマスクキング・フィルタの作製2(floatで実装してみた)”の続き。

(2015/09/29 : unsharp_masking() が間違っていたので全面的に書き換えました。PRECISION を書き換えることで小数点以下の精度を変更できるようにしました。
2015/10/04:もう一度、
unsharp_masking() を修正しました

前回はfloat でアンシャープマスキング・フィルタを実装してみたが、リソース使用量が 100% を超えてしまって、ZYBOに実装できなかった。今回は float を止めて固定小数点で実装した。
誤差が出るので、エラーになってもリターンしないようにテストベンチを変更した。

鮮鋭化の強さが k = 3.0 だと9を割った商が整数なので、float のアンシャープマスキング・フィルタの結果と固定小数点の結果は同一だ。
unsharp_mask_11_150926.png

鮮鋭化の強さが k = 2.5 だと9を割った商が小数なので、float のアンシャープマスキング・フィルタの結果と固定小数点の結果は誤差が出てしまう。
unsharp_mask_12_150926.png

鮮鋭化の強さが k = 2.5 の時の出力BMPファイル temp_usm.bmp も問題無さそうだ。
unsharp_mask_17_150926.png

なお、小数点以下が 4  だと鮮鋭化の強さが k = 2.5 の時の出力BMPファイル temp_usm.bmp の背景がわずかに灰色に近くなってしまったので、6 を小数点以下の2進数の数とした。

これで、C から HDL へ合成した時の結果を下に示す。
unsharp_mask_13_150926.png

unsharp_mask_14_150926.png

DSP は 22 %、LUT 使用率は 10 % だった。float の時の LUT 使用率は 330 % だったので、1/33 になった。

Anaylsis を見てみた。
unsharp_mask_15_150926.png

unsharp_mask_9_150926.png

こちらも float の時の 114 ステートが 31 ステートになった。

最後に 変更した unsharp_mask_axis.cpp の 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 ビットとする。
//

#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;

    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のいずれかを抽出
            }
        }
        int x1y1 = (9<<(PRECISION+num_adec_k))/k + (8<<PRECISION);

        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);
}

  1. 2015年09月27日 10:13 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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