カーネル コーディング ガイドライン - 2020.1 Japanese

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2020-08-20
Version
2020.1 Japanese

システム ベースの C カーネルを開発する基本的なガイドラインは、次のとおりです。

  • hls::streamqdma_axis<D,0,0,0> 型で使用します。qdma_axis 型には、ヘッダー ファイル ap_axi_sdata.h が必要です。
  • パラメーターのデータ型を定義するのに hls::stream が使用されているので、Vitis HLS ツールで axis ストリーミング インターフェイスが推論されます。
  • qdma_axis<D,0,0,0> は、ストリーミング プラットフォームを使用する際、ホストとカーネル間のデータ転送に使用される特殊なクラスで、ホストと通信するストリーミング カーネル インターフェイスでのみ使用され、ほかのカーネルと通信するインターフェイスには使用されません。テンプレートのパラメーター <D> はデータ幅を示します。残りの 3 つのパラメーターは現在のリリースでは使用しないように、0 に設定する必要があります。
  • 次に、入力ストリーム 1 つと出力ストリーム 1 つを含む単純なカーネル インターフェイスのコードを示します。
    #include "ap_axi_sdata.h"
    #include "hls_stream.h"
     
    //qdma_axis is the HLS class for stream data transfer between host and kernel for streaming platform
    //It contains "data" and two sideband signals (last and keep) exposed to the user via class member function. 
    typedef qdma_axis<64,0,0,0> datap;
     
    void kernel_top (
                 hls::stream<datap> &input,
                 hls::stream<datap> &output,
                 ..... , // Other Inputs/Outputs if any                   
                 )
    {
    
       ...
    }
    ヒント: hls::stream 型が定義されているので、Vitis HLS ツールで axis インターフェイスが推論されます。次の INTERFACE プラグマは例として示しており、コードには追加されません。
    #pragma HLS INTERFACE axis port=input
    #pragma HLS INTERFACE axis port=output
  • qdma_axis 型には、カーネル コード内で使用する必要のある 3 つの変数が含まれます。
    data
    qdma_axis 型には ap_int <D> が含まれますが、これには .get_data() および .set_data() メソッドでアクセスする必要があります。
    • D は 8、16、32、64、128、256、または 512 ビット幅である必要があります。
    last
    last 変数は入力ストリームおよび出力ストリームの最後の値を示します。入力ストリームから読み出されると、last でストリームの終了が検出されます。同様に、カーネルがホストに転送される出力ストリームを書き込む際にも、last を設定してストリームの終了を示す必要があります。
    • get_last/set_last: ストリームの最後のデータを示すのに使用される last 変数を取得および設定します。
    keep
    keep は、特殊な状況で、最後のデータのバイト数を切り捨てるために使用されます。ただし、keep はストリームの最後のデータ以外には使用できません。そのため、ほとんどの場合、カーネルからのすべての出力データで keep を 1 に設定する必要があります。
    • get_keep/set_keep: keep 変数を取得/設定します。
    • 最後のデータの前のデータすべてで keep を 1 に設定し、データのすべてのバイトが有効であることを示す必要があります。
    • 最後のデータでは、カーネルで少ないバイトを送信できます。たとえば、4 バイトを転送する際、次の set_keep() 関数を使用すると、最後のデータで 1 バイト、2 バイト、または 3 バイトを送信できます。
      • 最後のデータが 1 バイト ≥ .set_keep(1)
      • 最後のデータが 2 バイト ≥ .set_keep(3)
      • 最後のデータが 3 バイト ≥ .set_keep(7)
      • 最後のデータが 4 バイト (last 以外のデータと同様) ≥ .set_keep(-1)
  • 次のコードは、input ストリームがどのように読み込まれるかを示します。.last により、最後のデータが決定されます。
    // Stream Read
    // Using "last" flag to determine the end of input-stream
    // when kernel does not know the length of the input data
     hls::stream<ap_uint<64> >   internal_stream;
     while(true) {
            datap temp = input.read(); // "input" -> Input stream
            internal_stream << temp.get_data();  // Getting data from the 
    		stream
            if(temp.get_last())  // Getting last signal to determine the 
    		EOT (end of transfer). 
                break;
     }
  • 次のコードは、output ストリームがどのように書き出されるかを示します。set_keep はすべてのデータで -1 に設定されています。カーネルは、set_last() を使用してストリームの最後のデータを指定しています。
    重要: ホストおよびカーネル システムが正しく機能するようにするため、last ビットを設定してください。
    // Stream Write
    for(int j = 0; j <....; j++) {
          datap t;
          t.set_data(...);
          t.set_keep(-1);        // keep flag -1 , all bytes are valid
          if(... )               // check if this is last data to be write
             t.set_last(1);      // Setting last data of the stream
          else
             t.set_last(0);
          output.write(t);  	 // output stream from the kernel
    }