C API for PYNQでDMAをする
PYNQでFPGAとOS上のアプリケーション通信間で高速に通信するにはDMAが有効です。前回の記事でも述べたようにPythonのスレッド間通信は低速なのでFPGA側からDMAで送られてきたデータを処理しようとすると速度不足になりやすいです。 今回はPYNQでAXIStreamによるDMAができたのその記事を書こうと思います。 github.com
README.MDにサンプルコードがあるのですが、実行するための回路を生成するTCLもビットファイルも無いので、回路を動かすためにどうしたらいいかわかりづらいと思います。そこで回路を作って実行してみました。
回路作成
以下のブログの「PS に接続されたメモリのデータを PL から読み書きしてみる」の回路を丸々拝借します。 www.acri.c.titech.ac.jp
出来上がったものがこちら そして注目すべきところが作ったaxi_dmaにたいしてAXI_LITEで接続しているアドレス部分。
このアドレス部分をソースコード中のPYNQ_openDMA(&dma, アドレス);
と一致させる必要があります。
ソースコード
丸々引用のコードです
#include <stdio.h> #include <pynq_api.h> int main() { PYNQ_loadBitstream("/home/xilinx/my_bitstream.bit"); PYNQ_SHARED_MEMORY shared_memory_1, shared_memory_2; PYNQ_allocatedSharedMemory(&shared_memory_1, sizeof(int)*10, 1); PYNQ_allocatedSharedMemory(&shared_memory_2, sizeof(int)*10, 1); int * d1=(int*)shared_memory_1.pointer; int * d2=(int*)shared_memory_2.pointer; for (int i=0;i<10;i++) { d1[i]=i; d2[i]=0; } PYNQ_AXI_DMA dma; PYNQ_openDMA(&dma, 0x40400000); PYNQ_writeDMA(&dma, &shared_memory_1, 0, sizeof(int) * 10); PYNQ_readDMA(&dma, &shared_memory_2, 0, sizeof(int) * 10); PYNQ_waitForDMAComplete(&dma, AXI_DMA_WRITE); PYNQ_waitForDMAComplete(&dma, AXI_DMA_READ); for (int i=0;i<10;i++) { printf("%d %d %d\n", i, d1[i], d2[i]); } PYNQ_closeDMA(&dma); PYNQ_freeSharedMemory(&shared_memory_1); PYNQ_freeSharedMemory(&shared_memory_2); return 0; }
以下のように実行すると数を二倍した結果を得られます。
$ g++ -o my_dma DMA.cpp -lpynq -lcma -lpthread -O3 $./my_dma 0 0 0 1 1 2 2 2 4 3 3 6 4 4 8 5 5 10 6 6 12 7 7 14 8 8 16 9 9 18