終了しないカーネルの場合、最上位関数の引数が次のコード要件に従っている必要があります。
- カーネルは、
auto_restart
ビットをイネーブルにするap_ctrl_chain
ブロック制御プロトコルをインプリメントします。 - カーネルは AXI4-Stream インターフェイス (
axis
) をサポートしており、AXI4 メモリ マップド インターフェイス (m_axi
) を持たず、ほかのカーネルとはストリームを介してのみ送受信します。
ストリーミング パラダイムを使用するデザインは C で記述するのが困難な場合があります。複数の読み出しおよび書き込みを実行するためにポインターを使用すると、型修飾子が記述されるので、問題が発生する可能性があります。Vitis HLS には、ストリーミング データ構造を記述するための C++ テンプレート クラスの hls::stream<ap_axis<N>>
が含まれます。ハードウェアでは、hls::stream
が axis
インターフェイスとしてインプリメントされます。
ap_axi_sdata.h で定義されるように、Vitis HLS は AXI4-Stream インターフェイスを次のシグネチャを持つ構造体型としてインプリメントします。
template <typename T, size_t WUser, size_t WId, size_t WDest> struct axis { .. };
説明:
-
T
: ストリーム データ型 -
WUser
: TUSER 信号の幅 -
WId
: TID 信号の幅 -
WDest
: TDest 信号の幅
ストリーム データ型 (T
) が単純な整数型の場合、次の 2 つの定義済みタイプの AXI4-Stream インプリメンテーションを使用できます。
-
AXI4-Stream クラスの符号付きインプリメンテーション:
hls::axis<ap_int<WData>, WUser, WId, WDest>
- 符号なしのインプリメンテーション:
hls::axis<ap_uint<WData>, WUser, WId, WDest>
TVALID
、TREADY
、および TLAST
は、AXI4-Stream プロトコルに必要な制御信号です。サイドチャネル信号の TKEEP
、TSTRB
、TUSER
、TID
、および TDEST
は、追加のブックキーピング データを渡すために使用可能な特別信号です。
『Vitis 高位合成ユーザー ガイド』 (UG1399) の AXI4-Stream インターフェイス で説明されるように、テンプレート パラメーターの WUser
、WId
、および WDest
に指定される値は、インターフェイスでのサイド チャネル信号の使用を定義します。
次の例は、AXI4-Stream を使用した、データ駆動型で終了しないカーネルのプログラミング モデルを示しています。
#include "ap_axi_sdata.h"
#include "hls_stream.h"
typedef ap_axis<32, 0, 0, 0> pkt;
extern "C" {
10 void krnl_stream_vdatamover(hls::stream<pkt> &in,
11 hls::stream<pkt> &out // Internal Stream
12 ) {
13 #pragma HLS interface ap_ctrl_chain port=return
14 bool eos = false;
15 vdatamover:
16 do {
17 // Reading a and b streaming into packets
18 pkt t1 = in.read();
19
20 // Packet for output
21 pkt t_out;
22
23 // Reading data from input packet
24 ap_uint<DWIDTH> in1 = t1.data;
25
26 // Vadd operation
27 ap_uint<DWIDTH> tmpOut = in1;
28
29 // Setting data and configuration to output packet
30 t_out.data = tmpOut;
31 t_out.last = t1.last;
32 t_out.keep = -1; // Enabling all bytes
33
34 // Writing packet to output stream
35 out.write(t_out);
36
37 if (t1.last) {
38 eos = true;
39 }
40 } while (eos == false);
重要: 終了しないカーネルは、カーネルの周りに
while(1)
ループがあるところを示しています。このため、非確定的な動作が発生しないよう、ソース コードで while(1)
ループを明示的に指定しないでください。