#概要
Vivado HLSの使い方について備忘録を残す
#今回のターゲット
AXI-Streamの入出力について記す。
Xilinx FPGAの場合は、画像系のインターフェースとして使用される。
詳細は UG761
#Example Design
Vivado HLS -> Open Example Design -> axi_stream_side_channel_data
#Cソース
@example.cpp
#include "ap_axi_sdata.h"
void example(ap_axis<32,2,5,6> A[50], ap_axis<32,2,5,6> B[50]){
#pragma HLS INTERFACE axis port=A
#pragma HLS INTERFACE axis port=B
int i;
for(i = 0; i < 50; i++){
B[i].data = A[i].data.to_int() + 5;
B[i].keep = A[i].keep;
B[i].strb = A[i].strb;
B[i].user = A[i].user;
B[i].last = A[i].last;
B[i].id = A[i].id;
B[i].dest = A[i].dest;
}
}
##解説
ヘッダファイル(ap_axi_sdata.h)
AXIS含めDMA用のインターフェースも含まれている
以下にテンプレート
ふつうはkeep/strb/id/destは使用しないが、テンプレートない
validとreadyはどうしているかわからない
template<int D,int U,int TI,int TD>
struct ap_axis{
ap_int<D> data;
ap_uint<(D+7)/8> keep;
ap_uint<(D+7)/8> strb;
ap_uint<U> user;
ap_uint<1> last;
ap_uint<TI> id;
ap_uint<TD> dest;
};
template<int D>
struct ap_axis <D, 0, 0, 0>{
ap_int<D> data;
ap_uint<(D+7)/8> keep;
ap_uint<(D+7)/8> strb;
ap_uint<1> last;
};
インターフェース詳細
ap_axis<32,2,5,6> A[50]
ap_int<D> data
32bitのデータ幅
ap_uint<U> user
2bitのTUSERIDとDESTはどうでもよい
配列要素の[50]はレジスタの数?よくわからん
AXISを使用するためのプラグマ
#pragma HLS INTERFACE axis port=A
処理部
B[i].data = A[i].data.to_int() + 5
#Verilogソース
##入出力
input ap_clk;
input ap_rst_n;
input ap_start;
output ap_done;
output ap_idle;
output ap_ready;
input [31:0] A_TDATA;
input A_TVALID;
output A_TREADY;
input [3:0] A_TKEEP;
input [3:0] A_TSTRB;
input [1:0] A_TUSER;
input [0:0] A_TLAST;
input [4:0] A_TID;
input [5:0] A_TDEST;
output [31:0] B_TDATA;
output B_TVALID;
input B_TREADY;
output [3:0] B_TKEEP;
output [3:0] B_TSTRB;
output [1:0] B_TUSER;
output [0:0] B_TLAST;
output [4:0] B_TID;
output [5:0] B_TDEST;
AXI-Stream系
RTL化すると、VALIDとREADYが追加されている。
NotReady条件等はよくわからんAP-Control系
UG902図1-38を参照
合成状態によってはスループットが低下?
こちらのブログも参考になる
https://marsee101.blog.fc2.com/?mode=m&no=3497&photo=true
#所感
・高位合成により出力されるRTLは、RTL設計者からはイメージが付きづらい
・今回のように対した処理でもない(入力をそのまま出力するだけ)のに、生成されたRTLコードは複雑。
・CソースをそれなりにHDLを意識して記述&RTLでのSIM環境を整えなければ設計スピードと品質の両立は難しそうな気がする