FC2カウンター FPGAの部屋 2019年08月24日
FC2ブログ

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

FPGAの部屋

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

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る5

Vivado HLS で 2 つの引数から DMA Read する AXI4 Master モジュールを作る4”の続き。

前回は、x と y を構造体で表現したコードをチューニングしたが、1 クロックで 1 出力まではチューニングすることができなかった。今回は、32 ビット幅のDMA トランザクションの中で、フィールドを自分で決めて x と y を配置する形態でチューニングをしてみよう。

今回の sum_of_squares.cpp を示す。今回は、 ap_int<32> を使用している。
ap_int<32> の中から x と y の ap_int<8> の 8 ビット幅を切り出して、 ap_int<8> でキャストしている。

#include <ap_int.h>

int sum_of_squares(volatile ap_int<32> *xy, volatile ap_int<32> *result){
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave
    ap_int<8> x, y;

    for(int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
        ap_int<16> xyt = xy[i];

        x = (ap_int<8>)(xyt & 0xff);
        y = (ap_int<8>)((xyt & 0xff00)>>8);

        result[i] = x * x + y * y;
    }

    return(0);
}


テストベンチの sum_of_squares_tb.cpp を示す。

// sum_of_squares_tb.cpp

#include <iostream>
#include <ap_int.h>

int sum_of_squares(volatile ap_int<32> *xy, volatile ap_int<32> *result);

int main(){
    ap_int<32> xy[10];
    ap_int<32> result[10];

    for(int i=0; i<10; i++){
        xy[i] = i;
        xy[i] += (ap_int<32>)((i+1)<<8);
    }

    sum_of_squares(xy, result);

    for(int i=0; i<10; i++){
        std::cout << "x[" << i << "]= " << i <<
                ", y[" << i << "] = " << i+1 <<
                ", result[" << i << "] = " <<
                result[i] << std::endl;
    }
}


sum_of_squares_28_190821.png

C シミュレーションを行った。
sum_of_squares_29_190821.png

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

Initiation Interval の achieved が 1 クロックで良さそう。

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

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

DMA Read 、 DMA Write 共にバーストできていて良い感じだし、Latency も小さい。
これが良さそうだと思う。

最後におまけで、C++ でな無く、 C で書いたサンプル・プログラムを示す。

#include <ap_cint.h>

typedef struct xy_struct{
    int8 x;
    int8 y;
} xy_st;

int sum_of_squares(volatile xy_st *xy, volatile int *result){
#pragma HLS DATA_PACK variable=xy
#pragma HLS INTERFACE m_axi depth=10 port=xy offset=slave
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=10 port=result offset=slave

    for(int i=0; i<10; i++){
        result[i] = xy[i].x * xy[i].x + xy[i].y * xy[i].y;
    }

    return(0);
}

  1. 2019年08月24日 05:00 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0