More Related Content
Similar to ACRiウェビナー:小野様ご講演資料 (14)
ACRiウェビナー:小野様ご講演資料
- 3. FPGAの部屋のブログ
• 2005年にスタート
• 現在5,500記事位
• 664万アクセス
• カテゴリ数は167個
• Vitis HLS (77)
• Vitis_Vision (44)
• NNgen (14)などなど
• https://marsee101.blog.fc2.com/
• FPGA友達がいないので、寂しくて書き始めた
• 途中からは脳の外部記憶として書いた
3
- 4. Vitis HLS, Vivado HLSとは?
• Xilinx社の高位合成ツール
• C、C++からVHDL、Verilog HDLに合成しIPを生成す
るツール
• 機能を検証するための2種類のシミュレーション
• Cシミュレーション
• C/RTL協調シミュレーション
4
- 6. Vitis HLS(Vivado HLS)の私が考
える特徴および利点1
• C、C++からVHDL、Verilog HDLに合成しIPを生成する
• FPGAの種類を指定して、クロック周期を設定する
• 指定したクロック周期で動作するRTLを出力
• クロック周期を短く設定すると自動的にパイプライン段数が
増える
• AXI-Master, AXI-Lite Slaveはプラグマ1行のみで自動生成
• AXI-Streamはストリーム用テンプレートを使用する
• ソフトウェアから使用するためのドライバも自動生成
• ベアメタル用、Linux用
• 無料!!!(ただしデバイス限定)
• Vivado 2015.4から無償、すべてのバージョンで提供
• https://marsee101.blog.fc2.com/blog-entry-3319.html
• ライセンスが必要ない(ダウンロード時の登録は必要)
6
- 7. Vitis HLS(Vivado HLS)の私が考
える特徴および利点2
• 制御部(ステートマシン)を書く必要が無いということは、
ステートマシンに起因するバグが無くなる
• つまりHDL書くよりもバグが少なくなる
• 機能はCベースのシミュレーションで検証可能
• デバック時間が短い
• Eclipseのデバッカーでデバックできる
• HDLを合成したらRTLシミュレーションでHDLを検証
(C/RTL協調シミュレーション)
• CテストベンチからRTLシミュレータにデータを入力
• RTLシミュレーション
• RTLシミュレーションの結果をCテストベンチに返して検証
• タイミング波形を確認できる
7
- 9. 私のVivado HLS, Vitis HLS使用経
緯
• 2013年8月からVivado HLS 2013.2を使い始めた
• https://marsee101.blog.fc2.com/blog-entry-2563.html
• Vivado HLS 2013.4で作成したラプラシアンフィルタ
画像はソフトウェア画像と比べて画像が違ってい
た
• https://marsee101.blog.fc2.com/blog-entry-2737.html
• Vivado HLS 2014.1でソフトウェアとラプラシアンフィ
ルタ画像が同一になった
• バグが解消されたようだ
• Vivado HLSが使えるようになった
• https://marsee101.blog.fc2.com/blog-entry-2800.html
9
- 10. Vivado HLSからVitis HLSへ
• Vivado HLSを使用してきたが2020.1からVitis HLSへバト
ンタッチ
• 大体Vivado HLSと同じだが、変更されている部分も
• AXI4マスター・インターフェース作成したときのアドレスだが、
64ビット・アドレスがデフォルトになった
• ハードウェア化する関数内でのストリームの扱い
• Vitis HLSの方がデフォルトの状態でチューニングされている
(レイテンシが短い)
• 初心者は特にVitis HLSをお勧めする
• その他、いろいろ変更有り
• Vitis HLS 移行ガイド UG1391 (v2020.2) 2020 年 11 月
24 日参照
• https://www.xilinx.com/support/documentation/sw_manuals
_j/xilinx2020_2/ug1391-vitis-hls-migration-guide.pdf
10
- 11. Vivado HLS 対 Vitis HLS性能比
較、sobel_filter_aximの実装
• DDR SDRAMから画像データを直接Read
2022/3/7 「FPGAの部屋」, marsee101 11
- 12. Vivado HLS対Vitis HLS(ソーベ
ル・フィルタ)
12
int sobel_filter_axim(volatile int32_t *cam_fb, volatile int32_t *sobel_fb){
#pragma HLS INTERFACE m_axi depth=3072 port=sobel_fb offset=slave
#pragma HLS INTERFACE m_axi depth=3072 port=cam_fb offset=slave
#pragma HLS INTERFACE s_axilite port=return
int32_t sobel_val, sobel_h_val, sobel_v_val;
int32_t pix[3][3];
LOOP_Y: for(int y=0; y<(DISPLAY_HIGHT-2); y++){
LOOP_X: for(int x=0; x<(DISPLAY_WIDTH-2); x++){
LOOP1: for(int i=0; i<3; i++){
LOOP2: for(int j=0; j<3; j++){
pix[i][j] = conv_rgb2y(cam_fb[(y+i)*DISPLAY_WIDTH+(x+j)]);
}
}
sobel_h_val = sobel_fil(HORIZONTAL, pix[0][0], pix[0][1], pix[0][2],
pix[1][0], pix[1][1], pix[1][2],
pix[2][0], pix[2][1], pix[2][2]);
sobel_v_val = sobel_fil(VERTICAL, pix[0][0], pix[0][1], pix[0][2],
pix[1][0], pix[1][1], pix[1][2],
pix[2][0], pix[2][1], pix[2][2]);
sobel_val = square_root8(sobel_h_val*sobel_h_val + sobel_v_val*sobel_v_val);
sobel_fb[y*(DISPLAY_WIDTH-2)+x] = (sobel_val<<16)+(sobel_val<<8)+sobel_val; // 通常出力
}
}
- 16. 16
Vitis HLS 2021.2
Cコードの合成2
• Latencyは25706クロック
• Vivado HLSでは251299
クロック
• 性能は約9.8倍
• リソース使用率
• BRAM_18Kが4個
• Vivado HLSでは2個
• DSPが19個
• Vivado HLSでは9個
• FFが2280個
• Vivado HLSでは
1264個
• LUTが3300個
• Vivado HLSでは
2041個
- 18. Vitis HLS, Vivado HLSに対する
私の熱い思い(本音)
• 趣味or大学のお仕事でFPGAを使っているとシステムを
丸ごと(ハードもソフトも)自分1人で実装する
• 科研費の実装は速くする必要がある
• 実装は1年未満に… 6ヶ月位?
• 歳とともにHDLを書けない、書くスピードが遅くなった
• コードを書き始められない…引退が近い???
• そんなときにHLSでCコードを書いてIP実装
• 大幅なスピードアップ
• Xilinxさん、Vivado HLS、Vitis HLSを無料にしてくれて本当
にありがとうございます!
• Vitis HLS、Vivado HLSは私の救世主(使わなきゃ損です)
18
- 22. カメラを使用した画像認識により
白線間走行及び隊列走行するロ
ボットカーの使用IP
• 自作IP(9個)
• Vivado HLSで作成したIP(C言語で書いたIP)
• モーター用PWM IP
• モーター・モニターIP(モーターのパルス数をカウント)
• 超音波センサ・インターフェースIP
• ガボール・フィルタIP
• ガボール・フィルタ用DMAC IP
• ラプラシアンフィルタIP
• RGB-HSV変換IP
• ビットマップ・ディスプレイ・コントローラIP
• カメラ・インターフェースIP
• https://marsee101.web.fc2.com/white_line_detect.html
22
- 24. 白線をガボール・フィルタで検出2
• 左白線用、右白線用ガボール・フィルタのパラメータを決定
• Sigma, Lambda, Theta, Psi
• 日本大学の方のガボール・フィルタの実装を使用した(今Webサイトが無い)
• カーネルサイズを21ピクセルから9ピクセルへ変更
• パラメータを使って演算すればn x nの重みを画像に掛け算するのみ
24
• 9 x 9ピクセルの左白線用、右白線用ガボール・フィルタの重みを
取得した
• 左白線用、右白線用の2つのパラメータのガボール・フィルタを
Vivado HLS でC言語からHDLへ変換してIP化
- 26. ガボール・フィルタIPのソースコード
26
int Gabor_filter_lh(hls::stream<ap_axis<32,1,1,1> >& ins,
hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=ins
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE s_axilite port=return
ap_axis<32,1,1,1> pix;
ap_axis<32,1,1,1> gabor;
hls::LineBuffer<ARRAY_SIZE-
1, HORIZONTAL_PIXEL_WIDTH, int> linebuf;
hls::Window<ARRAY_SIZE, ARRAY_SIZE, int> mbuf;
int gray_pix, val, i, j, x, y;
do { // user が 1になった時にフレームがスタートする
ins >> pix;
} while(pix.user == 0);
for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS PIPELINE II=1
if (!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
mbuf.shift_left(); // mbuf の列を1ビット左シフト
for(i=ARRAY_SIZE-2; i>=0; --i){
mbuf.insert(linebuf(i,x), i+1, ARRAY_SIZE-1);
}
gray_pix = conv_rgb2y(pix.data);
mbuf.insert(gray_pix, 0, ARRAY_SIZE-1);
// LineBuffer の更新
linebuf.shift_down(x);
linebuf.insert_bottom(gray_pix, x);
// Gabor filter の演算
for (j=0, val=0; j<ARRAY_SIZE-1; j++){
for (i=0; i<ARRAY_SIZE-1; i++){
val += gabor_weight[j][i] * mbuf(ARRAY_SIZE-1-j,i);
}
}
val = val/256; // 256倍してあるので、1/256して戻す
if (val<0)
//val = -val; // 絶対値
val = 0; // マイナスの値を0に丸める
else if (val>255)
val = 255;
// Gabor filter・データの書き込み
gabor.data = (val<<16)+(val<<8)+val;
// 最初のARRAY_SIZE-1行とその他の行の最初のARRAY_SIZE-
1列は無効データなので0とする
if (x<(ARRAY_SIZE-1) || y<(ARRAY_SIZE-1))
gabor.data = 0;
if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
gabor.user = 1;
else
gabor.user = 0;
if (x == (HORIZONTAL_PIXEL_WIDTH-1)) // 行の最後
で TLAST をアサートする
gabor.last = 1;
else
gabor.last = 0;
outs << gabor; // AXI4-Stream へ出力
}
}
return(0);
}
https://marsee101.blog.fc2.com/b
log-entry-3524.html
- 30. 隊列走行ロボットカーの追従用
マーカー
• HSV でのH (色相)は、0~360 までの円で表される
ので、0 と 180 の距離が一番離れている。
• S = V = 255 とすると H = 0 は R=255, G = 0, B = 0 つ
まり赤であり、H =180 は R = 0, G = 255, B = 255 の
水色
30
水色の中に赤 RGB画像 HSV変換-S=V=255固定後
RGB変換
- 31. RGB2HSV IPのソースコード(一部)
31
int rgb2hsv(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis
<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE axis port=ins
ap_axis<32,1,1,1> pix;
int r, g, b;
int h, s, v;
int max, min;
int hsv;
do{
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
ins >> pix;
}while(pix.user == 0);
loop_y: for(int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
loop_x: for(int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS UNROLL factor=2
#pragma HLS PIPELINE II=1
if(!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
b = pix.data & 0xff;
g = (pix.data>>8) & 0xff;
r = (pix.data>>16) & 0xff;
// h と max, min を求める
if(r==g && g==b && r==b){
max = r; // 8倍
min = r;
}else if(r>=g && r>=b){ // r が最大
max = r;
if(g>=b)
min = b;
else
min = g;
}else if(g>=r && g>=b){ // g が最大
max = g;
if(r>=b)
min = b;
else
min = r;
}else{ // b が最大
max = b;
if(r>=g)
min = g;
else
min = r;
}
if(max-min == 0)
h = 0;
else if(max == r)
h = 60 * (((g-b)<<MAG)/(max-min)); // MAGビットシフトして精
度を確保
else if(max == g)
h = 60 * (((b-r)<<MAG)/(max-min)) + (120<<MAG); // MAG
ビットシフトして精度を確保
else // if(max == b)
h = 60 * (((r-g)<<MAG)/(max-min)) + (240<<MAG); // MAG
ビットシフトして精度を確保
if(h < 0)
h += 360<<MAG;
h += 1<<(MAG-1); // +0.5、四捨五入
https://marsee101.blog.fc2.com/b
log-entry-3604.html
- 35. その他の高位合成ツール
• インテル® HLS コンパイラーはインテル® Quartus®
Prime 開発ソフトウェアのインストールに含まれる
• 2017年に試してみたことがある
• https://marsee101.web.fc2.com/intel_hls.html
• Microchip社のSmartHLS
• 2021年12月に試してみた
• https://marsee101.web.fc2.com/smarthls.html
35