FC2カウンター FPGAの部屋 Vivado HLS の任意精度固定小数点型を使用した内積の計算

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

FPGAの部屋

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

Vivado HLS の任意精度固定小数点型を使用した内積の計算

今回は、配列の内積をVivado HLS の任意精度固定小数点型を使用して計算してみようと思う。浮動小数点数の計算値と比較してみよう。

Vivado HLS の任意精度固定小数点型を使用した配列の内積を計算するVivado HLS 2017.1 のプロジェクトを示す。
ap_fixed_dot_1_170601.png

nn_test.h を示す。

// nn_test.h
// 2017/05/31 by marsee
//

#ifndef __NN_TEST_H__
#define __NN_TEST_H__

#include <ap_fixed.h>

const ap_fixed<91, AP_TRN_ZERO, AP_SAT> wt[3][4]={
    {-0.10.2, -0.30.4},
    {-0.50.6, -0.70.8},
    {-0.20.4, -0.50.6}
};

const ap_fixed<91, AP_TRN_ZERO, AP_SAT> b[4] ={
    -0.10.4, -0.30.5
};

#endif


nn_test.cpp を示す。

// nn_test.cpp
// 2017/05/29 by marsee
//

#include <stdio.h>
#include "nn_test.h"

int nn_test(ap_ufixed<80, AP_TRN_ZERO, AP_SAT> in[3], ap_fixed<135, AP_TRN_ZERO, AP_SAT> out[4]){
    ap_fixed<135, AP_TRN_ZERO, AP_SAT> dot[4];

    Loop1: for(int j=0; j<4; j++){
        dot[j] = 0;
        Loop2: for(int i=0; i<3; i++){
            dot[j] += in[i]*wt[i][j];
        }
        dot[j] += b[j];
        out[j] = dot[j];
    }

    return(0);
}


nn_test_tb.cpp を示す。

// nn_test_tb.cpp
// 2017/05/29 by marsee
//

#include <stdio.h>
#include "nn_test.h"

int nn_test(ap_ufixed<80, AP_TRN_ZERO, AP_SAT> in[3], ap_fixed<135, AP_TRN_ZERO, AP_SAT> out[4]);
int nn_test_soft(ap_ufixed<80, AP_TRN_ZERO, AP_SAT> in[3], ap_fixed<135, AP_TRN_ZERO, AP_SAT> out[4]);

int main(){
    ap_ufixed<80, AP_TRN_ZERO, AP_SAT> in[3] = {0.3906250.58593750.78125};
    ap_fixed<135, AP_TRN_ZERO, AP_SAT> out[4];
    ap_fixed<135, AP_TRN_ZERO, AP_SAT> out_soft[4];

    nn_test(in, out);
    nn_test_soft(in, out_soft);

    for(int i=0; i<4; i++){
        if(out[i] != out_soft[i]){
            printf("ERROR HW and SW results mismatch i = %d, HW = %f, SW = %f\n", i, (float)out[i], (float)out_soft[i]);
        }else{
            printf("out[%d] = %f\n", i, (float)out[i]);
        }
    }

    return(0);
}

int nn_test_soft(ap_ufixed<80, AP_TRN_ZERO, AP_SAT> in[3], ap_fixed<135, AP_TRN_ZERO, AP_SAT> out[4]){
    ap_fixed<135, AP_TRN_ZERO, AP_SAT> dot[4];

    for(int j=0; j<4; j++){
        dot[j] = 0;
        for(int i=0; i<3; i++){
            dot[j] += in[i]*wt[i][j];
        }
        dot[j] += b[j];
        out[j] = dot[j];
    }

    return(0);
}


C シミュレーションを行った。結果を示す。
ap_fixed_dot_2_170601.png

out[] の値を示す。
out[0] = -0.578125
out[1] = 1.128906
out[2] = -1.207031
out[3] = 1.582031

Vivado HLS の任意精度固定小数点型をそっくりそのまま float 型で実装したVivado HLS プロジェクトの結果を示す。
ap_fixed_dot_3_170601.png

out[] の値を示す。
out[0] = -0.588281
out[1] = 1.142187
out[2] = -1.217969
out[3] = 1.593750

このコードで本当に配列の内積が計算できているか?を調べるために、maxima で配列の内積を計算した。
ap_fixed_dot_4_170601.png

その結果 float 型で計算したVivado HLS のプロジェクトの値は、maxima で計算した値にほぼ等しい。
Vivado HLS の任意精度固定小数点型はやはり固定小数点なので、誤差があるが、おおむね値は合っていそうだ。

Vivado HLS の任意精度固定小数点型のVivado HLS プロジェクトで、C コードの合成を行った。
ap_fixed_dot_5_170601.png

全く指示子を与えていないので、デフォルトの状態になっている。

C/RTL協調シミュレーションを行った。
ap_fixed_dot_6_170601.png

C/RTL協調シミュレーションの波形を示す。
ap_fixed_dot_7_170601.png

このように、Vivado HLS の任意精度固定小数点型で書くと、固定小数点数のビット長や固定小数点位置が違っても、うまく計算してくれる。とっても便利だ。
うまく計算してくれるのは、以前のやった結果からわかってはいたのだが、もう一度、確認するためにやってみた。
  1. 2017年06月01日 04:05 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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