🏩
VitisHLS 高位合成によるビットブロック表示回路の作成
VitisHLS高位合成によるビットブロック表示回路の作成
はじめに
前回に続き、「FPGAプログラミング大全 第2版」をやる
本投稿では本書11-2~「高位合成の応用」を実施したメモを書きます
内容としては前回記事の続きです
環境
FPGA : Xilinx Zybo Z7-20
OS : WSL2 Ubuntu20.04
開発環境 : Vivado ML edition 2022.1 Linux版
やりたいこと
Vitis HLSを使って高位合成によってビットブロック表示回路を作る
IP化を行い、前回作成したパターン表示回路と合わせてZynqのブロックデザインに組み込み実機確認まで行う
ビットブロック描画回路仕様
- 転送元の画像を2つ用意できる
- 透明度αにより2つの画像に対する画素間演算を行う
- 演算結果を表示用メモリに格納する
実装
projectの作成~回路合成
*ソースコードは以下より
- SourceとTest benchを追加
- Directiveの追加
- C synthesis
下記はSourceに対してDirectiveを付与したもの
#include <ap_int.h>
#include "bitblt.h"
u32 calc(u32 src, u32 dst, u8 alpha)
{
u32 src_r = (src>>16) & 0xff;
u32 src_g = (src>> 8) & 0xff;
u32 src_b = src & 0xff;
u32 dst_r = (dst>>16) & 0xff;
u32 dst_g = (dst>> 8) & 0xff;
u32 dst_b = dst & 0xff;
dst_r = (alpha*src_r + (255-alpha)*dst_r)/255;
dst_g = (alpha*src_g + (255-alpha)*dst_g)/255;
dst_b = (alpha*src_b + (255-alpha)*dst_b)/255;
return ((dst_r<<16) & 0xff0000) | ((dst_g<<8) & 0xff00) | (dst_b & 0xff);
}
void bitblt(
volatile u32 *srcin,
volatile u32 *dstin,
volatile u32 *dstout,
u8 alpha,
u11 width,
u11 height)
{
#pragma HLS INTERFACE mode=s_axilite port=height
#pragma HLS INTERFACE mode=s_axilite port=width
#pragma HLS INTERFACE mode=s_axilite port=alpha
#pragma HLS INTERFACE mode=m_axi bundle=dst depth=307200 max_write_burst_length=32 num_write_outstanding=16 port=dstout offset=slave
#pragma HLS INTERFACE mode=m_axi bundle=dst depth=307200 max_write_burst_length=32 num_write_outstanding=16 port=dstin offset=slave
#pragma HLS INTERFACE mode=m_axi bundle=src depth=307200 max_read_burst_length=32 num_read_outstanding=16 port=srcin offset=slave
u32 src[XSIZE], dst[XSIZE];
height_loop: for (int y=0; y<height; y++) {
#pragma HLS LOOP_TRIPCOUNT avg=240 max=480 min=1
#pragma HLS DATAFLOW
src_loop: for (int x=0; x<width; x++) {
#pragma HLS PIPELINE
#pragma HLS LOOP_TRIPCOUNT avg=320 max=640 min=1
src[x] = srcin[x + y*XSIZE];
}
dstin_loop: for (int x=0; x<width; x++) {
#pragma HLS PIPELINE
#pragma HLS LOOP_TRIPCOUNT avg=320 max=640 min=1
dst[x] = dstin[x + y*XSIZE];
}
dstout_loop: for (int x=0; x<width; x++) {
#pragma HLS PIPELINE
#pragma HLS LOOP_TRIPCOUNT avg=320 max=640 min=1
dstout[x + y*XSIZE] = calc(src[x], dst[x], alpha);
}
}
}
合成結果
- 動作周波数・サイクル
- 回路規模
C-RTL Cosimulation
- C-RTL Cosimulationを実行
- 1ライン目はsrc,dst各1ポートずつReadしており、dstの書き込みは行われていない
1画素のトランザクション
-
src port Read: burst長=32、Hライン画素数320より、320/32=10トランザクション
-
dst port Read: burst長=16、Hライン画素数320より、320/16=20トランザクション
-
トランザクション終了後にR/AR ValidがLになり、次のVラインまでのマージンを設けている
-
画素最終部分。1画素目とは反対に、dstポートの書き込みのみが行われている。ここからパイプライン処理が実装されていると分かる
出力の確認
テストベンチで作成したrawfileを確認
- 中央部分が青+赤になっており、画素同士の補正ができている
データ的にはこの部分
Export RTLよりIP化して終了
Discussion