FC2カウンター FPGAの部屋 Vivado HLS でAXI4-Stream Master Model IP を作る

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

FPGAの部屋

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

Vivado HLS でAXI4-Stream Master Model IP を作る

久しぶり Verilog HDL を使って、AXI4-Stream版ビットマップ・ディスプレイ・コントローラを作っている。ビットマップ・ディスプレイ・コントローラはAXI4-Stream Slave なので、シミュレーションするには AXI4-Stream Master が必要となる。始めは、HDL で AXI4-Stream Master IP を作ろうとしたのだが、考えてみれば、Vivado HLS で、C++ で AXI4-Stream Master IP を作ってもよいのじゃないか?ということで、Vivado HLS 2016.2 を使用して作ってみた。

Vivado HLS 2016.2 の axi4-stream_master プロジェクトを示す。
AXI4-Stream_bitmap_disp_cont_8_160815.png

最初に axi4_stream_master.h を示す。

// axi4_stream_master.h
// 2016/08/15 by marsee
//

#ifndef __AXI4_STREAM_MASTER_H__
#define __AXI4_STREAM_MASTER_H__

#define HORIZONTAL_PIXELS 800
#define VERTICAL_LINES 600

#endif


ソースファイルの axi4_stream_master.cpp を示す。

// axi4_stream_master.cpp
// 2016/08/15 by marsee
//
// AXI4-Stream Master Model
//

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

#include "axi4_stream_master.h"

void axi4_stream_master(hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE ap_ctrl_hs port=return
    ap_uint<8> red = 0;
    ap_uint<8> blue = 0;
    ap_uint<8> green = 0;
    ap_axis<32,1,1,1> pix;

    for (int y=0; y<VERTICAL_LINES; y++){
        for (int x=0; x<HORIZONTAL_PIXELS; x++){
#pragma HLS PIPELINE II=1
            pix.data = red*65536 + green*256 + blue;
            red++;
            green += 2;
            blue += 3;
            if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
                pix.user = 1;
            else
                pix.user = 0;

            if (x==(HORIZONTAL_PIXELS-1)) // 行の最後で TLAST をアサートする
                pix.last = 1;
            else
                pix.last = 0;

            outs << pix;
        }
    }
}


テストベンチの axi4_stream_master.tb.cpp を示す。

// axi4_stream_master.tb.cpp
// 2016/08/15 by marsee
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <ap_axi_sdata.h>

#include "axi4_stream_master.h"

void axi4_stream_master(hls::stream<ap_axis<32,1,1,1> >& outs);

int main(){
    using namespace std;

    hls::stream<ap_axis<32,1,1,1> > outs;
    ap_axis<32,1,1,1> pix;
    ap_uint<8> red = 0;
    ap_uint<8> blue = 0;
    ap_uint<8> green = 0;
    ap_int<32> pix_data;

    axi4_stream_master(outs);

    for (int y=0; y<VERTICAL_LINES; y++){
        for (int x=0; x<HORIZONTAL_PIXELS; x++){
            outs >> pix;
            pix_data = red*65536 + green*256 + blue;
            //printf("red=%x, green=%x, blue=%x, pix_data=%x\n", (int)red, (int)green, (int)blue, (int)pix_data);
            if (pix.data != pix_data){
                printf("ERROR HW and SW results mismatch x = %d, y = %d, HW = %x, SW = %x\n", x, y, (int)pix.data, (int)pix_data);
                return(1);
            }
            red++;
            green += 2;
            blue += 3;
        }
    }
    cout << "Success HW and SW results match" << endl;
    cout << endl;

    return(0);
}


合成はしないけれども、C コードの合成結果を示す。
AXI4-Stream_bitmap_disp_cont_9_160815.png

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

outs_TVALID と outs_TREADY がずっと1のままなので、大丈夫そうだ。

AXI4-Stream_bitmap_disp_cont_11_160815.png

最初のデータで outs_TUSER が 1 になっているのがわかる。

AXI4-Stream_bitmap_disp_cont_12_160815.png

さいしょのデータが始まってから、outs_TLAST が 1 にアサートされて、0 になるまでの間は 8 us だった。これは、10 ns のクロックが 800 個分なので、合っている。

最後にIP 化は行ったが、HDLを直接使用すると思う。
  1. 2016年08月16日 03:47 |
  2. IP
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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