AXI4-Stream インターフェイスは、どの入力引数でも、どの配列またはポインター出力引数にでも使用できます。
AXI4-Stream インターフェイスはデータをシーケンシャル ストリーミングで送信するので、読み込みと書き出しの両
方を実行する引数とは併用できません。AXI4-Stream インターフェイスは常に次のバイトに符号拡張されます。たと えば、12 ビットのデータ値は 16 ビットに符号拡張されます。
AXI4-Stream インターフェイスは、複数の HLS IP ブロックと AXI-Stream インターフェイスがより 大きなデザインに 統合される際に、組み合わせフィードバックパスが作成されないように、常にレジスタ付きインターフェイスとして インプリメントされます。AXI-Stream インターフェイスには、AXI-Stream インターフェイスのレジスタのインプリ メント方法を制御する 4 つのレジスタ モードが含まれます。
• Forward: TDATAおよびTVALID信号のみがレジスタに送信されます。
• Reverse: TREADY 信号のみがレジスタに送信されます。
• Both: すべての信号 (TDATA、TREADY、TVALID) がレジスタに送信されます。これがデフォルトです。
• Off: どのポート信号もレジスタに送信されません。
AXI-Stream サイドチャネル信号はデータ信号と考慮され、TDATA にレジスタが付けられるとレジスタが付けられま
す。
推奨: HLS で生成した IP ブロックを AXI4-Stream インターフェイスに接続する際は、少なくとも 1 つのインターフ ェイスをレジスタ付きのインターフェイスとしてインプリメントするか 、ブロックを AXI4-Stream Register Slice を 介して接続する必要があります。
デザインで AXI4-Stream を使用するには、基本的に次の 2 つの方法があります。
• サイドチャネルなしで AXI4-Stream を使用します。
• サイドチャネルありで AXI4-Stream を使用します。
この 2 つ目のユース ケースの場合は、AXI4-Stream 規格の一部であるオプションのサイドチャネルが C コードで直接 使用できるという機能もあります。
サイドチャネルなしの AXI4-Stream インターフェイス
AXI4-Stream は、関数引数ap_axis型に AXI4 サイドチャネルエレメントが含まれない場合は、サイドチャネルな
しで使用されます。この例では、両方のインターフェイスが AXI4-Stream を使用してインプリメントされます。
#include "ap_axi_sdata.h"
#include "hls_stream.h"
void example(hls::stream< ap_axis<32>> &A, hls::stream< ap_axis<32>> &B) {#pragma HLS INTERFACE axis port=A
#pragma HLS INTERFACE axis port=B ap_axis<32> tmp;
A.read(tmp);
tmp.data = tmp + 5;
B.write(tmp);
}
合成後は、次の図に示すように、どちらの引数もデータ ポートと標準 AXI4-Stream の TVALID および TREADY ポー トを使用してインプリメントされます。
図 59: サイドチャネルなしの AXI4-Stream インターフェイス
構造体を使用して複数の変数を 1 つの AXI4-Stream インターフェイスにまとめることができ、Vitis HLS によりデフ ォルトで統合されます。構造体の要素を 1 つの幅の広いベクターに統合すると、構造体のすべての要素を同じ
AXI4-Stream インターフェイスにインプリメントできます。
サイドチャネルありの AXI4-Stream インターフェイス
次の例は、サイドチャネルを C コードで直接使用する方法とインターフェイスへのインプリメント方法を示していま す。このコードは、API 用にap_axi_sdata.hインクルードファイルを使用して、AXI4-Stream インターフェイス のサイドチャネルを処理します。この例の場合、符号付き 32 ビットのデータ型が使用されています。
#include "ap_axi_sdata.h"
#include "ap_int.h"
#include "hkls_stream.h"
#define DWIDTH 32
typedef ap_axiu<DWIDTH, 0, 0, 0> trans_pkt;
extern "C"{
void krnl_stream_vmult(hls::stream<trans+pkt> &b, hls::stream<trans_pkt>
&output) {
#pragma HLS INTERFACE axis port=b #pragma HLS INTERFACE axis port=output
#pragma HLS INTERFACE s_axilite port=return bundle=control bool eos = false;
vmult:
do {
#pragma HLS PIPLINE II=1 trans_pkt t2 = b.read();
//Patcket for Output trans_pkt t_out;
// Reading data from input packet ap_uint<DWIDTH> in2 = t2.data;
ap_uint<DWIDTH> tmpOut = in2 * 5;
// Setting data and configuration to output packet t_out.data = tmpOut;
t_out.last = t1.get_last();
t_out.keep = -1; //Enabling all bytes //Writing packet to output stream output.write(t_out);
if(t.get_last()) { eos = true;
}
} while (eos == false);
}}
合成後は、どちらの引数も、データ ポート、標準 AXI4-Stream の TVALID および TREADY プロトコル ポート、およ び構造体で記述されたオプションのポートすべてを使用してインプリメントされます。
図 60: サイドチャネルありの AXI4-Stream インターフェイス
構造体の AXI4-Stream インターフェイスへのパック
AXI4-Stream インターフェイスと一緒に構造体を使用する場合は、デフォルトの合成動作が異なります。構造体のデ
フォルトの合成動作については、インターフェイス合成および構造体を参照してください。
サイドチャネルありまたはなしの AXI4-Stream インターフェイスを使用していて、関数引数が構造体の場合、Vitis HLS でその構造体のすべての要素が単一幅のデータ ベクターにまとめられます。インターフェイスは、関連する TVALID および TREADY 信号を使用して単一幅のデータ ベクターとしてインプリメントされます。
サイドチャネルありの AXI4-Stream インターフェイスを使用する場合、Vitis HLS ツールでは RGBPixel などの構造体 を axis インターフェイスを介して送信できません。独自の構造体を定義するために ap_axiu 構造体をオーバーロー ドすることはできません。この制限を回避するには、構造体初期化関数を使用して意図する結果を取得します。
struct RGBPixel { unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
RGBPixel(ap_int<32> d) : r(d.range(7,0)), g(d.range(15,8)), b(d.range(23,16)), a(d.range(31,24)) {
#pragma HLS INLINE }
operator ap_int<32>() {
#pragma HLS INLINE
return (ap_int<8>(a), ap_int<8>(b), ap_int<8>(g), ap_int<8>(r));
}
}__attribute__((aligned(4)));