FC2カウンター FPGAの部屋 Zybot で Gabor filter を使う際のDMA Write IP

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Zybot で Gabor filter を使う際のDMA Write IP

Zybotのカメラによる白線追従走行”では、Gabor filter をソフトウェアで 250 ms ごとに切り替えていた。これは、500 ms に1回 Gabor filter の画像が取得できることを表している。この時間を短くしたいということで、AXI VDMA をVivado HLS 2016.2 で作成したDMA Write IP に差し替えようと思う。つまり、ハードウェアで自動的に左右のGabor filter を切り替えて、異なるアドレスのフレームバッファに書き込むことにしよう。

2016/09/22 修正: RorL を 1 ビットに修正しました)

DMA Write IP を書き換えて3 フレームバッファから 2 フレームバッファにした。次に、active_frame 信号の代わりに RorL 信号を追加した。
ヘッダファイルの dmaw4gabor.h を示す。これはシミュレーション用の画像用だ。実際に使用するときは、800 x 600 に変更する。なお、800 x 600 では、C/RTL協調シミュレーションがエラーになってしまった。現在の 64 x 48 では、問題なく C/RTL協調シミュレーションが通る。

// dmaw4gabor.h
// 2016/09/20 by marsee
//

#ifndef __DMA_WRITE_H__
#define __DMA_WRITE_H__

//#define HORIZONTAL_PIXEL_WIDTH    800
//#define VERTICAL_PIXEL_WIDTH    600

#define HORIZONTAL_PIXEL_WIDTH    64
#define VERTICAL_PIXEL_WIDTH    48

#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define MAX_FRAME_NUMBER    2

#endif


次に、dmaw4gabor.cpp を示す。

// dmaw4gabor.cpp
// 2016/09/20 by marsee
//
// frame_buffer0, frame_buffer1、2つのフレームバッファ
// if (RorL == 0) Left Gabor filter
// if (RorL == 1) Right Gabor filter
//

#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "dmaw4gabor.h"

int dmaw4gabor(hls::stream<ap_axis<32,1,1,1> >& ins, volatile int *out,
        unsigned int frame_buffer0, unsigned int frame_buffer1,
        volatile ap_uint<1> & RorL){
#pragma HLS INTERFACE ap_none port=RorL
#pragma HLS INTERFACE s_axilite port=frame_buffer0
#pragma HLS INTERFACE s_axilite port=frame_buffer1
#pragma HLS INTERFACE m_axi depth=5000000 port=out offset=off
#pragma HLS INTERFACE axis port=ins
#pragma HLS INTERFACE s_axilite port=return

    ap_axis<32,1,1,1> pix;
    int dma_index;

    for (int i=0; i<MAX_FRAME_NUMBER; i++){
        switch (i){
            case 0 :
                dma_index = frame_buffer0/sizeof(int);
                break;
            default//case 1 :
                dma_index = frame_buffer1/sizeof(int);
                break;
        }
        RorL = i;

        do { // user が 1になった時にフレームがスタートする
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
            ins >> pix;
        } while(pix.user == 0);

        for (int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
            for (int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS PIPELINE II=1
                if (!(x==0 && y==0))    // 最初の入力はすでに入力されている
                    ins >> pix;    // AXI4-Stream からの入力
                out[dma_index+(y*HORIZONTAL_PIXEL_WIDTH)+x] = pix.data;
            }
        }
    }
    return 0;
}


C シミュレーションは問題なかった。

C コードの合成も問題ない。C コードの合成結果は 800 x 600 に変更して行ったときに結果を示そうと思う。

C/RTL協調シミュレーション結果を示す。
DMAW4Gabor_1_160921.png

C/RTL協調シミュレーション波形を示す。
DMAW4Gabor_2_160921.png
DMAW4Gabor_3_160921.png

ins_TVALID と ins_TREADY がずっと 1 で待ちがなく、連続的にAXI4-Stream でデータ転送ができていることがわかる。

次に dmaw4gabor.h の画像のサイズを 64 x 48 から 800 x 600 に変更して、C コードの合成を行った。結果を示す。
DMAW4Gabor_4_160921.png

問題なさそうなので、IP 化を行った。

2016/09/22 追加 : Gabor_Filter_lh を変更した)

DMA Write IP に接続するGabor filter も RorL の INTERFACE指示子を s_axilite から ap_none に変更した。今までは、AXI4 Lite Slave インターフェースのレジスタとして RorL がマップされていたが、出力ポートになった。
gabor_filter_lh_1_160922.png

C コードの合成をして、IP 化を行った。
  1. 2016年09月21日 04:16 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3579-9e3fc1e0
この記事にトラックバックする(FC2ブログユーザー)