FC2カウンター FPGAの部屋 2015年03月
fc2ブログ

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

FPGAの部屋

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

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化5(tu1978さんのCソースコードを実機で検証)

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化4(tu1978さんのCソースコード)”の続き。

前回、IP化した tu1978 さんの高速化ラプラシアンフィルタIP を実機で検証してみることにした。

”Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化3(PIPELINEディレクティブを実機テスト)”で使用したプロジェクト(Z:\V_ZYBO_CAMDfL144)の hls_lap_filter_axim フォルダにラプラシアンフィルタIP が入っているので、その中身を今回の tu1978さんの高速化ラプラシアンフィルタIP の中身で置き換えた。
その後、プロジェクトを立ちあげたが、 tu1978さんの高速化ラプラシアンフィルタIP は、中身の構成が違いっているからか?前回のシミュレーションでもIP の更新が効かずにロックされてしまったため、消去してAdd IP し直した。
これでIP のロックも解除されたため、論理合成、インプリメント、ビットストリームの生成まで行って、成功した。
lap_fil_hls_14_4_57_150331.png

lap_fil_hls_14_4_58_150331.png

ZedBoard、ISE でIP をインプリメントした際には、100MHzの動作周波数制約を満たさなかったが、今回は制約を満たすことができた。Vivado が優秀なのか?Vivado HLS が優秀なHDL を出力したのかわからないが。。。

次に、ハードウェアをエクスポートして、SDKが立ち上がり、リビルドが自動的に行われた。

BOOT.bin の生成を行った。下にBOOT.bin 生成後のSDK 画面を示す。
lap_fil_hls_14_4_59_150331.png

出来上がったBOOT.bin をMicro SDカードに書いて、ZYBO のスロットに挿入して電源をONした。

SSH からログインして、最初にラプラシアンフィルタ全体の処理時間を計測したところ、約 35.4 ms だった。
lap_fil_hls_14_4_60_150331.png

次に、ラプラシアンフィルタ処理時間のみを計測してみたところ、約 20.0 ms だった。前回のPIPELINEディレクティブを下要したラプラシアンフィルタIP の処理時間が 60.0 ms だったので、ラプラシアンフィルタの処理時間は1/3 になっている。つまり3倍高速化している。
lap_fil_hls_14_4_61_150331.png

高速化無しの状態でのラプラシアンフィルタ処理時間は、全体経過時間で約 95.4 ms、ラプラシアンフィルタ処理時間のみでは、約 80 ms だったので、4倍に高速化された。

ちなみに、Vivado HLS 2014.4 で今回の tu1978 さんの高速化ラプラシアンフィルタ処理を行った場合の約 35.4 ms と完全にソフトウェアでラプラシアンフィルタ処理を行った場合の約 455.7 ms を比べると、約 12.9 倍に高速化されたことがわかる。
  1. 2015年03月31日 04:37 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化4(tu1978さんのCソースコード)

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化3(PIPELINEディレクティブを実機テスト)”の続き。

ZedBoard の時に、tu1978 さんにラプラシアンフィルタを高速化して頂いた。下にその時の記事を示す。

Vivado HLS 2014.1でラプラシアン・フィルタ関数をaxi masterモジュールにする5(Cソースのフィルタ処理をパイプライン化)
Vivado HLS 2014.1でラプラシアン・フィルタ関数をaxi masterモジュールにする6(パイプライン化ソースを実機テスト1)
Vivado HLS 2014.1でラプラシアン・フィルタ関数をaxi masterモジュールにする7(パイプライン化ソースを実機テスト2)
Vivado HLS 2014.1でラプラシアン・フィルタ関数をaxi masterモジュールにする8(パイプライン化ソースを実機テスト3)
Vivado HLS 2014.1でラプラシアン・フィルタ関数をaxi masterモジュールにする9(単体シミュレーション)

tu1978 さんにラプラシアンフィルタの高速化を改めて見てみると、私のようにline_buf(ピクセルのラインバッファ)の2次元配列の内の3つのラインから3つのピクセルを取り出すと、どうしてもポート数が足りなくなると思う。line_bufはBlockRAMにアサインされていると思うので、ポート数が精々2つである。そこから3つを取り出すので、少なくとも2クロック掛かる。もしかして、何も指定していないと3クロック掛けて3 ピクセルを取り出しているかもしれない?

tu1978さんの高速化ラプラシアンフィルタでは、line_bufのピクセルを3つの配列に入れ直して、pragma の array_partition の complete を指定している。これは、配列がその個別エレメ ントにパーティシ ョンされる pragma で個別のレジスタになるはずである。9つの個別レジスタにマップされ、9つのポートできるので、動作周波数が許せば1クロックで演算を行うことができるはずだ。

考えてみれば、HDLで書く時はBlockRAM に保存されているデータをポート数が足りないのでシフトレジスタに入れ替えて、そのデータでフィルタを演算する。それと同じ構造になっている訳だ。ここまで来るとFPGAの内部がわかっていないとチューニングをすることはできない。

さて、その tu1978 さんの高速化ラプラシアンフィルタのIP化を行った。
IP化をする際に、割り算をカウンタに置き換えた。
lap_fil_hls_14_4_52_150329.png

高位合成を行った。やはり、遅延が大きい。
lap_fil_hls_14_4_53_150329.png

IP 化をして、シミュレーションを行った。
lap_fil_hls_14_4_54_150330.png

シミュレーション波形を示す。
lap_fil_hls_14_4_55_150330.png

このシミュレーションから、DMA Write の間隔は32.7 us に短縮された。
高速化を何もしていない時のDMA Write の間隔が 131.95 us だった。
PIPELINEディレクティブを入れた時のDMA Write の間隔が 91.86 us だった。
tu1978 さんの高速化ラプラシアンフィルタは、プレーンの状態の 25% 程度の処理時間であるということが言える。つまり 4倍高速化されたわけだ。

DMA Write の間に、800ピクセルの次のラインの画像データを DMA Read して、以前の2つのラインの画像データを使って800ピクセル分のラプラシアンフィルタ処理を行い、その結果をDMA Write している。つまり、DMA Write の間隔の間に800ピクセルのラプラシアンフィルタ処理を行っている。依って、1ピクセル分の処理時間を計算してみよう。800で割ればよいはずだ。
高速化を何もしていない時の1ピクセルの処理時間は、131.95 us / 800 ≒ 165 ns 動作周波数は100MHzなので、16.5 クロックだ。
PIPELINEディレクティブを入れた時の1ピクセルの処理時間は、91.86 us / 800 ≒ 165 ns 動作周波数は100MHzなので、11.5 クロックだ。
tu1978 さんの高速化ラプラシアンフィルタの1ピクセルの処理時間は、32.7 us / 800 ≒ 41 ns 動作周波数は100MHzなので、4.1 クロックだ。これは、DMA Read を1クロック、DMA Write を1クロックとすると、ラプラシアンフィルタ処理は2クロックで行われていることになる。多分、AXI4 Master (memcopy()) を使っている状態ではこれが最速だと思う。

tu1978 さんの高速化ラプラシアンフィルタ(改) (lap_filter_axi_tu.cpp) のCソースコードを貼っておく。

// lap_filter_axi_tu.cpp
// lap_filter_axim()

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

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

void conv_line(unsigned int* buf){
    for (int b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){
#pragma HLS pipeline
        buf[b] = conv_rgb2y(buf[b]);    // カラーから白黒へ
    }
}

void filter_line(unsigned int* lap_buf, unsigned int* fl, unsigned int* sl, unsigned int* tl){
    int lap_fil_val;
    ap_uint<8> prev[3],current[3],next[3];    // 0->1ライン目, 1->2ライン目, 2->3ライン目, prev->1pixel前, current->現在, next->次pixel
#pragma HLS array_partition variable=prev complete dim=0
#pragma HLS array_partition variable=current complete dim=0
#pragma HLS array_partition variable=next complete dim=0

    next[0] = fl[0] & 0xFF;
    next[1] = sl[0] & 0xFF;
    next[2] = sl[0] & 0xFF;

    for (int x = 0; x < HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS pipeline
        if (x == 0 || x == HORIZONTAL_PIXEL_WIDTH-1){
            lap_fil_val = 0;

            current[0] = next[0];
            next[0] = fl[1];

            current[1] = next[1];
            next[1] = sl[1];

            current[2] = next[2];
            next[2] = tl[1];
        }else{
            prev[0] = current[0];
            current[0] = next[0];
            next[0] = fl[x+1];

            prev[1] = current[1];
            current[1] = next[1];
            next[1] = sl[x+1];

            prev[2] = current[2];
            current[2] = next[2];
            next[2] = tl[x+1];
            lap_fil_val = laplacian_fil(prev[0], current[0], next[0],
                                        prev[1], current[1], next[1],
                                        prev[2], current[2], next[2]);
        }
        lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
    }
}

int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS INTERFACE s_axilite port=cam_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=lap_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=return bundle=BUS_AXI4LS
    #pragma HLS INTERFACE ap_none port=cam_addr
    #pragma HLS INTERFACE ap_none port=lap_addr

    #pragma HLS INTERFACE m_axi port=cam_fb depth=1920
    #pragma HLS INTERFACE m_axi port=lap_fb depth=1920

    unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
#pragma HLS array_partition variable line_buf block factor=3 dim=1
#pragma HLS resource variable=line_buf core=RAM_2P

    unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH];
    int x, y;
    int lap_fil_val;
    int a, b;
    int fl, sl, tl;
    unsigned int offset_cam_addr, offset_lap_addr;
    int *cam_fb_addr, *lap_fb_addr;
    int line_sel;

    offset_cam_addr = cam_addr/sizeof(int);
    offset_lap_addr = lap_addr/sizeof(int);

    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=1, line_sel=0; y<VERTICAL_PIXEL_WIDTH-1; y++){
        // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        switch(line_sel){
            case 1 :
                fl = 0; sl = 1; tl = 2;
                break;
            case 2 :
                fl = 1; sl = 2; tl = 0;
                break;
            case 3 :
                fl = 2; sl = 0; tl = 1;
                break;
            default :
                fl = 0; sl = 1; tl = 2;
        }

        if (y == 1){
#ifndef __SYNTHESIS__
            printf("copy 3 lines\n");
#endif
            for (a=0; a<3; a++){
 // 3ライン分
                cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH)));
                memcpy(line_buf[a], (unsigned int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                conv_line(line_buf[a]);
            }
        }else// 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている
            cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH)));
            memcpy(line_buf[tl], (unsigned int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
            conv_line(line_buf[tl]);
        }
        filter_line(lap_buf, line_buf[fl], line_buf[sl], line_buf[tl]);
        lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH)));
#ifndef __SYNTHESIS__
        printf("write back:%d\n", y);
#endif
        memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));

        line_sel++;
        if (line_sel > 3){
            line_sel = 1;
        }
    }

    // 最初と最後のラインは0にする
    for (x = 0; x < HORIZONTAL_PIXEL_WIDTH; x++)
        lap_buf[x] = 0;
    lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(0*(HORIZONTAL_PIXEL_WIDTH)));
    memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
    lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(VERTICAL_PIXEL_WIDTH-1)*HORIZONTAL_PIXEL_WIDTH);
    memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));

    return(1);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8// 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


高位合成時のレポートファイル lap_filter_axim_csynth.rpt を貼っておく。


================================================================
== Vivado HLS Report for 'lap_filter_axim'
================================================================
* Date: Sun Mar 29 15:36:13 2015

* Version: 2014.4 (Build 1071461 on Tue Nov 18 16:42:57 PM 2014)
* Project: lap_filter_axim_tu_2014_4
* Solution: solution1
* Product family: zynq
* Target device: xc7z010clg400-1


================================================================
== Performance Estimates
================================================================
+ Timing (ns):
* Summary:
+---------+-------+----------+------------+
| Clock | Target| Estimated| Uncertainty|
+---------+-------+----------+------------+
|default | 10.00| 9.63| 1.25|
+---------+-------+----------+------------+

+ Latency (clock cycles):
* Summary:
+---------+---------+---------+---------+---------+
| Latency | Interval | Pipeline|
| min | max | min | max | Type |
+---------+---------+---------+---------+---------+
| 1942922| 3893598| 1942923| 3893599| none |
+---------+---------+---------+---------+---------+

+ Detail:
* Instance:
+----------------------------------------+-----------------------------+-----+-----+-----+-----+---------+
| | | Latency | Interval | Pipeline|
| Instance | Module | min | max | min | max | Type |
+----------------------------------------+-----------------------------+-----+-----+-----+-----+---------+
|grp_lap_filter_axim_filter_line_fu_420 |lap_filter_axim_filter_line | 807| 807| 807| 807| none |
|grp_lap_filter_axim_conv_line_fu_431 |lap_filter_axim_conv_line | 806| 806| 806| 806| none |
+----------------------------------------+-----------------------------+-----+-----+-----+-----+---------+

* Loop:
+-------------------------------+---------+---------+-------------+-----------+-----------+------+----------+
| | Latency | Iteration | Initiation Interval | Trip | |
| Loop Name | min | max | Latency | achieved | target | Count| Pipelined|
+-------------------------------+---------+---------+-------------+-----------+-----------+------+----------+
|- Loop 1 | 1940510| 3891186| 3245 ~ 6507 | -| -| 598| no |
| + Loop 1.1 | 4890| 4890| 1630| -| -| 3| no |
| ++ memcpy..cam_fb | 814| 814| 16| 1| 1| 800| yes |
| + memcpy..cam_fb | 814| 814| 16| 1| 1| 800| yes |
| + memcpy.lap_fb.lap_buf.gep8 | 801| 801| 3| 1| 1| 800| yes |
|- Loop 2 | 800| 800| 1| -| -| 800| no |
|- memcpy.lap_fb.lap_buf.gep7 | 801| 801| 3| 1| 1| 800| yes |
|- memcpy.lap_fb.lap_buf.gep | 801| 801| 3| 1| 1| 800| yes |
+-------------------------------+---------+---------+-------------+-----------+-----------+------+----------+



================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 5| 0| 573|
|FIFO | -| -| -| -|
|Instance | 0| 4| 2244| 2804|
|Memory | 8| -| 0| 0|
|Multiplexer | -| -| -| 493|
|Register | -| -| 626| 4|
+-----------------+---------+-------+-------+-------+
|Total | 8| 9| 2870| 3874|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 6| 11| 8| 22|
+-----------------+---------+-------+-------+-------+

+ Detail:
* Instance:
+------------------------------------------+--------------------------------------+---------+-------+-----+-----+
| Instance | Module | BRAM_18K| DSP48E| FF | LUT |
+------------------------------------------+--------------------------------------+---------+-------+-----+-----+
|lap_filter_axim_BUS_AXI4LS_s_axi_U |lap_filter_axim_BUS_AXI4LS_s_axi | 0| 0| 144| 232|
|lap_filter_axim_cam_fb_m_axi_U |lap_filter_axim_cam_fb_m_axi | 0| 0| 512| 580|
|grp_lap_filter_axim_conv_line_fu_431 |lap_filter_axim_conv_line | 0| 3| 122| 139|
|grp_lap_filter_axim_filter_line_fu_420 |lap_filter_axim_filter_line | 0| 1| 204| 523|
|lap_filter_axim_lap_fb_m_axi_U |lap_filter_axim_lap_fb_m_axi | 0| 0| 512| 580|
|lap_filter_axim_urem_12ns_11ns_12_16_U11 |lap_filter_axim_urem_12ns_11ns_12_16 | 0| 0| 375| 375|
|lap_filter_axim_urem_12ns_11ns_12_16_U12 |lap_filter_axim_urem_12ns_11ns_12_16 | 0| 0| 375| 375|
+------------------------------------------+--------------------------------------+---------+-------+-----+-----+
|Total | | 0| 4| 2244| 2804|
+------------------------------------------+--------------------------------------+---------+-------+-----+-----+

* Memory:
+--------------+----------------------------+---------+---+----+------+-----+------+-------------+
| Memory | Module | BRAM_18K| FF| LUT| Words| Bits| Banks| W*Bits*Banks|
+--------------+----------------------------+---------+---+----+------+-----+------+-------------+
|lap_buf_U |lap_filter_axim_lap_buf | 2| 0| 0| 800| 28| 1| 22400|
|line_buf_0_U |lap_filter_axim_line_buf_0 | 2| 0| 0| 800| 32| 1| 25600|
|line_buf_1_U |lap_filter_axim_line_buf_0 | 2| 0| 0| 800| 32| 1| 25600|
|line_buf_2_U |lap_filter_axim_line_buf_0 | 2| 0| 0| 800| 32| 1| 25600|
+--------------+----------------------------+---------+---+----+------+-----+------+-------------+
|Total | | 8| 0| 0| 3200| 124| 4| 99200|
+--------------+----------------------------+---------+---+----+------+-----+------+-------------+

* FIFO:
N/A

* Expression:
+------------------------+----------+-------+---+----+------------+------------+
| Variable Name | Operation| DSP48E| FF| LUT| Bitwidth P0| Bitwidth P1|
+------------------------+----------+-------+---+----+------------+------------+
|mul2_fu_668_p2 | * | 1| 0| 0| 12| 13|
|mul_fu_778_p2 | * | 1| 0| 0| 12| 13|
|tmp_15_fu_691_p2 | * | 1| 0| 0| 10| 10|
|tmp_4_cast_fu_609_p2 | * | 1| 0| 0| 10| 10|
|tmp_4_fu_633_p2 | * | 1| 0| 0| 2| 10|
|a_1_fu_727_p2 | + | 0| 0| 2| 2| 1|
|grp_fu_659_p0 | + | 0| 0| 12| 12| 12|
|indvar_next1_fu_898_p2 | + | 0| 0| 10| 10| 1|
|indvar_next2_fu_648_p2 | + | 0| 0| 10| 10| 1|
|indvar_next3_fu_935_p2 | + | 0| 0| 10| 10| 1|
|indvar_next4_fu_813_p2 | + | 0| 0| 10| 10| 1|
|indvar_next_fu_762_p2 | + | 0| 0| 10| 10| 1|
|line_sel_1_fu_829_p2 | + | 0| 0| 32| 32| 1|
|next_mul_fu_715_p2 | + | 0| 0| 12| 12| 10|
|tmp2_fu_914_p2 | + | 0| 0| 31| 31| 19|
|tmp_10_fu_618_p2 | + | 0| 0| 31| 31| 31|
|tmp_16_fu_737_p2 | + | 0| 0| 31| 31| 31|
|tmp_17_fu_768_p2 | + | 0| 0| 12| 12| 12|
|tmp_fu_479_p2 | + | 0| 0| 31| 31| 10|
|x_1_fu_871_p2 | + | 0| 0| 10| 10| 1|
|y_1_fu_859_p2 | + | 0| 0| 10| 10| 1|
|newSel1_fu_537_p3 | Select | 0| 0| 2| 1| 2|
|newSel2_fu_545_p3 | Select | 0| 0| 3| 1| 1|
|newSel3_fu_563_p3 | Select | 0| 0| 2| 1| 2|
|newSel_fu_529_p3 | Select | 0| 0| 3| 1| 3|
|p_s_fu_851_p3 | Select | 0| 0| 32| 1| 1|
|sel_tmp1_fu_571_p3 | Select | 0| 0| 3| 1| 1|
|sel_tmp3_fu_579_p3 | Select | 0| 0| 3| 1| 3|
|tl_fu_587_p3 | Select | 0| 0| 2| 1| 2|
|ap_sig_bdd_1064 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_1086 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_1093 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_1107 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_1117 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_1123 | and | 0| 0| 1| 1| 1|
|exitcond1_fu_892_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond2_fu_642_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond3_fu_929_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond4_fu_721_p2 | icmp | 0| 0| 2| 2| 2|
|exitcond5_fu_489_p2 | icmp | 0| 0| 11| 10| 10|
|exitcond6_fu_807_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond9_fu_756_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond_fu_865_p2 | icmp | 0| 0| 11| 10| 9|
|icmp_fu_845_p2 | icmp | 0| 0| 38| 30| 1|
|sel_tmp2_fu_501_p2 | icmp | 0| 0| 40| 32| 2|
|sel_tmp4_fu_507_p2 | icmp | 0| 0| 40| 32| 1|
|sel_tmp_fu_495_p2 | icmp | 0| 0| 40| 32| 2|
|tmp_7_fu_599_p2 | icmp | 0| 0| 11| 10| 1|
|or_cond_fu_523_p2 | or | 0| 0| 1| 1| 1|
|not_sel_tmp4_fu_513_p2 | xor | 0| 0| 2| 1| 2|
|not_sel_tmp_fu_553_p2 | xor | 0| 0| 2| 1| 2|
+------------------------+----------+-------+---+----+------------+------------+
|Total | | 5| 0| 573| 535| 289|
+------------------------+----------+-------+---+----+------------+------------+

* Multiplexer:
+---------------------------------------------+----+-----------+-----+-----------+
| Name | LUT| Input Size| Bits| Total Bits|
+---------------------------------------------+----+-----------+-----+-----------+
|a_reg_340 | 2| 2| 2| 4|
|ap_NS_fsm | 66| 38| 1| 38|
|ap_reg_ppiten_pp0_it15 | 1| 2| 1| 2|
|ap_reg_ppiten_pp1_it15 | 1| 2| 1| 2|
|ap_reg_ppiten_pp2_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp3_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp4_it2 | 1| 2| 1| 2|
|ap_sig_ioackin_cam_fb_ARREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_AWREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_WREADY | 1| 2| 1| 2|
|cam_fb_ARADDR | 32| 3| 32| 96|
|grp_lap_filter_axim_conv_line_fu_431_tmp_20 | 2| 3| 2| 6|
|indvar1_reg_397 | 10| 2| 10| 20|
|indvar2_reg_329 | 10| 2| 10| 20|
|indvar3_reg_408 | 10| 2| 10| 20|
|indvar4_reg_375 | 10| 2| 10| 20|
|indvar_reg_364 | 10| 2| 10| 20|
|lap_buf_address0 | 10| 6| 10| 60|
|lap_buf_ce0 | 1| 3| 1| 3|
|lap_buf_d0 | 28| 3| 28| 84|
|lap_buf_we0 | 1| 3| 1| 3|
|lap_fb_AWADDR | 32| 4| 32| 128|
|lap_fb_WDATA | 32| 4| 32| 128|
|line_buf_0_address0 | 10| 3| 10| 30|
|line_buf_0_address1 | 10| 5| 10| 50|
|line_buf_0_ce0 | 1| 3| 1| 3|
|line_buf_0_ce1 | 1| 4| 1| 4|
|line_buf_0_d1 | 32| 3| 32| 96|
|line_buf_0_we1 | 1| 3| 1| 3|
|line_buf_1_address0 | 10| 3| 10| 30|
|line_buf_1_address1 | 10| 5| 10| 50|
|line_buf_1_ce0 | 1| 3| 1| 3|
|line_buf_1_ce1 | 1| 4| 1| 4|
|line_buf_1_d1 | 32| 3| 32| 96|
|line_buf_1_we1 | 1| 3| 1| 3|
|line_buf_2_address0 | 10| 3| 10| 30|
|line_buf_2_address1 | 10| 5| 10| 50|
|line_buf_2_ce0 | 1| 3| 1| 3|
|line_buf_2_ce1 | 1| 4| 1| 4|
|line_buf_2_d1 | 32| 3| 32| 96|
|line_buf_2_we1 | 1| 3| 1| 3|
|line_sel_reg_317 | 32| 2| 32| 64|
|phi_mul_reg_352 | 12| 2| 12| 24|
|x_reg_386 | 10| 2| 10| 20|
|y_reg_305 | 10| 2| 10| 20|
+---------------------------------------------+----+-----------+-----+-----------+
|Total | 493| 166| 428| 1352|
+---------------------------------------------+----+-----------+-----+-----------+

* Register:
+--------------------------------------------------------------+----+----+-----+-----------+
| Name | FF | LUT| Bits| Const Bits|
+--------------------------------------------------------------+----+----+-----+-----------+
|a_1_reg_1059 | 2| 0| 2| 0|
|a_reg_340 | 2| 0| 2| 0|
|ap_CS_fsm | 37| 0| 37| 0|
|ap_reg_ioackin_cam_fb_ARREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_AWREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_WREADY | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it10 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it11 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it12 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it13 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it14 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it15 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it3 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it4 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it5 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it6 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it7 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it8 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it9 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it10 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it11 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it12 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it13 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it14 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it15 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it3 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it4 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it5 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it6 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it7 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it8 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it9 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it2 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond1_reg_1131_pp3_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond3_reg_1155_pp4_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond6_reg_1093_pp2_it1 | 1| 0| 1| 0|
|exitcond1_reg_1131 | 1| 0| 1| 0|
|exitcond3_reg_1155 | 1| 0| 1| 0|
|exitcond4_reg_1055 | 1| 0| 1| 0|
|exitcond6_reg_1093 | 1| 0| 1| 0|
|grp_lap_filter_axim_conv_line_fu_431_ap_start_ap_start_reg | 1| 0| 1| 0|
|grp_lap_filter_axim_filter_line_fu_420_ap_start_ap_start_reg | 1| 0| 1| 0|
|indvar1_reg_397 | 10| 0| 10| 0|
|indvar2_reg_329 | 10| 0| 10| 0|
|indvar3_reg_408 | 10| 0| 10| 0|
|indvar4_reg_375 | 10| 0| 10| 0|
|indvar_reg_364 | 10| 0| 10| 0|
|lap_fb_addr_2_reg_1045 | 32| 0| 32| 0|
|line_sel_reg_317 | 32| 0| 32| 0|
|newSel1_reg_980 | 2| 0| 2| 0|
|newSel3_reg_985 | 2| 0| 2| 0|
|next_mul_reg_1050 | 12| 0| 12| 0|
|offset_cam_addr_cast_reg_951 | 31| 0| 31| 0|
|offset_lap_addr_cast_reg_961 | 31| 0| 31| 0|
|p_s_reg_1107 | 32| 0| 32| 0|
|phi_mul_reg_352 | 12| 0| 12| 0|
|reg_440 | 32| 0| 32| 0|
|reg_447 | 28| 0| 28| 0|
|tl_cast47_cast_reg_996 | 2| 0| 12| 10|
|tl_reg_990 | 2| 0| 2| 0|
|tmp2_reg_1145 | 31| 0| 31| 0|
|tmp_10_reg_1010 | 31| 0| 31| 0|
|tmp_12_reg_1035 | 12| 0| 12| 0|
|tmp_16_reg_1064 | 31| 0| 31| 0|
|tmp_29_t_reg_1041 | 2| 0| 2| 0|
|tmp_3_reg_956 | 30| 0| 30| 0|
|tmp_41_t_reg_1089 | 2| 0| 2| 0|
|tmp_4_cast_reg_1005 | 14| 0| 19| 5|
|tmp_4_reg_1021 | 7| 0| 12| 5|
|tmp_7_reg_1001 | 1| 0| 1| 0|
|tmp_reg_967 | 31| 0| 31| 0|
|x_reg_386 | 10| 0| 10| 0|
|y_1_reg_1112 | 10| 0| 10| 0|
|y_cast48_cast_reg_972 | 10| 0| 21| 11|
|y_reg_305 | 10| 0| 10| 0|
|tmp_29_t_reg_1041 | 0| 2| 2| 0|
|tmp_41_t_reg_1089 | 0| 2| 2| 0|
+--------------------------------------------------------------+----+----+-----+-----------+
|Total | 626| 4| 661| 31|
+--------------------------------------------------------------+----+----+-----+-----------+



================================================================
== Interface
================================================================
* Summary:
+--------------------------+-----+-----+------------+-----------------+--------------+
| RTL Ports | Dir | Bits| Protocol | Source Object | C Type |
+--------------------------+-----+-----+------------+-----------------+--------------+
|s_axi_BUS_AXI4LS_AWVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WDATA | in | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WSTRB | in | 4| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RDATA | out | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|ap_clk | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|ap_rst_n | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|interrupt | out | 1| ap_ctrl_hs | lap_filter_axim | return value |
|m_axi_cam_fb_AWVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WDATA | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WSTRB | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WLAST | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RDATA | in | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RLAST | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_lap_fb_AWVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WDATA | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WSTRB | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WLAST | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RDATA | in | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RLAST | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RUSER | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BUSER | in | 1| m_axi | lap_fb | pointer |
+--------------------------+-----+-----+------------+-----------------+--------------+


  1. 2015年03月30日 05:05 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化3(PIPELINEディレクティブを実機テスト)

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化2(PIPELINEディレクティブ)”の続き。

前回、PIPELINEディレクティブを入れて、高位合成したラプラシアンフィルタIP をシミュレーション用のVivado 2014.4 プロジェクトに入れてシミュレーションを行ったところ、速度が 30% 程度改善した。
今回は、ZYBOでラプラシアンフィルタIP をテストして、実際にどのくらい速度が改善したか?を検証してみた。

V_ZYBO_CAMD143 プロジェクト(Vivado 2014.4のプロジェクトに変換済み)を使用して、ラプラシアンフィルタIP をPIPELINEディレクティブを入れて、高位合成したラプラシアンフィルタIP に書き換えた。

IP Status がレポートされて、ラプラシアンフィルタIP を更新したところだ。
lap_filter_axim_0 が変更されているというレポートが出ているが、すでに更新したので、表示を更新するためにRerun をクリックした。
lap_fil_hls_14_4_45_150324.png

ラプラシアンフィルタIP が更新された。
lap_fil_hls_14_4_46_150324.png

論理合成、インプリメント、ビットストリームの生成を行った。成功した。
lap_fil_hls_14_4_47_150324.png

ハードウェアをエクスポートして、SDKが立ち上がり、リビルドが自動的に行われた。
lap_fil_hls_14_4_48_150324.png

BOOT.bin の生成を行った。
lap_fil_hls_14_4_49_150324.png

出来上がったBOOT.bin をMicro SDカードに書いて、ZYBO のスロットに挿入して電源をONした。

SSH からログインして、最初にラプラシアンフィルタ全体の処理時間を計測したところ、約 71.4 ms だった。
次に、ラプラシアンフィルタ処理時間のみを計測してみたところ、約 60.0 ms だった。
lap_fil_hls_14_4_50_150324.png

高速化無しの状態でのラプラシアンフィルタ処理時間は、全体経過時間で約 95.4 ms、ラプラシアンフィルタ処理時間のみでは、約 80 ms だったので、約 1.33倍に高速化された。

ちなみに、完全にソフトウェアでラプラシアンフィルタ処理を行った場合は、約 455.7 ms だったので、Vivado HLS 2014.4 でラプラシアンフィルタ処理を行った場合の約 71.1 ms に比べると、6.41倍に高速化された。
lap_fil_hls_14_4_51_150324.png
  1. 2015年03月27日 04:14 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

娘の学位記授与式(卒業式)に行ってきました

(いささか、前にタイムスリップしますが、)娘の学位記授与式に出席するために仙台まで車で行ってきました。

つくばを出て常磐道へ入りました。今回は、常磐道をずっと宮城県まで乗って行く予定です。怖い物見たさというか、福島第一原発の近くを見たいという気持ちでした。
いわき市を過ぎて、ずっと行って楢葉町辺りなんでしょうか?両側に大量の黒い袋が積んであって、緑色のビニルシートがかぶせてあるところがありましたが、これが放射性の表土を剥ぎとったものが入った黒い袋のようです。
それとは別に畑のところに置いてある黒い袋もありました。これは大量ではなかったので、畑の表土を剥ぎとったばかりなんでしょうか?

放射線の強度は電光掲示板で表示されていますが、最高は5.4 uSv/h でした。結構高いようですが、走り抜けるので、影響は無いでしょう?この高い地域は1箇所だけで、他は1つ1 uSv/h 台があっただけで、後は 0.いくつ uSv/h 台でした。

放射線強度が高いところの家々は人が住んでいない感じでした。屋根が壊れたままで、窓が開いている建物もありました。震災当時を思い出しました。帰れない方々は大変だと思います。

この辺りと言うか、いわきから先は片側1車線で最高速度も 80km/h に制限されています。

車で走っていると、仙台東部道路にいつの間にか乗っていて、その後、仙台南部道路を通って、東北道に乗り、いつもの通りに仙台宮城インターで降りました。本当は、仙台南部道路で長町インターで降りれば良かったのかもしれませんが、道が分からないので、遠回りになりました。高速料金は6千6百円位だったです。長町インターまででも300kmを超えていたので、矢板から東北道の方が距離は近いようです。

仙台市内の駐車場に車を置いて、仙台市体育館に地下鉄に乗って向かいました。
touhoku_univ_sotugyoushiki_1_150325.jpg

行ってみると東北大学の学位記授与式が始まっていました。ものすごく広い体育館です。約1万人くらい入れるそうです。3階席に行くと、ひな壇にいる人が豆粒のようです。卒業生は学部、大学院合わせて4千6百人くらいでした。それに父兄がいますから、やはり約1万人は入っているでしょう。
touhoku_univ_sotugyoushiki_2_150325.jpg

体育館で卒業式をやるということで、とっても寒いんだろうと覚悟していったんですが、とっても暑かったです。30度位あったんじゃないでしょうか?サウナ状態でした。一番上の方なので、熱い空気が上がってきているんだと思いますが、下にいた娘も暑かったそうです。もう少し暖房を控えめにして欲しかったです。

学位記授与式も終わり、振り袖袴姿の娘と会えました。とっても綺麗で良かったです。娘と奥さんと私の3人で記念写真も取ってもらいました。

仙台市内に戻って、娘と食事をしました。美味しいオムライスの店ということで、オムハヤシライスを頼んだんですが、卵液にご飯を混ぜて焼いた様です。卵の間にご飯が入っているようなオムライスでした。フワフワでとっても美味しかったです。いくらでも行けそうですね。
touhoku_univ_sotugyoushiki_3_150325.jpg
  1. 2015年03月25日 20:26 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化2(PIPELINEディレクティブ)

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化1(割り算を削除)”の続き。

前回は、ラプラシアンフィルタ処理の高速化として割り算使った剰余演算をカウンタに置き換えた。
今回はPIPELINEディレクティブを使用して高速化を試みる。

Vivado HLS 2014.4 のラプラシアンフィルタのプロジェクトで、PIPELINEディレクティブをCソースコードに追加する。

Vivado HLS の右側のウインドウで、Directive タブをクリックする。

for Statement が表示されているので、一番中のfor ループのfor Statement を右クリックして、Insert Directive... を選択した。
lap_fil_hls_14_4_30_150322.png

Vivado HLS Directive Editor が表示された。

Directive でPIPELINE をDestination でSource Files を選択した。Destination でSource Files を選択すると、ディレクティブがソースファイルに書かれる。Directive File を選択するとディレクティブ用のファイルが作られる。
lap_fil_hls_14_4_31_150322.png

Directive タブのfor Statement にHLS PIPELINE が入った。ソースコードには、

#pragma HLS PIPELINE

が入った。
lap_fil_hls_14_4_32_150322.png

Directive タブのつぎのfor Statement にHLS PIPELINE を定義して、これでPIPELINE ディレクティブの設定は終わりにした。
lap_fil_hls_14_4_33_150323.png

高位合成、IP 化を行った。下に高位合成時のレポートの一部を示す。
lap_fil_hls_14_4_43_150323.png

ラプラシアンフィルタ・シミュレーション用のVivado 2014.4 プロジェクトのラプラシアンフィルタIP と交換して、シミュレーションを行った。その結果のシミュレーション波形を下に示す。
lap_fil_hls_14_4_44_150323.png

DMA Write 間の間隔が、91.86 us になった。最初のシミュレーション波形でのDMA Write 間の間隔は、131.95 us だった。
131.95 us からでは、

(131.95 - 91.86) / 131.95 x 100 ≒ 30.4 %

の改善となった。
ラプラシアンフィルタ処理時間は

91.86 us x 600 行 = 55116 us ≒ 55.12 ms

になるだろう?

laplacian_filter.c を貼っておく。

// laplacian_filter.c
// lap_filter_axim()

#include <stdio.h>
#include <string.h>

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS INTERFACE s_axilite port=cam_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=lap_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=return bundle=BUS_AXI4LS
    #pragma HLS INTERFACE ap_none port=cam_addr
    #pragma HLS INTERFACE ap_none port=lap_addr

    #pragma HLS INTERFACE m_axi port=cam_fb depth=1920
    #pragma HLS INTERFACE m_axi port=lap_fb depth=1920

    unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
    unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH];
    int x, y;
    int lap_fil_val;
    int a, b;
    int fl, sl, tl;
    unsigned int offset_cam_addr, offset_lap_addr;
    int *cam_fb_addr, *lap_fb_addr;
    int line_sel;

    offset_cam_addr = cam_addr/sizeof(int);
    offset_lap_addr = lap_addr/sizeof(int);
    
    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0, line_sel=0; y<VERTICAL_PIXEL_WIDTH; y++){
        // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        switch(line_sel){
            case 1 :
                fl = 0; sl = 1; tl = 2;
                break;
            case 2 :
                fl = 1; sl = 2; tl = 0;
                break;
            case 3 :
                fl = 2; sl = 0; tl = 1;
                break;
            default :
                fl = 0; sl = 1; tl = 2;
        }

        //fl = (y-1)%3;    // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        //sl = y%3;        // 2番めのライン
        //tl = (y+1)%3;    // 3番目のライン
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
                lap_fil_val = 0;
            }else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
                lap_fil_val = 0;
            }else{
                 if (x == 1){ // ラインの最初でラインの画素を読み出す
                    if (y == 1){ // 最初のラインでは3ライン分の画素を読み出す
                        for (a=0; a<3; a++){ // 3ライン分
                            cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH)));
                            memcpy(&line_buf[a][0], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                            for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){
#pragma HLS PIPELINE
 // ライン
                                line_buf[a][b] = conv_rgb2y(line_buf[a][b]);    // カラーから白黒へ
                            }
                        }
                    } else { // 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている
                        cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH)));
                         memcpy(line_buf[tl], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                        for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){
#pragma HLS PIPELINE
 // ライン
                            line_buf[tl][b] = conv_rgb2y(line_buf[tl][b]);    // カラーから白黒へ
                        }
                    }
                }
                lap_fil_val = laplacian_fil(line_buf[fl][x-1], line_buf[fl][x], line_buf[fl][x+1], line_buf[sl][x-1], line_buf[sl][x], line_buf[sl][x+1], line_buf[tl][x-1], line_buf[tl][x], line_buf[tl][x+1]);
            }
            lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
        }
        lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH)));
        memcpy(lap_fb_addr, (const int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));

        line_sel++;
        if (line_sel > 3){
            line_sel = 1;
        }
    }
    return(1);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8// 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}



割り算を削除した前回の高位合成結果の内のUtilization Estimates を示す。

================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 1080|
|FIFO | -| -| -| -|
|Instance | 0| -| 1168| 1392|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 401|
|Register | -| -| 1086| -|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2254| 2873|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 6| 16|
+-----------------+---------+-------+-------+-------+


PIPELINEディレクティブを2つ追加した今回の高位合成結果の内のUtilization Estimates を示す。

================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 1080|
|FIFO | -| -| -| -|
|Instance | 0| -| 1168| 1392|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 385|
|Register | -| -| 1097| 34|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2265| 2891|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 6| 16|
+-----------------+---------+-------+-------+-------+


FF とLUT が多少増えている。

最後に高位合成時のレポートを貼っておく。

================================================================
== Vivado HLS Report for 'lap_filter_axim'
================================================================
* Date: Mon Mar 23 05:08:39 2015

* Version: 2014.4 (Build 1071461 on Tue Nov 18 16:42:57 PM 2014)
* Project: lap_filter_axim_2014_4
* Solution: solution1
* Product family: zynq
* Target device: xc7z010clg400-1


================================================================
== Performance Estimates
================================================================
+ Timing (ns):
* Summary:
+---------+-------+----------+------------+
| Clock | Target| Estimated| Uncertainty|
+---------+-------+----------+------------+
|default | 10.00| 8.75| 1.25|
+---------+-------+----------+------------+

+ Latency (clock cycles):
* Summary:
+---------+------------+---------+------------+---------+
| Latency | Interval | Pipeline|
| min | max | min | max | Type |
+---------+------------+---------+------------+---------+
| 1445401| 2329445401| 1445402| 2329445402| none |
+---------+------------+---------+------------+---------+

+ Detail:
* Instance:
N/A

* Loop:
+------------------------------+---------+------------+----------------+-----------+-----------+------+----------+
| | Latency | Iteration | Initiation Interval | Trip | |
| Loop Name | min | max | Latency | achieved | target | Count| Pipelined|
+------------------------------+---------+------------+----------------+-----------+-----------+------+----------+
|- Loop 1 | 1445400| 2329445400| 2409 ~ 3882409 | -| -| 600| no |
| + Loop 1.1 | 1600| 3881600| 2 ~ 4852 | -| -| 800| no |
| ++ Loop 1.1.1 | 4842| 4842| 1614| -| -| 3| no |
| +++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| +++ Loop 1.1.1.2 | 804| 804| 6| 1| 1| 800| yes |
| ++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| ++ Loop 1.1.3 | 804| 804| 6| 1| 1| 800| yes |
| + memcpy.lap_fb.lap_buf.gep | 801| 801| 3| 1| 1| 800| yes |
+------------------------------+---------+------------+----------------+-----------+-----------+------+----------+



================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 1080|
|FIFO | -| -| -| -|
|Instance | 0| -| 1168| 1392|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 385|
|Register | -| -| 1097| 34|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2265| 2891|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 6| 16|
+-----------------+---------+-------+-------+-------+

+ Detail:
* Instance:
+------------------------------------+----------------------------------+---------+-------+-----+-----+
| Instance | Module | BRAM_18K| DSP48E| FF | LUT |
+------------------------------------+----------------------------------+---------+-------+-----+-----+
|lap_filter_axim_BUS_AXI4LS_s_axi_U |lap_filter_axim_BUS_AXI4LS_s_axi | 0| 0| 144| 232|
|lap_filter_axim_cam_fb_m_axi_U |lap_filter_axim_cam_fb_m_axi | 0| 0| 512| 580|
|lap_filter_axim_lap_fb_m_axi_U |lap_filter_axim_lap_fb_m_axi | 0| 0| 512| 580|
+------------------------------------+----------------------------------+---------+-------+-----+-----+
|Total | | 0| 0| 1168| 1392|
+------------------------------------+----------------------------------+---------+-------+-----+-----+

* Memory:
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
| Memory | Module | BRAM_18K| FF| LUT| Words| Bits| Banks| W*Bits*Banks|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|lap_buf_U |lap_filter_axim_lap_buf | 2| 0| 0| 800| 24| 1| 19200|
|line_buf_U |lap_filter_axim_line_buf | 8| 0| 0| 2400| 32| 1| 76800|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|Total | | 10| 0| 0| 3200| 56| 2| 96000|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+

* FIFO:
N/A

* Expression:
+--------------------------+----------+-------+---+----+------------+------------+
| Variable Name | Operation| DSP48E| FF| LUT| Bitwidth P0| Bitwidth P1|
+--------------------------+----------+-------+---+----+------------+------------+
|p_addr1_fu_695_p2 | * | 1| 0| 0| 2| 10|
|p_addr3_fu_704_p2 | * | 1| 0| 0| 2| 10|
|p_addr_fu_686_p2 | * | 1| 0| 0| 2| 10|
|tmp_2_fu_677_p2 | * | 1| 0| 0| 2| 10|
|tmp_38_i8_fu_873_p2 | * | 1| 0| 0| 8| 7|
|tmp_38_i_fu_1030_p2 | * | 1| 0| 0| 8| 7|
|tmp_39_i9_fu_845_p2 | * | 1| 0| 0| 8| 8|
|tmp_39_i_fu_1002_p2 | * | 1| 0| 0| 8| 8|
|tmp_40_i1_fu_854_p2 | * | 1| 0| 0| 8| 5|
|tmp_40_i_fu_1011_p2 | * | 1| 0| 0| 8| 5|
|y_i16_op_cast_fu_1230_p2 | * | 1| 0| 1| 24| 17|
|a_1_fu_916_p2 | + | 0| 0| 2| 2| 1|
|b_2_fu_973_p2 | + | 0| 0| 10| 10| 1|
|b_fu_817_p2 | + | 0| 0| 10| 10| 1|
|indvar_next1_fu_1263_p2 | + | 0| 0| 10| 10| 1|
|indvar_next2_fu_796_p2 | + | 0| 0| 10| 10| 1|
|indvar_next_fu_951_p2 | + | 0| 0| 10| 10| 1|
|line_sel_1_fu_1278_p2 | + | 0| 0| 32| 32| 1|
|next_mul1_fu_546_p2 | + | 0| 0| 19| 19| 10|
|next_mul2_fu_898_p2 | + | 0| 0| 12| 12| 10|
|next_mul_fu_904_p2 | + | 0| 0| 12| 12| 10|
|p_addr10_fu_1091_p2 | + | 0| 0| 12| 12| 12|
|p_addr11_fu_1125_p2 | + | 0| 0| 12| 12| 12|
|p_addr12_fu_1101_p2 | + | 0| 0| 12| 12| 12|
|p_addr13_fu_1116_p2 | + | 0| 0| 12| 12| 12|
|p_addr2_fu_1142_p2 | + | 0| 0| 12| 12| 12|
|p_addr4_fu_1064_p2 | + | 0| 0| 12| 12| 12|
|p_addr5_fu_1138_p2 | + | 0| 0| 12| 12| 12|
|p_addr6_fu_827_p2 | + | 0| 0| 12| 12| 12|
|p_addr7_fu_1078_p2 | + | 0| 0| 12| 12| 12|
|p_addr8_fu_1134_p2 | + | 0| 0| 12| 12| 12|
|p_addr9_fu_983_p2 | + | 0| 0| 12| 12| 12|
|sum2_i_fu_1166_p2 | + | 0| 0| 16| 32| 32|
|tmp21_fu_1110_p2 | + | 0| 0| 32| 32| 32|
|tmp22_fu_1146_p2 | + | 0| 0| 32| 32| 32|
|tmp_12_fu_957_p2 | + | 0| 0| 12| 12| 12|
|tmp_19_fu_1055_p2 | + | 0| 0| 11| 11| 2|
|tmp_37_fu_768_p2 | + | 0| 0| 31| 31| 31|
|tmp_39_fu_926_p2 | + | 0| 0| 31| 31| 31|
|tmp_8_fu_772_p2 | + | 0| 0| 31| 31| 31|
|tmp_fu_540_p2 | + | 0| 0| 31| 31| 10|
|tmp_s_fu_802_p2 | + | 0| 0| 12| 12| 12|
|x_1_fu_720_p2 | + | 0| 0| 10| 10| 1|
|y_1_fu_558_p2 | + | 0| 0| 10| 10| 1|
|sum3_neg_i_fu_1170_p2 | - | 0| 0| 16| 32| 32|
|tmp_42_i_fu_1186_p2 | - | 0| 0| 32| 32| 32|
|tmp_43_i_fu_1191_p2 | - | 0| 0| 32| 32| 32|
|tmp_i1_fu_1176_p2 | - | 0| 0| 32| 32| 32|
|y_4_fu_1197_p2 | - | 0| 0| 32| 32| 32|
|newSel2_fu_606_p3 | Select | 0| 0| 3| 1| 1|
|newSel_fu_598_p3 | Select | 0| 0| 3| 1| 3|
|p_s_fu_1300_p3 | Select | 0| 0| 32| 1| 1|
|phitmp_fu_1235_p3 | Select | 0| 0| 24| 1| 2|
|sel_tmp1_fu_624_p3 | Select | 0| 0| 3| 1| 1|
|sel_tmp3_fu_632_p3 | Select | 0| 0| 3| 1| 3|
|tl_fu_640_p3 | Select | 0| 0| 2| 1| 2|
|tmp_5_fu_648_p3 | Select | 0| 0| 2| 1| 2|
|tmp_6_fu_656_p3 | Select | 0| 0| 2| 1| 2|
|ap_sig_bdd_1016 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_368 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_389 | and | 0| 0| 1| 1| 1|
|exitcond1_fu_1257_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond2_fu_790_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond3_fu_967_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond4_fu_910_p2 | icmp | 0| 0| 2| 2| 2|
|exitcond5_fu_714_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond6_fu_552_p2 | icmp | 0| 0| 11| 10| 10|
|exitcond7_fu_945_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond_fu_811_p2 | icmp | 0| 0| 11| 10| 9|
|icmp1_fu_1294_p2 | icmp | 0| 0| 38| 30| 1|
|icmp_fu_1220_p2 | icmp | 0| 0| 30| 24| 1|
|sel_tmp2_fu_570_p2 | icmp | 0| 0| 40| 32| 2|
|sel_tmp4_fu_576_p2 | icmp | 0| 0| 40| 32| 1|
|sel_tmp_fu_564_p2 | icmp | 0| 0| 40| 32| 2|
|tmp_13_fu_726_p2 | icmp | 0| 0| 11| 10| 10|
|tmp_23_fu_732_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_32_fu_744_p2 | icmp | 0| 0| 11| 10| 9|
|tmp_34_fu_750_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_4_fu_667_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_7_fu_762_p2 | icmp | 0| 0| 11| 10| 1|
|or_cond_fu_592_p2 | or | 0| 0| 1| 1| 1|
|tmp_31_fu_738_p2 | or | 0| 0| 1| 1| 1|
|tmp_35_fu_756_p2 | or | 0| 0| 1| 1| 1|
|not_sel_tmp4_fu_582_p2 | xor | 0| 0| 2| 1| 2|
|not_sel_tmp_fu_614_p2 | xor | 0| 0| 2| 1| 2|
+--------------------------+----------+-------+---+----+------------+------------+
|Total | | 11| 0|1080| 1073| 776|
+--------------------------+----------+-------+---+----+------------+------------+

* Multiplexer:
+-------------------------------+----+-----------+-----+-----------+
| Name | LUT| Input Size| Bits| Total Bits|
+-------------------------------+----+-----------+-----+-----------+
|a_reg_391 | 2| 2| 2| 4|
|ap_NS_fsm | 60| 35| 1| 35|
|ap_reg_ppiten_pp0_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp1_it5 | 1| 2| 1| 2|
|ap_reg_ppiten_pp2_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp3_it5 | 1| 2| 1| 2|
|ap_reg_ppiten_pp4_it2 | 1| 2| 1| 2|
|ap_sig_ioackin_cam_fb_ARREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_AWREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_WREADY | 1| 2| 1| 2|
|b1_reg_437 | 10| 2| 10| 20|
|b_1_reg_380 | 10| 2| 10| 20|
|cam_fb_ARADDR | 32| 3| 32| 96|
|indvar1_reg_466 | 10| 2| 10| 20|
|indvar2_reg_369 | 10| 2| 10| 20|
|indvar_reg_426 | 10| 2| 10| 20|
|lap_buf_address0 | 10| 3| 10| 30|
|lap_fil_val_1_phi_fu_452_p8 | 24| 2| 24| 48|
|lap_fil_val_1_reg_448 | 24| 2| 24| 48|
|line_buf_address0 | 24| 9| 12| 108|
|line_buf_address1 | 24| 8| 12| 96|
|line_buf_d1 | 32| 4| 32| 128|
|line_sel_reg_333 | 32| 2| 32| 64|
|phi_mul1_reg_345 | 19| 2| 19| 38|
|phi_mul2_reg_414 | 12| 2| 12| 24|
|phi_mul_reg_402 | 12| 3| 12| 36|
|x_reg_357 | 10| 2| 10| 20|
|y_reg_321 | 10| 2| 10| 20|
+-------------------------------+----+-----------+-----+-----------+
|Total | 385| 107| 302| 911|
+-------------------------------+----+-----------+-----+-----------+

* Register:
+-----------------------------------------+----+----+-----+-----------+
| Name | FF | LUT| Bits| Const Bits|
+-----------------------------------------+----+----+-----+-----------+
|a_1_reg_1493 | 2| 0| 2| 0|
|a_reg_391 | 2| 0| 2| 0|
|ap_CS_fsm | 34| 0| 34| 0|
|ap_reg_ioackin_cam_fb_ARREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_AWREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_WREADY | 1| 0| 1| 0|
|ap_reg_phibuf_phi_mul_reg_402 | 12| 0| 12| 0|
|ap_reg_ppiten_pp0_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it3 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it4 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it5 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it3 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it4 | 1| 0| 1| 0|
|ap_reg_ppiten_pp3_it5 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp4_it2 | 1| 0| 1| 0|
|ap_reg_ppstg_b_3_reg_1460_pp1_it2 | 8| 0| 8| 0|
|ap_reg_ppstg_b_4_reg_1538_pp3_it2 | 8| 0| 8| 0|
|ap_reg_ppstg_exitcond1_reg_1680_pp4_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond2_reg_1431_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond7_reg_1509_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_tmp_12_reg_1518_pp2_it1 | 12| 0| 12| 0|
|ap_reg_ppstg_tmp_s_reg_1440_pp0_it1 | 12| 0| 12| 0|
|b1_reg_437 | 10| 0| 10| 0|
|b_1_reg_380 | 10| 0| 10| 0|
|b_3_reg_1460 | 8| 0| 8| 0|
|b_4_reg_1538 | 8| 0| 8| 0|
|exitcond1_reg_1680 | 1| 0| 1| 0|
|exitcond2_reg_1431 | 1| 0| 1| 0|
|exitcond3_reg_1523 | 1| 0| 1| 0|
|exitcond7_reg_1509 | 1| 0| 1| 0|
|exitcond_reg_1445 | 1| 0| 1| 0|
|icmp_reg_1660 | 1| 0| 1| 0|
|indvar1_reg_466 | 10| 0| 10| 0|
|indvar2_reg_369 | 10| 0| 10| 0|
|indvar_reg_426 | 10| 0| 10| 0|
|lap_buf_load_reg_1694 | 24| 0| 24| 0|
|lap_fil_val_1_reg_448 | 24| 0| 24| 0|
|line_buf_addr_2_reg_1454 | 12| 0| 12| 0|
|line_buf_addr_3_reg_1532 | 12| 0| 12| 0|
|line_sel_reg_333 | 32| 0| 32| 0|
|next_mul1_reg_1323 | 19| 0| 19| 0|
|next_mul2_reg_1480 | 12| 0| 12| 0|
|next_mul_reg_1485 | 12| 0| 12| 0|
|offset_cam_addr_cast_reg_1308 | 31| 0| 31| 0|
|offset_lap_addr_cast_reg_1313 | 31| 0| 31| 0|
|p_addr1_reg_1375 | 7| 0| 12| 5|
|p_addr2_reg_1621 | 12| 0| 12| 0|
|p_addr3_reg_1382 | 7| 0| 12| 5|
|p_addr5_reg_1616 | 12| 0| 12| 0|
|p_addr8_reg_1611 | 12| 0| 12| 0|
|p_addr_reg_1367 | 7| 0| 12| 5|
|p_s_reg_1699 | 32| 0| 32| 0|
|phi_mul1_reg_345 | 19| 0| 19| 0|
|phi_mul2_reg_414 | 12| 0| 12| 0|
|phi_mul_reg_402 | 12| 0| 12| 0|
|phitmp_reg_1670 | 24| 0| 24| 0|
|reg_498 | 32| 0| 32| 0|
|reg_504 | 8| 0| 8| 0|
|reg_508 | 8| 0| 8| 0|
|tl_reg_1336 | 2| 0| 2| 0|
|tmp18_reg_1470 | 16| 0| 16| 0|
|tmp19_reg_1548 | 16| 0| 16| 0|
|tmp21_reg_1596 | 32| 0| 32| 0|
|tmp22_reg_1626 | 32| 0| 32| 0|
|tmp_12_reg_1518 | 12| 0| 12| 0|
|tmp_2_reg_1362 | 7| 0| 12| 5|
|tmp_31_reg_1403 | 1| 0| 1| 0|
|tmp_33_trn_cast_reg_1558 | 11| 0| 12| 1|
|tmp_34_trn_cast_reg_1569 | 10| 0| 12| 2|
|tmp_35_reg_1407 | 1| 0| 1| 0|
|tmp_36_trn_cast_reg_1580 | 10| 0| 12| 2|
|tmp_37_reg_1415 | 31| 0| 31| 0|
|tmp_39_i9_reg_1465 | 15| 0| 16| 1|
|tmp_39_i_reg_1543 | 15| 0| 16| 1|
|tmp_39_reg_1498 | 31| 0| 31| 0|
|tmp_43_i_reg_1651 | 32| 0| 32| 0|
|tmp_44_reg_1656 | 1| 0| 1| 0|
|tmp_46_reg_1665 | 24| 0| 24| 0|
|tmp_4_reg_1352 | 1| 0| 1| 0|
|tmp_5_cast1_reg_1356 | 19| 0| 31| 12|
|tmp_5_reg_1342 | 2| 0| 2| 0|
|tmp_6_reg_1347 | 2| 0| 2| 0|
|tmp_8_reg_1420 | 31| 0| 31| 0|
|tmp_i1_reg_1641 | 32| 0| 32| 0|
|tmp_reg_1318 | 31| 0| 31| 0|
|tmp_s_reg_1440 | 12| 0| 12| 0|
|x_1_reg_1397 | 10| 0| 10| 0|
|x_cast_reg_1389 | 10| 0| 11| 1|
|x_reg_357 | 10| 0| 10| 0|
|y_1_reg_1331 | 10| 0| 10| 0|
|y_2_reg_1475 | 8| 0| 8| 0|
|y_3_reg_1553 | 8| 0| 8| 0|
|y_reg_321 | 10| 0| 10| 0|
|exitcond3_reg_1523 | 0| 1| 1| 0|
|exitcond_reg_1445 | 0| 1| 1| 0|
|line_buf_addr_2_reg_1454 | 0| 12| 12| 0|
|line_buf_addr_3_reg_1532 | 0| 12| 12| 0|
|reg_508 | 0| 8| 8| 0|
+-----------------------------------------+----+----+-----+-----------+
|Total |1097| 34| 1171| 40|
+-----------------------------------------+----+----+-----+-----------+



================================================================
== Interface
================================================================
* Summary:
+--------------------------+-----+-----+------------+-----------------+--------------+
| RTL Ports | Dir | Bits| Protocol | Source Object | C Type |
+--------------------------+-----+-----+------------+-----------------+--------------+
|s_axi_BUS_AXI4LS_AWVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WDATA | in | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WSTRB | in | 4| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RDATA | out | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|ap_clk | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|ap_rst_n | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|interrupt | out | 1| ap_ctrl_hs | lap_filter_axim | return value |
|m_axi_cam_fb_AWVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WDATA | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WSTRB | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WLAST | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RDATA | in | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RLAST | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_lap_fb_AWVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WDATA | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WSTRB | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WLAST | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RDATA | in | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RLAST | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RUSER | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BUSER | in | 1| m_axi | lap_fb | pointer |
+--------------------------+-----+-----+------------+-----------------+--------------+

  1. 2015年03月23日 05:37 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:2

Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化1(割り算を削除)

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)
ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル4(うまく行った)
で、Vivado HLS 2014.4 で合成したラプラシアンフィルタIP が動作した。

今回は、Vivado HLS のAnalysis 画面を見ながら、高速化を試みる。

Vivado HLS 2014.4 でAnalysis ボタンをクリックし、更に、Recource - lap_filter_axim タブのRecource タブをクリックする。
すると、lap_filter_axim_srem_11ns_3ns_11_15_seq_U0 がクロックを消費しているように見える。
これはCソースコードの何処なのかを知るために、lap_filter_axim_srem_11ns_3ns_11_15_seq_U0 のsrem で右クリックして、右クリックメニューからGoto Source を選択する。
lap_fil_hls_14_4_34_150322.png

右にCソースコードが表示された。該当する行がハイライトされている。
lap_fil_hls_14_4_35_150322.png

該当する行は

fl = (y-1)%3;

だった。
次に、、lap_filter_axim_srem_11ns_3ns_11_15_seq_U0 で右クリックし、右クリックメニューからGoto Verilog を選択する。
lap_fil_hls_14_4_36_150322.png

すると、該当する Verilog コードが表示される。
lap_fil_hls_14_4_37_150322.png

それは、lap_filter_axim_srem_11ns_3ns_11_15_seq.v にある lap_filter_axim_srem_11ns_3ns_11_15_seq_div モジュールを呼んでいる。つまり、割り算をしていた訳だ。

割り算をするとクロックが余計に必要になるので、カウンタで代用することにした。
int line_sel; を定義して、最初は 0 に設定し、その後は、1、2、3 と進んで、その後は 1 に戻る。
lap_fil_hls_14_4_39_150322.png

lap_fil_hls_14_4_40_150322.png

これで高位合成し、IP 化も行った。

シミュレーション環境に持って行って、Vivado HLS 2014.4 のラプラシアンフィルタIP と入れ替え、IP を更新して、論理シミュレーションを行った。下に論理シミュレーションの波形を示す。
lap_fil_hls_14_4_42_150322.png

DMA Write 間の時間は、131.81 us だった。
Cソースコードの修正前は、131.95 us だったので、140 ns の改善ということになる。100MHzクロックなので 14 クロックだ。以前の論理シミュレーション波形を下に示す。
lap_fil_hls_14_4_27_150321.png

ざっと計算して 1% 程度の改善にしかならなかった。割り算はそれ自体はクロックを消費しても、DMA Write 1回について 1回なので、このような結果になった。アムダールの法則を実感してしまった。
内部のループが圧倒的にクロックを消費しているので、そこを改善しないと効果が薄い。。。

Cソースコード (laplacian_filter.c) を貼っておく。

// laplacian_filter.c
// lap_filter_axim()

#include <stdio.h>
#include <string.h>

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS INTERFACE s_axilite port=cam_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=lap_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=return bundle=BUS_AXI4LS
    #pragma HLS INTERFACE ap_none port=cam_addr
    #pragma HLS INTERFACE ap_none port=lap_addr

    #pragma HLS INTERFACE m_axi port=cam_fb depth=1920
    #pragma HLS INTERFACE m_axi port=lap_fb depth=1920

    unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
    unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH];
    int x, y;
    int lap_fil_val;
    int a, b;
    int fl, sl, tl;
    unsigned int offset_cam_addr, offset_lap_addr;
    int *cam_fb_addr, *lap_fb_addr;
    int line_sel;

    offset_cam_addr = cam_addr/sizeof(int);
    offset_lap_addr = lap_addr/sizeof(int);
    
    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0, line_sel=0; y<VERTICAL_PIXEL_WIDTH; y++){
        // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        switch(line_sel){
            case 1 :
                fl = 0; sl = 1; tl = 2;
                break;
            case 2 :
                fl = 1; sl = 2; tl = 0;
                break;
            case 3 :
                fl = 2; sl = 0; tl = 1;
                break;
            default :
                fl = 0; sl = 1; tl = 2;
        }

        //fl = (y-1)%3;    // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        //sl = y%3;        // 2番めのライン
        //tl = (y+1)%3;    // 3番目のライン
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
                lap_fil_val = 0;
            }else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
                lap_fil_val = 0;
            }else{
                 if (x == 1){ // ラインの最初でラインの画素を読み出す
                    if (y == 1){ // 最初のラインでは3ライン分の画素を読み出す
                        for (a=0; a<3; a++){ // 3ライン分
                            cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH)));
                            memcpy(&line_buf[a][0], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                            for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                                line_buf[a][b] = conv_rgb2y(line_buf[a][b]);    // カラーから白黒へ
                            }
                        }
                    } else { // 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている
                        cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH)));
                         memcpy(line_buf[tl], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                        for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                            line_buf[tl][b] = conv_rgb2y(line_buf[tl][b]);    // カラーから白黒へ
                        }
                    }
                }
                lap_fil_val = laplacian_fil(line_buf[fl][x-1], line_buf[fl][x], line_buf[fl][x+1], line_buf[sl][x-1], line_buf[sl][x], line_buf[sl][x+1], line_buf[tl][x-1], line_buf[tl][x], line_buf[tl][x+1]);
            }
            lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
        }
        lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH)));
        memcpy(lap_fb_addr, (const int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));

        line_sel++;
        if (line_sel > 3){
            line_sel = 1;
        }
    }
    return(1);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8// 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


合成結果は、割り算を削除したので、前回の結果と比較するとリソース使用量が減っている。
前回の高位合成結果の内のUtilization Estimates を示す。

================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 849|
|FIFO | -| -| -| -|
|Instance | 0| -| 1416| 1686|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 393|
|Register | -| -| 1053| -|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2469| 2928|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 7| 16|
+-----------------+---------+-------+-------+-------+


割り算を削除した今回の高位合成結果の内のUtilization Estimates を示す。

================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 1080|
|FIFO | -| -| -| -|
|Instance | 0| -| 1168| 1392|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 401|
|Register | -| -| 1086| -|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2254| 2873|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 6| 16|
+-----------------+---------+-------+-------+-------+


最後に高位合成時のレポートを貼っておく。

================================================================
== Vivado HLS Report for 'lap_filter_axim'
================================================================
* Date: Sun Mar 22 05:31:18 2015

* Version: 2014.4 (Build 1071461 on Tue Nov 18 16:42:57 PM 2014)
* Project: lap_filter_axim_2014_4
* Solution: solution1
* Product family: zynq
* Target device: xc7z010clg400-1


================================================================
== Performance Estimates
================================================================
+ Timing (ns):
* Summary:
+---------+-------+----------+------------+
| Clock | Target| Estimated| Uncertainty|
+---------+-------+----------+------------+
|default | 10.00| 8.75| 1.25|
+---------+-------+----------+------------+

+ Latency (clock cycles):
* Summary:
+---------+------------+---------+------------+---------+
| Latency | Interval | Pipeline|
| min | max | min | max | Type |
+---------+------------+---------+------------+---------+
| 1445401| 8083685401| 1445402| 8083685402| none |
+---------+------------+---------+------------+---------+

+ Detail:
* Instance:
N/A

* Loop:
+------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+
| | Latency | Iteration | Initiation Interval | Trip | |
| Loop Name | min | max | Latency | achieved | target | Count| Pipelined|
+------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+
|- Loop 1 | 1445400| 8083685400| 2409 ~ 13472809 | -| -| 600| no |
| + Loop 1.1 | 1600| 13472000| 2 ~ 16840 | -| -| 800| no |
| ++ Loop 1.1.1 | 16830| 16830| 5610| -| -| 3| no |
| +++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| +++ Loop 1.1.1.2 | 4800| 4800| 6| -| -| 800| no |
| ++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| ++ Loop 1.1.3 | 4800| 4800| 6| -| -| 800| no |
| + memcpy.lap_fb.lap_buf.gep | 801| 801| 3| 1| 1| 800| yes |
+------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+



================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 1080|
|FIFO | -| -| -| -|
|Instance | 0| -| 1168| 1392|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 401|
|Register | -| -| 1086| -|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2254| 2873|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 6| 16|
+-----------------+---------+-------+-------+-------+

+ Detail:
* Instance:
+------------------------------------+----------------------------------+---------+-------+-----+-----+
| Instance | Module | BRAM_18K| DSP48E| FF | LUT |
+------------------------------------+----------------------------------+---------+-------+-----+-----+
|lap_filter_axim_BUS_AXI4LS_s_axi_U |lap_filter_axim_BUS_AXI4LS_s_axi | 0| 0| 144| 232|
|lap_filter_axim_cam_fb_m_axi_U |lap_filter_axim_cam_fb_m_axi | 0| 0| 512| 580|
|lap_filter_axim_lap_fb_m_axi_U |lap_filter_axim_lap_fb_m_axi | 0| 0| 512| 580|
+------------------------------------+----------------------------------+---------+-------+-----+-----+
|Total | | 0| 0| 1168| 1392|
+------------------------------------+----------------------------------+---------+-------+-----+-----+

* Memory:
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
| Memory | Module | BRAM_18K| FF| LUT| Words| Bits| Banks| W*Bits*Banks|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|lap_buf_U |lap_filter_axim_lap_buf | 2| 0| 0| 800| 24| 1| 19200|
|line_buf_U |lap_filter_axim_line_buf | 8| 0| 0| 2400| 32| 1| 76800|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|Total | | 10| 0| 0| 3200| 56| 2| 96000|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+

* FIFO:
N/A

* Expression:
+--------------------------+----------+-------+---+----+------------+------------+
| Variable Name | Operation| DSP48E| FF| LUT| Bitwidth P0| Bitwidth P1|
+--------------------------+----------+-------+---+----+------------+------------+
|p_addr1_fu_691_p2 | * | 1| 0| 0| 2| 10|
|p_addr3_fu_700_p2 | * | 1| 0| 0| 2| 10|
|p_addr_fu_682_p2 | * | 1| 0| 0| 2| 10|
|tmp_2_fu_673_p2 | * | 1| 0| 0| 2| 10|
|tmp_38_i8_fu_902_p2 | * | 1| 0| 0| 8| 7|
|tmp_38_i_fu_1059_p2 | * | 1| 0| 0| 8| 7|
|tmp_39_i9_fu_874_p2 | * | 1| 0| 0| 8| 8|
|tmp_39_i_fu_1031_p2 | * | 1| 0| 0| 8| 8|
|tmp_40_i1_fu_883_p2 | * | 1| 0| 0| 8| 5|
|tmp_40_i_fu_1040_p2 | * | 1| 0| 0| 8| 5|
|y_i16_op_cast_fu_1226_p2 | * | 1| 0| 1| 24| 17|
|a_1_fu_945_p2 | + | 0| 0| 2| 2| 1|
|b_2_fu_1002_p2 | + | 0| 0| 10| 10| 1|
|b_fu_813_p2 | + | 0| 0| 10| 10| 1|
|indvar_next1_fu_1259_p2 | + | 0| 0| 10| 10| 1|
|indvar_next2_fu_792_p2 | + | 0| 0| 10| 10| 1|
|indvar_next_fu_980_p2 | + | 0| 0| 10| 10| 1|
|line_sel_1_fu_1274_p2 | + | 0| 0| 32| 32| 1|
|next_mul1_fu_542_p2 | + | 0| 0| 19| 19| 10|
|next_mul2_fu_927_p2 | + | 0| 0| 12| 12| 10|
|next_mul_fu_933_p2 | + | 0| 0| 12| 12| 10|
|p_addr10_fu_1087_p2 | + | 0| 0| 12| 12| 12|
|p_addr11_fu_1121_p2 | + | 0| 0| 12| 12| 12|
|p_addr12_fu_1097_p2 | + | 0| 0| 12| 12| 12|
|p_addr13_fu_1112_p2 | + | 0| 0| 12| 12| 12|
|p_addr2_fu_1138_p2 | + | 0| 0| 12| 12| 12|
|p_addr4_fu_842_p2 | + | 0| 0| 12| 12| 12|
|p_addr5_fu_1134_p2 | + | 0| 0| 12| 12| 12|
|p_addr6_fu_823_p2 | + | 0| 0| 12| 12| 12|
|p_addr7_fu_856_p2 | + | 0| 0| 12| 12| 12|
|p_addr8_fu_1130_p2 | + | 0| 0| 12| 12| 12|
|p_addr9_fu_1012_p2 | + | 0| 0| 12| 12| 12|
|sum2_i_fu_1162_p2 | + | 0| 0| 16| 32| 32|
|tmp21_fu_1106_p2 | + | 0| 0| 32| 32| 32|
|tmp22_fu_1142_p2 | + | 0| 0| 32| 32| 32|
|tmp_12_fu_986_p2 | + | 0| 0| 12| 12| 12|
|tmp_17_fu_833_p2 | + | 0| 0| 11| 11| 2|
|tmp_35_fu_764_p2 | + | 0| 0| 31| 31| 31|
|tmp_37_fu_955_p2 | + | 0| 0| 31| 31| 31|
|tmp_8_fu_768_p2 | + | 0| 0| 31| 31| 31|
|tmp_fu_536_p2 | + | 0| 0| 31| 31| 10|
|tmp_s_fu_798_p2 | + | 0| 0| 12| 12| 12|
|x_1_fu_716_p2 | + | 0| 0| 10| 10| 1|
|y_1_fu_554_p2 | + | 0| 0| 10| 10| 1|
|sum3_neg_i_fu_1166_p2 | - | 0| 0| 16| 32| 32|
|tmp_42_i_fu_1182_p2 | - | 0| 0| 32| 32| 32|
|tmp_43_i_fu_1187_p2 | - | 0| 0| 32| 32| 32|
|tmp_i1_fu_1172_p2 | - | 0| 0| 32| 32| 32|
|y_4_fu_1193_p2 | - | 0| 0| 32| 32| 32|
|newSel2_fu_602_p3 | Select | 0| 0| 3| 1| 1|
|newSel_fu_594_p3 | Select | 0| 0| 3| 1| 3|
|p_s_fu_1296_p3 | Select | 0| 0| 32| 1| 1|
|phitmp_fu_1231_p3 | Select | 0| 0| 24| 1| 2|
|sel_tmp1_fu_620_p3 | Select | 0| 0| 3| 1| 1|
|sel_tmp3_fu_628_p3 | Select | 0| 0| 3| 1| 3|
|tl_fu_636_p3 | Select | 0| 0| 2| 1| 2|
|tmp_5_fu_644_p3 | Select | 0| 0| 2| 1| 2|
|tmp_6_fu_652_p3 | Select | 0| 0| 2| 1| 2|
|ap_sig_bdd_1016 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_373 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_394 | and | 0| 0| 1| 1| 1|
|exitcond1_fu_1253_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond2_fu_786_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond3_fu_996_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond4_fu_939_p2 | icmp | 0| 0| 2| 2| 2|
|exitcond5_fu_710_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond6_fu_548_p2 | icmp | 0| 0| 11| 10| 10|
|exitcond7_fu_974_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond_fu_807_p2 | icmp | 0| 0| 11| 10| 9|
|icmp1_fu_1290_p2 | icmp | 0| 0| 38| 30| 1|
|icmp_fu_1216_p2 | icmp | 0| 0| 30| 24| 1|
|sel_tmp2_fu_566_p2 | icmp | 0| 0| 40| 32| 2|
|sel_tmp4_fu_572_p2 | icmp | 0| 0| 40| 32| 1|
|sel_tmp_fu_560_p2 | icmp | 0| 0| 40| 32| 2|
|tmp_13_fu_722_p2 | icmp | 0| 0| 11| 10| 10|
|tmp_19_fu_728_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_30_fu_740_p2 | icmp | 0| 0| 11| 10| 9|
|tmp_32_fu_746_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_4_fu_663_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_7_fu_758_p2 | icmp | 0| 0| 11| 10| 1|
|or_cond_fu_588_p2 | or | 0| 0| 1| 1| 1|
|tmp_29_fu_734_p2 | or | 0| 0| 1| 1| 1|
|tmp_33_fu_752_p2 | or | 0| 0| 1| 1| 1|
|not_sel_tmp4_fu_578_p2 | xor | 0| 0| 2| 1| 2|
|not_sel_tmp_fu_610_p2 | xor | 0| 0| 2| 1| 2|
+--------------------------+----------+-------+---+----+------------+------------+
|Total | | 11| 0|1080| 1073| 776|
+--------------------------+----------+-------+---+----+------------+------------+

* Multiplexer:
+-------------------------------+----+-----------+-----+-----------+
| Name | LUT| Input Size| Bits| Total Bits|
+-------------------------------+----+-----------+-----+-----------+
|a_reg_387 | 2| 2| 2| 4|
|ap_NS_fsm | 78| 44| 1| 44|
|ap_reg_ppiten_pp0_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp1_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp2_it2 | 1| 2| 1| 2|
|ap_sig_ioackin_cam_fb_ARREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_AWREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_WREADY | 1| 2| 1| 2|
|b1_reg_433 | 10| 2| 10| 20|
|b_1_reg_376 | 10| 2| 10| 20|
|cam_fb_ARADDR | 32| 3| 32| 96|
|indvar1_reg_462 | 10| 2| 10| 20|
|indvar2_reg_365 | 10| 2| 10| 20|
|indvar_reg_422 | 10| 2| 10| 20|
|lap_buf_address0 | 10| 3| 10| 30|
|lap_fil_val_1_phi_fu_448_p8 | 24| 2| 24| 48|
|lap_fil_val_1_reg_444 | 24| 2| 24| 48|
|line_buf_address0 | 24| 9| 12| 108|
|line_buf_address1 | 24| 8| 12| 96|
|line_buf_d1 | 32| 4| 32| 128|
|line_sel_reg_329 | 32| 2| 32| 64|
|phi_mul1_reg_341 | 19| 2| 19| 38|
|phi_mul2_reg_410 | 12| 2| 12| 24|
|phi_mul_reg_398 | 12| 2| 12| 24|
|x_reg_353 | 10| 2| 10| 20|
|y_reg_317 | 10| 2| 10| 20|
+-------------------------------+----+-----------+-----+-----------+
|Total | 401| 111| 300| 904|
+-------------------------------+----+-----------+-----+-----------+

* Register:
+-----------------------------------------+----+----+-----+-----------+
| Name | FF | LUT| Bits| Const Bits|
+-----------------------------------------+----+----+-----+-----------+
|a_1_reg_1511 | 2| 0| 2| 0|
|a_reg_387 | 2| 0| 2| 0|
|ap_CS_fsm | 43| 0| 43| 0|
|ap_reg_ioackin_cam_fb_ARREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_AWREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_WREADY | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it2 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond1_reg_1675_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond2_reg_1427_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond7_reg_1527_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_tmp_12_reg_1536_pp1_it1 | 12| 0| 12| 0|
|ap_reg_ppstg_tmp_s_reg_1436_pp0_it1 | 12| 0| 12| 0|
|b1_reg_433 | 10| 0| 10| 0|
|b_1_reg_376 | 10| 0| 10| 0|
|b_2_reg_1544 | 10| 0| 10| 0|
|b_3_reg_1477 | 8| 0| 8| 0|
|b_4_reg_1555 | 8| 0| 8| 0|
|b_reg_1444 | 10| 0| 10| 0|
|exitcond1_reg_1675 | 1| 0| 1| 0|
|exitcond2_reg_1427 | 1| 0| 1| 0|
|exitcond4_reg_1507 | 1| 0| 1| 0|
|exitcond7_reg_1527 | 1| 0| 1| 0|
|icmp_reg_1655 | 1| 0| 1| 0|
|indvar1_reg_462 | 10| 0| 10| 0|
|indvar2_reg_365 | 10| 0| 10| 0|
|indvar_reg_422 | 10| 0| 10| 0|
|lap_buf_load_reg_1689 | 24| 0| 24| 0|
|lap_fil_val_1_reg_444 | 24| 0| 24| 0|
|line_buf_addr_2_reg_1449 | 12| 0| 12| 0|
|line_buf_addr_3_reg_1549 | 12| 0| 12| 0|
|line_sel_reg_329 | 32| 0| 32| 0|
|next_mul1_reg_1319 | 19| 0| 19| 0|
|next_mul2_reg_1497 | 12| 0| 12| 0|
|next_mul_reg_1502 | 12| 0| 12| 0|
|offset_cam_addr_cast_reg_1304 | 31| 0| 31| 0|
|offset_lap_addr_cast_reg_1309 | 31| 0| 31| 0|
|p_addr1_reg_1371 | 7| 0| 12| 5|
|p_addr2_reg_1616 | 12| 0| 12| 0|
|p_addr3_reg_1378 | 7| 0| 12| 5|
|p_addr5_reg_1611 | 12| 0| 12| 0|
|p_addr8_reg_1606 | 12| 0| 12| 0|
|p_addr_reg_1363 | 7| 0| 12| 5|
|p_s_reg_1694 | 32| 0| 32| 0|
|phi_mul1_reg_341 | 19| 0| 19| 0|
|phi_mul2_reg_410 | 12| 0| 12| 0|
|phi_mul_reg_398 | 12| 0| 12| 0|
|phitmp_reg_1665 | 24| 0| 24| 0|
|reg_494 | 32| 0| 32| 0|
|reg_500 | 8| 0| 8| 0|
|reg_504 | 8| 0| 8| 0|
|tl_reg_1332 | 2| 0| 2| 0|
|tmp17_reg_1487 | 16| 0| 16| 0|
|tmp19_reg_1565 | 16| 0| 16| 0|
|tmp21_reg_1591 | 32| 0| 32| 0|
|tmp22_reg_1621 | 32| 0| 32| 0|
|tmp_12_reg_1536 | 12| 0| 12| 0|
|tmp_29_reg_1399 | 1| 0| 1| 0|
|tmp_2_reg_1358 | 7| 0| 12| 5|
|tmp_31_trn_cast_reg_1455 | 11| 0| 12| 1|
|tmp_32_trn_cast_reg_1466 | 10| 0| 12| 2|
|tmp_33_reg_1403 | 1| 0| 1| 0|
|tmp_34_trn_cast_reg_1575 | 10| 0| 12| 2|
|tmp_35_reg_1411 | 31| 0| 31| 0|
|tmp_37_reg_1516 | 31| 0| 31| 0|
|tmp_39_i9_reg_1482 | 15| 0| 16| 1|
|tmp_39_i_reg_1560 | 15| 0| 16| 1|
|tmp_42_reg_1651 | 1| 0| 1| 0|
|tmp_43_i_reg_1646 | 32| 0| 32| 0|
|tmp_44_reg_1660 | 24| 0| 24| 0|
|tmp_4_reg_1348 | 1| 0| 1| 0|
|tmp_5_cast1_reg_1352 | 19| 0| 31| 12|
|tmp_5_reg_1338 | 2| 0| 2| 0|
|tmp_6_reg_1343 | 2| 0| 2| 0|
|tmp_7_reg_1407 | 1| 0| 1| 0|
|tmp_8_reg_1416 | 31| 0| 31| 0|
|tmp_i1_reg_1636 | 32| 0| 32| 0|
|tmp_reg_1314 | 31| 0| 31| 0|
|tmp_s_reg_1436 | 12| 0| 12| 0|
|x_1_reg_1393 | 10| 0| 10| 0|
|x_cast_reg_1385 | 10| 0| 11| 1|
|x_reg_353 | 10| 0| 10| 0|
|y_1_reg_1327 | 10| 0| 10| 0|
|y_2_reg_1492 | 8| 0| 8| 0|
|y_3_reg_1570 | 8| 0| 8| 0|
|y_reg_317 | 10| 0| 10| 0|
+-----------------------------------------+----+----+-----+-----------+
|Total |1086| 0| 1126| 40|
+-----------------------------------------+----+----+-----+-----------+



================================================================
== Interface
================================================================
* Summary:
+--------------------------+-----+-----+------------+-----------------+--------------+
| RTL Ports | Dir | Bits| Protocol | Source Object | C Type |
+--------------------------+-----+-----+------------+-----------------+--------------+
|s_axi_BUS_AXI4LS_AWVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WDATA | in | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WSTRB | in | 4| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RDATA | out | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|ap_clk | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|ap_rst_n | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|interrupt | out | 1| ap_ctrl_hs | lap_filter_axim | return value |
|m_axi_cam_fb_AWVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WDATA | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WSTRB | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WLAST | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RDATA | in | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RLAST | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_lap_fb_AWVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WDATA | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WSTRB | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WLAST | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RDATA | in | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RLAST | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RUSER | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BUSER | in | 1| m_axi | lap_fb | pointer |
+--------------------------+-----+-----+------------+-----------------+--------------+

  1. 2015年03月22日 11:25 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル4(うまく行った)

ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル3”の続き。
その前は、”ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル2

頭を悩ませてきたVivado HLS 2014.4 で高位合成したラプラシアンフィルタ IP の処理に27秒も掛かるバグは、”Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”でバグをフィックスすることができた。古いバグありコードを使ってしまって、本当に申し訳なかった。

ラプラシアンフィルタIP のバグもフィックスできたので、もう一度、”Vivado HLS 2014.4でラプラシアン・フィルタ関数をaxi masterモジュールにする4(ブロックデザインにVivado HLSのIPを追加、インプリメント)”のラプラシアンフィルタ IP をバグ無しのものにすげ替えて、ラプラシアンフィルタのIPを更新し、もう一度、論理合成、インプリメント、ビットストリームの生成を行った。

Vivado HLS 2014.4でラプラシアン・フィルタ関数をaxi masterモジュールにする5(BOOT.bin, devicetree.dtb の生成)”の手順で BOOT.bin を生成した。devicetree.dtb は変更していないので、そのままとした。

ZYBO用のSDカードにBOOT.bin を書き込んで、ZYBOに入れて電源をONした。

Ubuntu 14.04 LTS が立ち上がり、SSHでログインした。

linaro ユーザーでログインしているので、Apps/lap_fil_hls_1shot ディレクトリにログインして、./cam_disp_uio コマンドを実行して、カメラの画像を表示した。
lap_fil_hls_15_4_23_150321.jpg

./lap_fil_hls_1shot コマンドを実行して、ラプラシアンフィルタ処理を行った。
lap_fil_hls_15_4_24_150321.jpg

後に示す、lap_fil_hls_1shot.c の No.4 と No.2 の gettimeofday() コマンド間の経過時間は、約 95.4 ms だった。(ソフトウェアの開始から終了まで)

lap_fil_hls_1shot.c の No.2 と No.3 の gettimeofday() コマンド間の経過時間は、約 80.0 ms だった。(ラプラシアンフィルタの処理のみ)
lap_fil_hls_14_4_29_150321.png 

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”での予測値は、 79.2 ms だったので大体正しいようだ。

最後に、lap_fil_hls_1shot.c を貼っておく。

// lap_fil_hls_1shot.c
// by marsee
// 2015/02/19

#include "xlap_filter_axim.h"

#define CMA_START_ADDRESS 0x17800000
#define VIDEO_BUFFER_START_ADDRESS 0x18000000 // Limit 0x18800000, 800*600*4 = 2MBytes * 2
#define LAPLACIAN_FILTER_ADDRESS 0x18200000 // 800*600*4 = 0x1d4c00

int main() {
unsigned int fb_addr, next_frame_addr;
struct timeval start_time, temp1, temp2, end_time;
XLap_filter_axim lap_fil_lsalve, frame_buf, bitmap_dispc;
XLap_filter_axim *lap_fil_lsalvep, *frame_bufp, *bitmap_dispcp;
u32 a;

//gettimeofday(&start_time, NULL); // No.1

lap_fil_lsalvep = &lap_fil_lsalve;
frame_bufp = &frame_buf;
bitmap_dispcp = &bitmap_dispc;

// Initialization of bitmap display controller
if (XLap_filter_axim_Initialize(bitmap_dispcp, "bitmap_display_cntrler_axim") != XST_SUCCESS){
fprintf(stderr, "bitmap_display_cntrler_axim open error\n");
exit(-1);
}

a = *(volatile u32 *)(bitmap_dispcp->Bus_axi4ls_BaseAddress);
//printf("%d\n", a);

// Initialization of frame_buffer
if (XLap_filter_axim_Initialize(frame_bufp, "frame_buffer_bmdc") != XST_SUCCESS){
fprintf(stderr, "frame_buffer_bmdc open error\n");
exit(-1);
}
fb_addr = (unsigned int)frame_bufp->Bus_axi4ls_BaseAddress + (unsigned int)(VIDEO_BUFFER_START_ADDRESS-CMA_START_ADDRESS);

// frame buffer for laplacian filter result
next_frame_addr = (unsigned int)frame_bufp->Bus_axi4ls_BaseAddress + (unsigned int)(LAPLACIAN_FILTER_ADDRESS-CMA_START_ADDRESS);

// Initialization of lap_filter_axim
if (XLap_filter_axim_Initialize(lap_fil_lsalvep, "lap_filter_axim_hls") != XST_SUCCESS){
fprintf(stderr, "lap_filter_axim_hls open error\n");
exit(-1);
}

a = *(volatile u32 *)(lap_fil_lsalvep->Bus_axi4ls_BaseAddress);
//printf("%d\n", a); fflush(stdout);

XLap_filter_axim_Set_cam_addr(lap_fil_lsalvep, (u32)VIDEO_BUFFER_START_ADDRESS);

XLap_filter_axim_Set_lap_addr(lap_fil_lsalvep, (u32)LAPLACIAN_FILTER_ADDRESS);

gettimeofday(&start_time, NULL); // No.2

XLap_filter_axim_Start(lap_fil_lsalvep);

while(!XLap_filter_axim_IsDone(lap_fil_lsalvep)) ;

gettimeofday(&end_time, NULL); // No.3

// Displayed the laplacian filter image
*(volatile unsigned int *)bitmap_dispcp->Bus_axi4ls_BaseAddress = (unsigned int)LAPLACIAN_FILTER_ADDRESS;

if (XLap_filter_axim_Release(lap_fil_lsalvep) != XST_SUCCESS){
fprintf(stderr, "lap_filter_axim_hls release error\n");
exit(-1);
}

if (XLap_filter_axim_Release(frame_bufp) != XST_SUCCESS){
fprintf(stderr, "frame_buffer_bmdc release error\n");
exit(-1);
}

if (XLap_filter_axim_Release(bitmap_dispcp) != XST_SUCCESS){
fprintf(stderr, "bitmap_display_cntrler_axim release error\n");
exit(-1);
}

// Displayed the procee past time
//gettimeofday(&end_time, NULL); // No.4

if (end_time.tv_usec < start_time.tv_usec) {
printf("total time = %ld.%6.6ld sec\n", end_time.tv_sec - start_time.tv_sec - 1, 1000000 + end_time.tv_usec - start_time.tv_usec);
}
else {
printf("total time = %ld.%6.6ld sec\n", end_time.tv_sec - start_time.tv_sec, end_time.tv_usec - start_time.tv_usec);
}

return(0);
}
  1. 2015年03月21日 06:12 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)

おるさんのおかげで、1ヶ月半くらいの間、悩んできた Vivado HLS 2014.4 で生成したラプラシアンフィルタIP の原因が分かりました。おるさんありがとうございました。

それは、古いバグありのラプラシアンフィルタのCソースコードを使用してしまったからです。正しいCソースコードはあったのですが、Vivado HLS プロジェクトの外に出してあって、バージョンの違うVivado HLS プロジェクトで使えるようになっていました。古いバグありCソースコードがプロジェクト内に残っていたので勘違いしてしまいました。反省しております。。。

新しいラプラシアンフィルタIP のCソースコードを貼っておきます。

// laplacian_filter.c
// lap_filter_axim()

#include <stdio.h>
#include <string.h>

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS INTERFACE s_axilite port=cam_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=lap_addr bundle=BUS_AXI4LS
    #pragma HLS INTERFACE s_axilite port=return bundle=BUS_AXI4LS
    #pragma HLS INTERFACE ap_none port=cam_addr
    #pragma HLS INTERFACE ap_none port=lap_addr

    #pragma HLS INTERFACE m_axi port=cam_fb depth=1920
    #pragma HLS INTERFACE m_axi port=lap_fb depth=1920

    unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
    unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH];
    int x, y;
    int lap_fil_val;
    int a, b;
    int fl, sl, tl;
    unsigned int offset_cam_addr, offset_lap_addr;
    int *cam_fb_addr, *lap_fb_addr;

    offset_cam_addr = cam_addr/sizeof(int);
    offset_lap_addr = lap_addr/sizeof(int);
    
    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        fl = (y-1)%3;    // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        sl = y%3;        // 2番めのライン
        tl = (y+1)%3;    // 3番目のライン
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
                lap_fil_val = 0;
            }else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
                lap_fil_val = 0;
            }else{
                 if (x == 1){ // ラインの最初でラインの画素を読み出す
                    if (y == 1){ // 最初のラインでは3ライン分の画素を読み出す
                        for (a=0; a<3; a++){ // 3ライン分
                            cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH)));
                            memcpy(&line_buf[a][0], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                            for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                                line_buf[a][b] = conv_rgb2y(line_buf[a][b]);    // カラーから白黒へ
                            }
                        }
                    } else { // 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている
                        cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH)));
                         memcpy(line_buf[(y+1)%3], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                        for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                            line_buf[(y+1)%3][b] = conv_rgb2y(line_buf[(y+1)%3][b]);    // カラーから白黒へ
                        }
                    }
                }
                lap_fil_val = laplacian_fil(line_buf[fl][x-1], line_buf[fl][x], line_buf[fl][x+1], line_buf[sl][x-1], line_buf[sl][x], line_buf[sl][x+1], line_buf[tl][x-1], line_buf[tl][x], line_buf[tl][x+1]);
            }
            lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
        }
        lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH)));
        memcpy(lap_fb_addr, (const int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
    }
    return(1);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8// 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


Vivado HLS 2014.4 で合成し、IP 化した。
lap_fil_hls_14_4_28_150321.png  

lap_fil_hls_14_4 のVivado プロジェクトを終了した。

lap_filter_axim_0 のIP の中身と入れ替えて、もう一度、lap_fil_hls_14_4 のVivado プロジェクトを起動した。

ブロック・デザインを開くと、ラプラシアンフィルタIP の更新のお知らせがあったので、更新した。
lap_fil_hls_15_4_21_150318.png

Flow Navigator から Simulation -> Run Simulation -> Run Behevioral Simulation を選択して論理シミュレーションを行った。
シミュレーション結果を下に示す。
lap_fil_hls_14_4_26_150321.png 

3回 DMA Read を行ってから、DMA Write を行っている。その後は交互にDMA Read とDMA Write が続いている。これで問題ない。

DMA Write 間の時間を測ってみると、92.0 us だった。ラプラシアンフィルタ処理時間をざっと計算してみよう。DMA Write を600回(行数)行うので、

131.95 us x 600 行 = 79170 us ≒ 79.2 ms

となるはずだ。
lap_fil_hls_14_4_27_150321.png 

最後に、Vivado HLS 2014.4 でバグのないラプラシアンフィルタのCソースコードを高位合成した時のログファイルを貼っておく。



================================================================
== Vivado HLS Report for 'lap_filter_axim'
================================================================
* Date: Sat Mar 21 18:45:50 2015

* Version: 2014.4 (Build 1071461 on Tue Nov 18 16:42:57 PM 2014)
* Project: lap_filter_axim_2014_4
* Solution: solution1
* Product family: zynq
* Target device: xc7z010clg400-1


================================================================
== Performance Estimates
================================================================
+ Timing (ns):
* Summary:
+---------+-------+----------+------------+
| Clock | Target| Estimated| Uncertainty|
+---------+-------+----------+------------+
|default | 10.00| 8.75| 1.25|
+---------+-------+----------+------------+

+ Latency (clock cycles):
* Summary:
+---------+------------+---------+------------+---------+
| Latency | Interval | Pipeline|
| min | max | min | max | Type |
+---------+------------+---------+------------+---------+
| 1453801| 8083693801| 1453802| 8083693802| none |
+---------+------------+---------+------------+---------+

+ Detail:
* Instance:
N/A

* Loop:
+-------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+
| | Latency | Iteration | Initiation Interval | Trip | |
| Loop Name | min | max | Latency | achieved | target | Count| Pipelined|
+-------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+
|- Loop 1 | 1453800| 8083693800| 2423 ~ 13472823 | -| -| 600| no |
| + Loop 1.1 | 1600| 13472000| 2 ~ 16840 | -| -| 800| no |
| ++ Loop 1.1.1 | 16830| 16830| 5610| -| -| 3| no |
| +++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| +++ lap_filter_axim_label0 | 4800| 4800| 6| -| -| 800| no |
| ++ memcpy..cam_fb | 801| 801| 3| 1| 1| 800| yes |
| ++ Loop 1.1.3 | 4800| 4800| 6| -| -| 800| no |
| + memcpy.lap_fb.lap_buf.gep | 801| 801| 3| 1| 1| 800| yes |
+-------------------------------+---------+------------+-----------------+-----------+-----------+------+----------+



================================================================
== Utilization Estimates
================================================================
* Summary:
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|Expression | -| 11| 0| 849|
|FIFO | -| -| -| -|
|Instance | 0| -| 1416| 1686|
|Memory | 10| -| 0| 0|
|Multiplexer | -| -| -| 393|
|Register | -| -| 1053| -|
+-----------------+---------+-------+-------+-------+
|Total | 10| 11| 2469| 2928|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 8| 13| 7| 16|
+-----------------+---------+-------+-------+-------+

+ Detail:
* Instance:
+--------------------------------------------+-----------------------------------------+---------+-------+-----+-----+
| Instance | Module | BRAM_18K| DSP48E| FF | LUT |
+--------------------------------------------+-----------------------------------------+---------+-------+-----+-----+
|lap_filter_axim_BUS_AXI4LS_s_axi_U |lap_filter_axim_BUS_AXI4LS_s_axi | 0| 0| 144| 232|
|lap_filter_axim_cam_fb_m_axi_U |lap_filter_axim_cam_fb_m_axi | 0| 0| 512| 580|
|lap_filter_axim_lap_fb_m_axi_U |lap_filter_axim_lap_fb_m_axi | 0| 0| 512| 580|
|lap_filter_axim_srem_11ns_3ns_11_15_seq_U0 |lap_filter_axim_srem_11ns_3ns_11_15_seq | 0| 0| 88| 104|
|lap_filter_axim_urem_10ns_3ns_10_14_seq_U1 |lap_filter_axim_urem_10ns_3ns_10_14_seq | 0| 0| 80| 95|
|lap_filter_axim_urem_10ns_3ns_10_14_seq_U2 |lap_filter_axim_urem_10ns_3ns_10_14_seq | 0| 0| 80| 95|
+--------------------------------------------+-----------------------------------------+---------+-------+-----+-----+
|Total | | 0| 0| 1416| 1686|
+--------------------------------------------+-----------------------------------------+---------+-------+-----+-----+

* Memory:
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
| Memory | Module | BRAM_18K| FF| LUT| Words| Bits| Banks| W*Bits*Banks|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|lap_buf_U |lap_filter_axim_lap_buf | 2| 0| 0| 800| 24| 1| 19200|
|line_buf_U |lap_filter_axim_line_buf | 8| 0| 0| 2400| 32| 1| 76800|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+
|Total | | 10| 0| 0| 3200| 56| 2| 96000|
+------------+--------------------------+---------+---+----+------+-----+------+-------------+

* FIFO:
N/A

* Expression:
+--------------------------+----------+-------+---+----+------------+------------+
| Variable Name | Operation| DSP48E| FF| LUT| Bitwidth P0| Bitwidth P1|
+--------------------------+----------+-------+---+----+------------+------------+
|p_addr1_fu_608_p2 | * | 1| 0| 0| 3| 10|
|p_addr3_fu_617_p2 | * | 1| 0| 0| 3| 10|
|p_addr_fu_599_p2 | * | 1| 0| 0| 3| 10|
|tmp_38_i8_fu_819_p2 | * | 1| 0| 0| 8| 7|
|tmp_38_i_fu_976_p2 | * | 1| 0| 0| 8| 7|
|tmp_39_i9_fu_791_p2 | * | 1| 0| 0| 8| 8|
|tmp_39_i_fu_948_p2 | * | 1| 0| 0| 8| 8|
|tmp_40_i1_fu_800_p2 | * | 1| 0| 0| 8| 5|
|tmp_40_i_fu_957_p2 | * | 1| 0| 0| 8| 5|
|tmp_s_fu_590_p2 | * | 1| 0| 0| 3| 10|
|y_i16_op_cast_fu_1158_p2 | * | 1| 0| 1| 24| 17|
|a_1_fu_862_p2 | + | 0| 0| 2| 2| 1|
|b_2_fu_919_p2 | + | 0| 0| 10| 10| 1|
|b_fu_730_p2 | + | 0| 0| 10| 10| 1|
|grp_fu_560_p0 | + | 0| 0| 11| 11| 2|
|indvar_next1_fu_1191_p2 | + | 0| 0| 10| 10| 1|
|indvar_next2_fu_709_p2 | + | 0| 0| 10| 10| 1|
|indvar_next_fu_897_p2 | + | 0| 0| 10| 10| 1|
|next_mul1_fu_532_p2 | + | 0| 0| 19| 19| 10|
|next_mul2_fu_844_p2 | + | 0| 0| 12| 12| 10|
|next_mul_fu_850_p2 | + | 0| 0| 12| 12| 10|
|p_addr10_fu_1007_p2 | + | 0| 0| 13| 13| 13|
|p_addr11_fu_1050_p2 | + | 0| 0| 12| 12| 12|
|p_addr12_fu_1017_p2 | + | 0| 0| 12| 12| 12|
|p_addr13_fu_1040_p2 | + | 0| 0| 12| 12| 12|
|p_addr2_fu_1069_p2 | + | 0| 0| 12| 12| 12|
|p_addr4_fu_759_p2 | + | 0| 0| 13| 13| 13|
|p_addr5_fu_1064_p2 | + | 0| 0| 12| 12| 12|
|p_addr6_fu_740_p2 | + | 0| 0| 12| 12| 12|
|p_addr7_fu_773_p2 | + | 0| 0| 13| 13| 13|
|p_addr8_fu_1060_p2 | + | 0| 0| 12| 12| 12|
|p_addr9_fu_929_p2 | + | 0| 0| 12| 12| 12|
|sum2_i_fu_1094_p2 | + | 0| 0| 16| 32| 32|
|tmp4_fu_526_p2 | + | 0| 0| 31| 31| 10|
|tmp6_fu_1027_p2 | + | 0| 0| 32| 32| 32|
|tmp7_fu_1074_p2 | + | 0| 0| 32| 32| 32|
|tmp_11_fu_715_p2 | + | 0| 0| 12| 12| 12|
|tmp_13_fu_903_p2 | + | 0| 0| 12| 12| 12|
|tmp_17_fu_750_p2 | + | 0| 0| 11| 11| 2|
|tmp_2_fu_685_p2 | + | 0| 0| 31| 31| 31|
|tmp_31_fu_681_p2 | + | 0| 0| 31| 31| 31|
|tmp_33_fu_872_p2 | + | 0| 0| 31| 31| 31|
|x_1_fu_633_p2 | + | 0| 0| 10| 10| 1|
|y_1_fu_548_p2 | + | 0| 0| 10| 10| 1|
|sum3_neg_i_fu_1098_p2 | - | 0| 0| 16| 32| 32|
|tmp_42_i_fu_1114_p2 | - | 0| 0| 32| 32| 32|
|tmp_43_i_fu_1119_p2 | - | 0| 0| 32| 32| 32|
|tmp_i1_fu_1104_p2 | - | 0| 0| 32| 32| 32|
|y_4_fu_1125_p2 | - | 0| 0| 32| 32| 32|
|phitmp_fu_1163_p3 | Select | 0| 0| 24| 1| 2|
|ap_sig_bdd_1026 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_387 | and | 0| 0| 1| 1| 1|
|ap_sig_bdd_408 | and | 0| 0| 1| 1| 1|
|exitcond1_fu_1185_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond2_fu_703_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond3_fu_913_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond4_fu_856_p2 | icmp | 0| 0| 2| 2| 2|
|exitcond5_fu_627_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond6_fu_542_p2 | icmp | 0| 0| 11| 10| 10|
|exitcond7_fu_891_p2 | icmp | 0| 0| 11| 10| 9|
|exitcond_fu_724_p2 | icmp | 0| 0| 11| 10| 9|
|icmp_fu_1148_p2 | icmp | 0| 0| 30| 24| 1|
|tmp_10_fu_645_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_20_fu_657_p2 | icmp | 0| 0| 11| 10| 9|
|tmp_28_fu_663_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_6_fu_580_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_8_fu_675_p2 | icmp | 0| 0| 11| 10| 1|
|tmp_9_fu_639_p2 | icmp | 0| 0| 11| 10| 10|
|tmp_12_fu_651_p2 | or | 0| 0| 1| 1| 1|
|tmp_29_fu_669_p2 | or | 0| 0| 1| 1| 1|
+--------------------------+----------+-------+---+----+------------+------------+
|Total | | 11| 0| 849| 922| 754|
+--------------------------+----------+-------+---+----+------------+------------+

* Multiplexer:
+-------------------------------+-----+-----------+-----+-----------+
| Name | LUT | Input Size| Bits| Total Bits|
+-------------------------------+-----+-----------+-----+-----------+
|a_reg_377 | 2| 2| 2| 4|
|ap_NS_fsm | 102| 58| 1| 58|
|ap_reg_ppiten_pp0_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp1_it2 | 1| 2| 1| 2|
|ap_reg_ppiten_pp2_it2 | 1| 2| 1| 2|
|ap_sig_ioackin_cam_fb_ARREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_AWREADY | 1| 2| 1| 2|
|ap_sig_ioackin_lap_fb_WREADY | 1| 2| 1| 2|
|b1_reg_423 | 10| 2| 10| 20|
|b_1_reg_366 | 10| 2| 10| 20|
|cam_fb_ARADDR | 32| 3| 32| 96|
|indvar1_reg_452 | 10| 2| 10| 20|
|indvar2_reg_355 | 10| 2| 10| 20|
|indvar_reg_412 | 10| 2| 10| 20|
|lap_buf_address0 | 10| 3| 10| 30|
|lap_fil_val_1_phi_fu_438_p8 | 24| 2| 24| 48|
|lap_fil_val_1_reg_434 | 24| 2| 24| 48|
|line_buf_address0 | 24| 9| 12| 108|
|line_buf_address1 | 24| 8| 12| 96|
|line_buf_d1 | 32| 4| 32| 128|
|phi_mul1_reg_331 | 19| 2| 19| 38|
|phi_mul2_reg_400 | 12| 2| 12| 24|
|phi_mul_reg_388 | 12| 2| 12| 24|
|x_reg_343 | 10| 2| 10| 20|
|y_reg_319 | 10| 2| 10| 20|
+-------------------------------+-----+-----------+-----+-----------+
|Total | 393| 123| 268| 854|
+-------------------------------+-----+-----------+-----+-----------+

* Register:
+-----------------------------------------+----+----+-----+-----------+
| Name | FF | LUT| Bits| Const Bits|
+-----------------------------------------+----+----+-----+-----------+
|a_1_reg_1413 | 2| 0| 2| 0|
|a_reg_377 | 2| 0| 2| 0|
|ap_CS_fsm | 57| 0| 57| 0|
|ap_reg_ioackin_cam_fb_ARREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_AWREADY | 1| 0| 1| 0|
|ap_reg_ioackin_lap_fb_WREADY | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp0_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp1_it2 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it0 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppiten_pp2_it2 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond1_reg_1576_pp2_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond2_reg_1336_pp0_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_exitcond7_reg_1429_pp1_it1 | 1| 0| 1| 0|
|ap_reg_ppstg_tmp_11_reg_1345_pp0_it1 | 12| 0| 12| 0|
|ap_reg_ppstg_tmp_13_reg_1438_pp1_it1 | 12| 0| 12| 0|
|b1_reg_423 | 10| 0| 10| 0|
|b_1_reg_366 | 10| 0| 10| 0|
|b_2_reg_1446 | 10| 0| 10| 0|
|b_3_reg_1379 | 8| 0| 8| 0|
|b_4_reg_1457 | 8| 0| 8| 0|
|b_reg_1353 | 10| 0| 10| 0|
|exitcond1_reg_1576 | 1| 0| 1| 0|
|exitcond2_reg_1336 | 1| 0| 1| 0|
|exitcond4_reg_1409 | 1| 0| 1| 0|
|exitcond7_reg_1429 | 1| 0| 1| 0|
|fl_reg_1240 | 11| 0| 11| 0|
|icmp_reg_1556 | 1| 0| 1| 0|
|indvar1_reg_452 | 10| 0| 10| 0|
|indvar2_reg_355 | 10| 0| 10| 0|
|indvar_reg_412 | 10| 0| 10| 0|
|lap_buf_load_reg_1590 | 24| 0| 24| 0|
|lap_fil_val_1_reg_434 | 24| 0| 24| 0|
|line_buf_addr_2_reg_1358 | 12| 0| 12| 0|
|line_buf_addr_3_reg_1451 | 12| 0| 12| 0|
|next_mul1_reg_1221 | 19| 0| 19| 0|
|next_mul2_reg_1399 | 12| 0| 12| 0|
|next_mul_reg_1404 | 12| 0| 12| 0|
|offset_cam_addr_cast_reg_1206 | 31| 0| 31| 0|
|offset_lap_addr_cast_reg_1211 | 31| 0| 31| 0|
|p_addr1_reg_1279 | 8| 0| 13| 5|
|p_addr2_reg_1517 | 12| 0| 12| 0|
|p_addr3_reg_1286 | 7| 0| 12| 5|
|p_addr5_reg_1512 | 12| 0| 12| 0|
|p_addr8_reg_1507 | 12| 0| 12| 0|
|p_addr_reg_1271 | 7| 0| 12| 5|
|phi_mul1_reg_331 | 19| 0| 19| 0|
|phi_mul2_reg_400 | 12| 0| 12| 0|
|phi_mul_reg_388 | 12| 0| 12| 0|
|phitmp_reg_1566 | 24| 0| 24| 0|
|reg_484 | 32| 0| 32| 0|
|reg_490 | 8| 0| 8| 0|
|reg_494 | 8| 0| 8| 0|
|sl_reg_1245 | 10| 0| 10| 0|
|tl_reg_1250 | 10| 0| 10| 0|
|tmp2_reg_1467 | 16| 0| 16| 0|
|tmp4_reg_1216 | 31| 0| 31| 0|
|tmp5_reg_1389 | 16| 0| 16| 0|
|tmp6_reg_1492 | 32| 0| 32| 0|
|tmp7_reg_1522 | 32| 0| 32| 0|
|tmp_11_reg_1345 | 12| 0| 12| 0|
|tmp_12_reg_1308 | 1| 0| 1| 0|
|tmp_13_reg_1438 | 12| 0| 12| 0|
|tmp_17_reg_1364 | 11| 0| 11| 0|
|tmp_29_reg_1312 | 1| 0| 1| 0|
|tmp_29_trn_cast1_reg_1477 | 11| 0| 12| 1|
|tmp_2_reg_1325 | 31| 0| 31| 0|
|tmp_31_reg_1320 | 31| 0| 31| 0|
|tmp_33_reg_1418 | 31| 0| 31| 0|
|tmp_38_reg_1552 | 1| 0| 1| 0|
|tmp_39_i9_reg_1384 | 15| 0| 16| 1|
|tmp_39_i_reg_1462 | 15| 0| 16| 1|
|tmp_40_reg_1561 | 24| 0| 24| 0|
|tmp_43_i_reg_1547 | 32| 0| 32| 0|
|tmp_6_reg_1256 | 1| 0| 1| 0|
|tmp_7_cast1_reg_1260 | 19| 0| 31| 12|
|tmp_8_reg_1316 | 1| 0| 1| 0|
|tmp_i1_reg_1537 | 32| 0| 32| 0|
|tmp_s_reg_1266 | 7| 0| 12| 5|
|x_1_reg_1301 | 10| 0| 10| 0|
|x_cast_reg_1293 | 10| 0| 11| 1|
|x_reg_343 | 10| 0| 10| 0|
|y_1_reg_1229 | 10| 0| 10| 0|
|y_2_reg_1394 | 8| 0| 8| 0|
|y_3_reg_1472 | 8| 0| 8| 0|
|y_reg_319 | 10| 0| 10| 0|
+-----------------------------------------+----+----+-----+-----------+
|Total |1053| 0| 1089| 36|
+-----------------------------------------+----+----+-----+-----------+



================================================================
== Interface
================================================================
* Summary:
+--------------------------+-----+-----+------------+-----------------+--------------+
| RTL Ports | Dir | Bits| Protocol | Source Object | C Type |
+--------------------------+-----+-----+------------+-----------------+--------------+
|s_axi_BUS_AXI4LS_AWVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_AWADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WDATA | in | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_WSTRB | in | 4| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARVALID | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARREADY | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_ARADDR | in | 6| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RDATA | out | 32| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_RRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BVALID | out | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BREADY | in | 1| s_axi | BUS_AXI4LS | scalar |
|s_axi_BUS_AXI4LS_BRESP | out | 2| s_axi | BUS_AXI4LS | scalar |
|ap_clk | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|ap_rst_n | in | 1| ap_ctrl_hs | lap_filter_axim | return value |
|interrupt | out | 1| ap_ctrl_hs | lap_filter_axim | return value |
|m_axi_cam_fb_AWVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_AWUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WDATA | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WSTRB | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WLAST | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_WUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARVALID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREADY | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARADDR | out | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARID | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLEN | out | 8| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARSIZE | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARBURST | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARLOCK | out | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARCACHE | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARPROT | out | 3| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARQOS | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARREGION | out | 4| m_axi | cam_fb | pointer |
|m_axi_cam_fb_ARUSER | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RDATA | in | 32| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RLAST | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_RRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BVALID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BREADY | out | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BRESP | in | 2| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BID | in | 1| m_axi | cam_fb | pointer |
|m_axi_cam_fb_BUSER | in | 1| m_axi | cam_fb | pointer |
|m_axi_lap_fb_AWVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_AWUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WDATA | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WSTRB | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WLAST | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_WUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARVALID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREADY | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARADDR | out | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARID | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLEN | out | 8| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARSIZE | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARBURST | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARLOCK | out | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARCACHE | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARPROT | out | 3| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARQOS | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARREGION | out | 4| m_axi | lap_fb | pointer |
|m_axi_lap_fb_ARUSER | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RDATA | in | 32| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RLAST | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RUSER | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_RRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BVALID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BREADY | out | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BRESP | in | 2| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BID | in | 1| m_axi | lap_fb | pointer |
|m_axi_lap_fb_BUSER | in | 1| m_axi | lap_fb | pointer |
+--------------------------+-----+-----+------------+-----------------+--------------+

  1. 2015年03月20日 05:19 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:2

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション2

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション1”の続き。

(追記) Vivado HLS で合成したラプラシアンフィルタのバグの原因は、古いバグありラプラシアンフィルタのCソースコードを使用したためでした。正しいラプラシアンフィルタのCソースコードについては、”Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”をご覧ください。

前回、Vivado HLS 2014.4 でせいせいしたラプラシアンフィルタIP をVivado 2014.4 で、メモリIP やレジスタ値設定用IP などを追加して、ブロック・デザインを生成してシミュレーションを行った。
今回は、シミュレーションをもっと長く行って、ラプラシアンフィルタIP の実行時間が約27秒も掛かる原因を追求する。

110 ms シミュレーションを行った。
すると、2つのラプラシアンフィルタ処理後のデータのDMA Write アクセスがあるのが見えた。M_AXI_LAP_FB -> m_axi_lap_fb_AWVALID などである。
lap_fil_hls_14_4_12_150318.png

DMA Write の間隔を測定した。間隔は 44.85189 ms だった。
lap_fil_hls_14_4_13_150318.png

DMA Write は SVGA 解像度(800x600)では、600個あるはずである。1フレームの経過時間を計測してみると、

44.85189 x600 = 26911.134 ms ≒ 27 sec

となった。
実験結果とぴったり合う。シミュレーションは正しいことが証明された。

どういうことになっているのか?DMA Read 波形を見るために波形を拡大する。
lap_fil_hls_14_4_14_150318.png

上の波形は、最初のラプラシアンフィルタ処理のために3ライン分の画像のピクセル・データをDMA Read してくるところだ。DMA Read の間隔は 55.89 us だった。
M_AXI_CAM_FB -> m_axi_cam_fb_ARADDR[31:0] を見ると、50 us 辺りで 01000c00、100 us 辺りで 01001800、160 us 辺りで 01002400 になっているのがわかると思う。ここまではアドレスを増やしながら画像のピクセル・データをDMA Read してきたのが分かる。
しかし、その次は、220 us、270 us 共に 01002400 になっている。以下、ラプラシアンフィルタ処理後の値をDMA Write するまで同様にアドレスが 01002400 となっている。
DMA Write 後は、1ラインのDMA Read を行うはずなのだが、やはり、同じアドレスのDMA Read が続いている。

同じアドレスのDMA Read が何回行われているかを計算してみよう。

44851.89(us) / 55.89(us) = 802.5(個)

となった。これは、水平のピクセル数 800 に近い。

これは、やはり、Vivado HLS 2014.4 のバグなのではないか?と思う。次は、回避する手段を探ってみようと思う。
  1. 2015年03月18日 04:37 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:2

Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション1

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション6(シミュレーション)”で Vivado HLS 2014.1 で新たに作製したラプラシアンフィルタIP が動作しなったので、今度は、Vivado HLS 2014.4 で作製したラプラシアンフィルタIP をシミュレーションすることにした。

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション5(シミュレーション用プロジェクトの作製)”と同様にVivado 2014.4 のプロジェクトを作製した。

Vivado 2014.4 で ZYBO 用の lap_fil_hls_14_4 プロジェクトを作製した。
lap_fil_hls_14_4_1_150317.png

lap_fil_hls_sim ブロック・デザインを作製した。完成した状態のブロック・デザインを示す。
lap_fil_hls_14_4_2_150317.png

前回との違いは、rst_clk_wiz_100M IP の dcm_locked を 1 に固定したことだ。違いは無いと思う。その他の IP は前回のものをそのまま使用した。

mem_sim_axi_slave_0 の DEFAULT_VALUE は INCREMENT に設定した。前回もそうだが、C_S_Axi_Id_Width を 2 にしてある。こうしないとブロック・デザインの Validate Design でエラーになる。
lap_fil_hls_14_4_3_150317.png

Address Editor ウインドウの内容を下に示す。前回は、lap_filter_axim_0 のData は mem_sim_axi_slave_0 の 1つだけだったが、今回は、Data_m_axi_cam_fb と Data_m_axi_lap_fb の 2 つができていて、それぞれの下に mem_sim_axi_slave_0 が入っている。
lap_fil_hls_14_4_4_150317.png

レジスタ設定用IP の reg_set_axi_lite_master_0 の設定ファイルである reg_set.txt の内容を示す。フォーマットはアドレス、データで、オールFのアドレスで reg_set.txt の読み込みを停止する。

44A00000
00000000
44A00004
00000000
44A00008
00000001
44A00018
01000000
44A00020
02000000
44A00000
00000001
ffffffff


これで、Flow Navigator から Simulation -> Run Simulation -> Run Behevioral Simulation を選択して論理シミュレーションを行った。
lap_fil_hls_14_4_5_150317.png

波形はすべてVivado HLS 2014.4 で作製したラプラシアンフィルタIPの入力、出力ポートを見ている。レジスタ設定用の s_axi_BUS_AXI4LS と画像データをDMA Read する m_axi_cam_fb、ラプラシアンフィルタ処理後の画像データをDMA Write する m_axi_lap_fb だ。
その内の、s_axi_BUS_AXI4LS のレジスタ設定処理を下に示す。
lap_fil_hls_14_4_6_150317.png

次に、ラプラシアンフィルタ処理後の画像データをDMA Write する m_axi_lap_fb を見ると 20us 辺りで、WREADY が 0 になって、WLAST が出力されても、AWVALID がアクティブにならずに 1 のままである。これはおかしい。
lap_fil_hls_14_4_7_150317.png

何処がおかしいかというと、ラプラシアンフィルタIPがつながっている AXI Interconnect だ。

ブロック・デザインに戻って、lap_filter_axim_0_axi_periph をダブルクリックして、Interconnect Optimization Strategy を Custom から Minimize Area に変更した。
lap_fil_hls_14_4_8_150317.png

もう一度、論理シミュレーションを行った。
今度は、 m_axi_lap_fb はきちんとしたAXIバスの処理がされている。問題ないようだ。
lap_fil_hls_14_4_9_150317.png

画像データをDMA Read する m_axi_cam_fb を見ると、トランザクションが表示されていた。
lap_fil_hls_14_4_10_150317.png

更に、10 ms シミュレーションを行うと、最初は3回 m_axi_cam_fb のDMA Read を行った後に、m_axi_lap_fb の DMA Write
が行われるはずだが、行われていない。その後は、1回 m_axi_cam_fb のDMA Read を行った後に、m_axi_lap_fb の DMA Write が行われるはずだが、それも行われていない。
lap_fil_hls_14_4_11_150317.png

この辺りが、ラプラシアンフィルタの変換に約27秒も掛かる原因なのか?それともVivado のシミュレーションがおかしいのかまだわからない?

(追記) Vivado HLS で合成したラプラシアンフィルタのバグの原因は、古いバグありラプラシアンフィルタのCソースコードを使用したためでした。正しいラプラシアンフィルタのCソースコードについては、”Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”をご覧ください。
但し、AXI Interconnect の不具合の原因は別です。

AXI Interconnect の Interconnect Optimization Strategy を Custom にしておくと明らかにシミュレーション結果がおかしい。しかし、AXI Interconnect の Interconnect Optimization Strategy を Custom でも、論理合成、インプリメントして実機で試すとデッドロックはせずにラプラシアンフィルタ処理は終了するので、AXIバスの動作としてはおかしくない。
つまり、シミュレーションでは動作がおかしいが、論理合成、インプリメントすると問題ないのかもしれない?

一度、AXI Interconnect の Interconnect Optimization Strategy を Minimize Area に変更して、実機で確認してみたいと思う。
  1. 2015年03月17日 05:40 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション6(シミュレーション)

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション5(シミュレーション用プロジェクトの作製)”の続き。

前回はシミュレーション用プロジェクトを作成できたので、シミュレーションを行った。

Vivado HLS 2014.1 で高位合成したラプラシアンフィルタIPに設定することはできて、lap_fil_hls_sim_i -> lap_filter_axim_0 -> inst -> lap_filter_axim_LiteS_if_U の I_ap_start は 1 になったのだが、その後の cam_fb のAXIバスのReadが始まらない。
lap_fil_hls_14_1_19_150315.png

いろいろと試してみたのだが、うまく行かないので、Vivado 2014.4 で高位合成したラプラシアンフィルタIPのシミュレーションをやってみることにした。
  1. 2015年03月15日 06:13 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado 2014.4でのVerilog HDLで記述したROM の初期化データの扱い

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション5(シミュレーション用プロジェクトの作製)”でシミュレーション用のプロジェクトが完成したので、シミュレーションを行った。
しかし、”Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション2(reg_set_axi_lite_master IP の作製)”で、Vivado のIPとしたreg_set_axi_lite_master.v のrom 配列にラプラシアンフィルタIP を初期化して、ラプラシアンフィルタ処理をスタートする処理を書き込むことが出来ない。これは、”AXI VDMAのレジスタ設定用AXI Lite Master IPの作製2(シミュレーション)”に詳しく書かれているが、rom という2次元配列に initial 文で $readmemh("vdma_reg_set.txt", rom, 0, 255); を使用して、vdma_reg_set.txt に書いたアドレスとデータを読み込むようになっている。
今回は、vdma_reg_set.txt では、名前が良くないので、reg_set.txt に変更してある。

reg_set.txt をシミュレーションの時の work フォルダに置けば読まれるはずなのだが、プロジェクト内の何処においても読まれない。とっても困ってしまった。

現象としては、Vivado の Flow Navigator -> Simulation -> Run Simulation をクリックして、Run Behavioral Simulation を実行すると、エラボレーション時に、WARNINGが出て、reg_set_axi_lite_master_0 の rom[0:255][31:0] の内容が XXXXXXXX になってしまう。
lap_fil_hls_14_1_9_150312.png

WARNINGの内容を下に示す。

WARNING: File reg_set.txt referenced on Z:/Sim/lap_fil_hls_14_1/lap_fil_hls_14_1.srcs/sources_1/ipshared/marsee/reg_set_axi_lite_master_v1_0/087f6a47/reg_set_axi_lite_master.v at line 59 cannot be opened for reading. Please ensure that this file is available in the current working directory.



ファイル名が Verilog HDL ファイル内で固定されていると、ファイル名やパスを変えるのにIPを変更する必要が出てくるので、もう一度、reg_set_axi_lite_master IP を初期化ファイル名を parameter で変更できるように書き換えようと思う。

reg_set_axi_lite_master.v にROM_INITIALIZATION_FILE parameter を追加した。

module reg_set_axi_lite_master # (
    parameter integer C_M_AXI_ADDR_WIDTH = 32,
    parameter integer C_M_AXI_DATA_WIDTH = 32,
    parameter ROM_INITIALIZATION_FILE = "reg_set.dat"
)(


次に再度 IP化を行った。

Customization Parameters
lap_fil_hls_14_1_6_150312.png

Customization GUI
lap_fil_hls_14_1_7_150312.png

Review and Package を選択して、Re-Package IP ボタンをクリックして、再度 IP 化を行った。
lap_fil_hls_14_1_8_150312.png

reg_set_axi_lite_master IP が変更できた。
ブロック・デザイン上のROM初期化データファイル名を reg_set.txt として、reg_set_axi_lite_master IP の ROM_INITIALIZATION_FILE にフルパス(Z:/Sim/lap_fil_hls_14_1/Simulation/reg_set.txt)で入力した。
lap_fil_hls_14_1_11_150312.png

これで、もう一度、シミュレーションをしてみると、reg_set_axi_lite_master IP の rom に初期化データが入力された。
lap_fil_hls_14_1_12_150312.png

次に、macchan_jp さんに教えてもらった方法を試してみる。それは、初期化データファイルをVivado のプロジェクトに入れてしまうことだ。教えてもらったのは、.dat ファイルをプロジェクトに入れる方法なのだが、私は、ダブルクリックした時に表示してくれるので、.txt ファイルを使用した。シミュレーションの場合には .txt ファイルでも .dat ファイルでもどちらでも初期化データファイルとして使えるようだが、インプリメントの際には .dat ファイルでないとインプリメント出来ないようだ。どちらかと言ったら .dat ファイルを初期化データファイルとして使うことをお勧めする。

初期化データファイルをプロジェクトに入れる方法だと、プロジェクトを配布してファイルへのパスが変わっても問題ないので、絶対パスを入れるよりも良いと思う。それではやってみよう。

まずは、reg_set_axi_lite_master IPの ROM_INITIALIZATION_FILE parameter を reg_set.txt に戻した。
lap_fil_hls_14_1_10_150312.png

File メニューから Add Source... を選択する。

Add Source ダイアログで Add or create simulation sources ラジオボタンを選択する。
lap_fil_hls_14_1_13_150312.png

Add Files... ボタンをクリックして、reg_set.txt を選択する。
lap_fil_hls_14_1_14_150312.png

Simulation Sources に reg_set.txt が入った。
lap_fil_hls_14_1_15_150312.png

これでシミュレーションをすると、絶対パス指定の時と同様に、reg_set_axi_lite_master IP の rom に初期化データが入力された。
lap_fil_hls_14_1_12_150312.png

最後に、reg_set_axi_lite_master.v を貼っておく。

///////////////////////////////////////////////////////////////////////////////
//
// AXI4/Lite Master
//
////////////////////////////////////////////////////////////////////////////
//
// Structure:
//   reg_set_axi_lite_master
//
////////////////////////////////////////////////////////////////////////////

`default_nettype none

module reg_set_axi_lite_master # (
    parameter integer C_M_AXI_ADDR_WIDTH = 32,
    parameter integer C_M_AXI_DATA_WIDTH = 32,
    parameter ROM_INITIALIZATION_FILE = "reg_set.dat"
)(
    // System Signals
    input wire M_AXI_ACLK,
    input wire M_AXI_ARESETN,

    // Master Interface Write Address
    output wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
    output wire [3-1:0] M_AXI_AWPROT,
    output wire M_AXI_AWVALID,
    input wire M_AXI_AWREADY,

    // Master Interface Write Data
    output wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
    output wire [C_M_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB,
    output wire M_AXI_WVALID,
    input wire M_AXI_WREADY,

    // Master Interface Write Response
    input wire [2-1:0] M_AXI_BRESP,
    input wire M_AXI_BVALID,
    output wire M_AXI_BREADY,

    // Master Interface Read Address
    output wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR,
    output wire [3-1:0] M_AXI_ARPROT,
    output wire M_AXI_ARVALID,
    input wire M_AXI_ARREADY,

    // Master Interface Read Data 
    input wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA,
    input wire [2-1:0] M_AXI_RRESP,
    input wire M_AXI_RVALID,
    output wire M_AXI_RREADY,
    
    input    wire    init_done
);

    reg        [31:0] rom [0:255];
    reg        [31:0] rom_dout;
    
    initial begin
        $readmemh(ROM_INITIALIZATION_FILE, rom, 0, 255);
    end
    
    reg        reset_1b, reset;
    reg     [31:0]    reg_addr;
    reg        [31:0]    reg_data;
    reg     [7:0]    rom_addr;
    reg        awvalid;
    reg        wvalid;
    reg        bready;

    localparam    RESP_OKAY =        2'b00,
                RESP_EXOKAY =    2'b01,
                RESP_SLVERR =    2'b10,
                RESP_DECERR =    2'b11;
    
    localparam    IDLE_RRSM =                3'b000,
                ADDRESS_READ =            3'b001,
                DATA_READ =                3'b011,
                REG_SET_DATA_VALID =    3'b010,
                END_RRSM =                3'b110;
    reg        [2:0]    rrsm_cs;
    
    localparam    IDLE_ADDR =            2'b00,
                AWVALID_ASSERT =    2'b01,
                AWVALID_HOLD_OFF =    2'b11;
    reg        [1:0]    addr_cs;
    
    localparam    IDLE_DATA =            2'b00,
                WVALID_ASSERT =        2'b01,
                WVALID_HOLD_OFF =    2'b11;
    reg        [1:0]    data_cs;
    
    localparam    IDLE_RESP =        1'b0,
                BREADY_ASSERT =    1'b1;
    reg        resp_cs;
    
    reg        reg_data_valid;
    reg        rom_read_done;
    
    // Read is not implement
    assign M_AXI_ARADDR = 0;
    assign M_AXI_ARPROT = 3'd0;
    assign M_AXI_ARVALID = 1'b0;
    assign M_AXI_RDATA = 0;
    assign M_AXI_RREADY = 1'b1;
    assign M_AXI_WSTRB = 4'b1111;
    assign M_AXI_AWPROT = 3'b000;
    
    // reset
    always @(posedge M_AXI_ACLK) begin
        reset_1b <= ~M_AXI_ARESETN | ~init_done;
        reset <= reset_1b;
    end
    
    // instantiaton of rom
    always @(posedge M_AXI_ACLK) begin
        rom_dout <= rom[rom_addr];
    end
    
    // rom read State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            rrsm_cs <= IDLE_RRSM;
            reg_data_valid <= 1'b0;
        end else begin
            case (rrsm_cs) 
                IDLE_RRSM : 
                    rrsm_cs <= ADDRESS_READ;
                ADDRESS_READ :
                    rrsm_cs <= DATA_READ;
                DATA_READ : begin
                    if (rom_dout == 32'hFFFF_FFFF) begin // end
                        rrsm_cs <= END_RRSM;
                        reg_data_valid <= 1'b0;
                    end else begin
                        rrsm_cs <= REG_SET_DATA_VALID;
                        reg_data_valid <= 1'b1;
                    end
                end
                REG_SET_DATA_VALID : begin
                    if (rom_read_done) begin
                        rrsm_cs <= ADDRESS_READ;
                        reg_data_valid <= 1'b0;
                    end
                end
                END_RRSM :
                    rrsm_cs <= END_RRSM;
            endcase
        end
    end
    
    // rom_addr
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            rom_addr <= 8'd0;
        end else begin
            if (rrsm_cs == ADDRESS_READ) // Data
                rom_addr <= rom_addr + 8'd1;
            else if (rrsm_cs == REG_SET_DATA_VALID && rom_read_done) // Address
                rom_addr <= rom_addr + 8'd1;
        end
    end
    
    // AXI4 Lite Master Address
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            reg_addr <= 32'd0;
        end else begin
            if (rrsm_cs == DATA_READ)
                reg_addr <= rom_dout;
        end
    end
    assign M_AXI_AWADDR = reg_addr;
    
    // AXI4 Lite Master WDATA
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            reg_data <= 32'd0;
        end else begin
            if (rrsm_cs == REG_SET_DATA_VALID)
                reg_data <= rom_dout;
        end
    end
    assign M_AXI_WDATA = reg_data;
    
    // AXI Lite Master Address State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            addr_cs <= IDLE_ADDR;
            awvalid <= 1'b0;
        end else begin
            case (addr_cs)
                IDLE_ADDR :
                    if (rrsm_cs == REG_SET_DATA_VALID) begin
                        addr_cs <= AWVALID_ASSERT;
                        awvalid <= 1'b1;
                    end
                AWVALID_ASSERT :
                    if (M_AXI_AWREADY) begin
                        addr_cs <= AWVALID_HOLD_OFF;
                        awvalid <= 1'b0;
                    end
                AWVALID_HOLD_OFF :
                    if (rrsm_cs != REG_SET_DATA_VALID)
                        addr_cs <= IDLE_ADDR;
            endcase
        end
    end
    assign M_AXI_AWVALID = awvalid;
    
    // AXI Lite Master Data State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            data_cs <= IDLE_DATA;
            wvalid <= 1'b0;
        end else begin
            case (data_cs)
                IDLE_DATA : begin
                    if (rrsm_cs == REG_SET_DATA_VALID) begin
                        data_cs <= WVALID_ASSERT;
                        wvalid <= 1'b1;
                    end
                end
                WVALID_ASSERT :
                    if (M_AXI_WREADY) begin
                        wvalid <= 1'b0;
                        data_cs <= WVALID_HOLD_OFF;
                    end
                WVALID_HOLD_OFF : begin
                    if (addr_cs == AWVALID_HOLD_OFF && rrsm_cs != REG_SET_DATA_VALID)
                        data_cs <= IDLE_DATA;
                end
            endcase
        end
    end
    assign M_AXI_WVALID = wvalid;
    
    // bready State Machine
    always @(posedge M_AXI_ACLK) begin
        if (reset) begin
            resp_cs <= IDLE_RESP;
            bready <= 1'b0;
            rom_read_done <= 1'b0;
        end else begin
            case (resp_cs)
                IDLE_RESP : begin
                    rom_read_done <= 1'b0;
                    if (M_AXI_WREADY && data_cs == WVALID_ASSERT) begin
                        resp_cs <= BREADY_ASSERT;
                        bready <= 1'b1;
                    end
                end
                BREADY_ASSERT :
                    if (M_AXI_BVALID) begin
                        resp_cs <= IDLE_RESP;
                        bready <= 1'b0;
                        rom_read_done <= 1'b1;
                    end
            endcase
        end
    end
    assign M_AXI_BREADY = bready;
    
endmodule

`default_nettype wire

  1. 2015年03月12日 05:39 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション5(シミュレーション用プロジェクトの作製)

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション4(mem_sim_axi_slave IP の変更2)”の続き。

これで必要なIPが揃ったので、Vivado 2014.1 で作製したラプラシアンフィルタIP をシミュレーションするためのVivado 2014.4 のプロジェクトを作製する。

Vivado 2014.4 で ZYBO 用の lap_fil_hls_14_1 プロジェクトを作製した。
lap_fil_hls_14_1_1_150311.png

lap_fil_hls_sim ブロック・デザインを作製した。完成した状態のブロック・デザインを示す。
lap_fil_hls_14_1_2_150311.png

mem_sim_axi_slave_0 の DEFAULT_VALUE は INCREMENT に設定した。
lap_fil_hls_14_1_3_150311.png

Address Editor ウインドウの内容を下に示す。
lap_fil_hls_14_1_4_150311.png

HDL Wapper ファイルを作製した。lap_fil_hls_sim_wrapper.v を下に示す。

//Copyright 1986-2014 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2014.4 (win64) Build 1071353 Tue Nov 18 18:29:27 MST 2014
//Date        : Sun Mar 08 18:59:24 2015
//Host        : Masaaki-PC running 64-bit Service Pack 1  (build 7601)
//Command     : generate_target lap_fil_hls_sim_wrapper.bd
//Design      : lap_fil_hls_sim_wrapper
//Purpose     : IP block netlist
//--------------------------------------------------------------------------------
`timescale 1 ps / 1 ps

module lap_fil_hls_sim_wrapper
   (clk,
    reset);
  input clk;
  input reset;

  wire clk;
  wire reset;

lap_fil_hls_sim lap_fil_hls_sim_i
       (.clk(clk),
        .reset(reset));
endmodule


テストベンチ lap_fil_hls_sim_wrapper_tb.v を作製した。
lap_fil_hls_14_1_5_150311.png

テストベンチ lap_fil_hls_sim_wrapper_tb.v を下に示す。

// lap_fil_hls_sim_wrapper_tb.v
// 2015/03/11
//

`default_nettype none

`timescale 100ps / 1ps

module lap_fil_hls_sim_wrapper_tb;

    wire clk;
    wire reset;

    lap_fil_hls_sim_wrapper uut (
        .clk(clk),
        .reset(reset)
    );

    // clk
    clk_gen #(
        .CLK_PERIOD(100),    // 10.0nsec, 100MHz
        .CLK_DUTY_CYCLE(0.5),
        .CLK_OFFSET(0),
        .START_STATE(1'b0)
    ) aclk_i (
        .clk_out(clk)
    );

    // reset
    reset_gen #(
        .RESET_STATE(1'b1),
        .RESET_TIME(1000)    // 100nsec
    ) RESETi (
        .reset_out(reset)
    );
    
endmodule

module clk_gen #(
    parameter         CLK_PERIOD = 100,
    parameter real    CLK_DUTY_CYCLE = 0.5,
    parameter        CLK_OFFSET = 0,
    parameter        START_STATE    = 1'b0 )
(
    output    reg        clk_out
);
    begin
        initial begin
            #CLK_OFFSET;
            forever
            begin
                clk_out = START_STATE;
                #(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
                #(CLK_PERIOD*CLK_DUTY_CYCLE);
            end
        end
    end
endmodule

module reset_gen #(
    parameter    RESET_STATE = 1'b1,
    parameter    RESET_TIME = 100 )
(
    output    reg        reset_out
);
    begin
        initial begin
            reset_out = RESET_STATE;
            #RESET_TIME;
            reset_out = ~RESET_STATE;
        end
    end
endmodule

`default_nettype wire

  1. 2015年03月11日 04:30 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション4(mem_sim_axi_slave IP の変更2)

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション3”の続き。

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション3”の mem_sim_axi_slave プロジェクトで IP を再IP化する。

Sources ウインドウから Design Soures -> IP-AXCT -> component.xml をダブルクリックする。
Vivado_HLS_lap_filter_108_150310.png

Package IP ウインドウが立ち上がった。
Vivado_HLS_lap_filter_109_150310.png

この時点では、Customization Parameters に DEFAULT_VALUE パラメータは無い。

Customization Parameters ウインドウで右クリックし、右クリックメニューから Import IP Parameters... を選択する。
Vivado_HLS_lap_filter_110_150310.png

Import IP Parameters from HDL ダイアログが開く。Top entity name が mem_sim_axi_slave になっているので、これで良い。OKボタンをクリックする。
Vivado_HLS_lap_filter_111_150310.png

Customization Parameters に DEFAULT_VALUE パラメータが入った。
Vivado_HLS_lap_filter_112_150310.png

DEFAULT_VALUE パラメータをダブルクリックして設定を行う。
DEFAULT_VALUE パラメータは、0 - All ZERO, 1 - Increment Data, 2 - Random Data となるので、ZEROと入力すると 0、INCREMENT と入力すると 1、RANDOM と入力すると 2 の値を取るようにしたい。

Edit IP Parameter ダイアログが表示された。

Should the value be restricted のラジオボタンの Yes をクリックする。

すると、ダイアログの下に項目が追加される。

How is the value restricted? のリストボックスで pairs を選択する。

下の + Add Pair ボタンをクリックして、ペアを追加する。

key と value が追加される。
Vivado_HLS_lap_filter_113_150310.png

key をダブルクリックして ZERO と入力し、value をダブルクリックして 0 と入力する。
Vivado_HLS_lap_filter_114_150310.png

INCREMENT - 1、RANDOM - 2 と入力した。OKボタンをクリックした。
Vivado_HLS_lap_filter_115_150310.png

DEFAULT_VALUE パラメータのValue Validation List に ZERO:0 INCREMENT:1 RANDOM:2 が入った。
Vivado_HLS_lap_filter_116_150310.png

Customization GUI をクリックすると、Layout 画面に DEFAULT_VALUE パラメータが入っていなかった。これを表示させよう。
Vivado_HLS_lap_filter_117_150310.png

Layout 画面のPage 0 を選択して右クリックし、右クリックメニューから Add Parameter... を選択する。
Vivado_HLS_lap_filter_118_150310.png

Add Parameter ダイアログに DEFAULT_VALUE パラメータがすでに入っていた。Widet Type はRadio Group としたがリストボックスでも選べるようだ。
Vivado_HLS_lap_filter_119_150310.png

OKボタンをクリックすると、Layout 画面のPage 0 に DEFAULT_VALUE パラメータがラジオボタン選択で追加されて、前のダイアログで、Layout を Vertical に設定したので、ラジオボタンが縦に並んでいる。
Vivado_HLS_lap_filter_120_150310.png

Review and Package を選択して、Re-Package IP ボタンをクリックして、再度 IP 化を行った。
Vivado_HLS_lap_filter_121_150310.png
  1. 2015年03月10日 05:32 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション3( mem_sim_axi_slave IP の変更1)

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション2”の続き。

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション1”で作った mem_sim_axi_slave IP のコードを少し修正することにした。
次に、Vivado HLS 2014.1 で作製したラプラシアンフィルタIP のシミュレーションをする予定なのだが、ラプラシアンフィルタIP のレジスタを設定する reg_set_axi_lite_master IP とメモリIP の mem_sim_axi_slave だけでは、メモリの値を書き換えるIP が存在しない。現在では、mem_sim_axi_slave の memory_8bit.v の中でメモリの初期値はオール 0 にクリアされているので、ラプラシアンフィルタIP でカメラデータを Read するために DMA しても、ラプラシアンフィルタ処理後のデータを Write するために DMA しても全て 0 のみとなる。これでは寂しいので、せめて、メモリの初期値を変更できるように、memory_8bit.v のメモリの初期値を変更できるようにした。

実装としては、mem_sim_axi_slave.v に DEFAULT_VALUE で初期値を変更できるようにした。DEFAULT_VALUE = 0 の時は、オール 0 、1 の時は 0 から +1 された値、2 の場合はランダム値(M系列の擬似乱数)を初期値としてメモリに書き込むようにした。

parameter integer DEFAULT_VALUE = 0 // 0 - All ZERO, 1 - Increment Data, 2 - Random Data


修正した後で mem_sim_axi_slave IP の単体シミュレーションを行った。最初に DEFAULT_VALUE = 0 の時、つまり mem の初期値はオール 0 の時だ。下にシミュレーション結果を示す。
Vivado_HLS_lap_filter_105_150309.png

次に、DEFAULT_VALUE = 1 の時、つまり mem の初期値は 0 から +1 された値の時だ。
Vivado_HLS_lap_filter_106_150309.png

最後に、DEFAULT_VALUE = 2 の時、つまり mem の初期値は ランダム値の時だ(M系列の擬似乱数を使用)。
Vivado_HLS_lap_filter_107_150309.png

mem_sim_axi_slave.v を貼っておく。

//-----------------------------------------------------------------------------
//-- (c) Copyright 2010 Xilinx, Inc. All rights reserved.
//--
//-- This file contains confidential and proprietary information
//-- of Xilinx, Inc. and is protected under U.S. and
//-- international copyright and other intellectual property
//-- laws.
//--
//-- DISCLAIMER
//-- This disclaimer is not a license and does not grant any
//-- rights to the materials distributed herewith. Except as
//-- otherwise provided in a valid license issued to you by
//-- Xilinx, and to the maximum extent permitted by applicable
//-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
//-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
//-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
//-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
//-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
//-- (2) Xilinx shall not be liable (whether in contract or tort,
//-- including negligence, or under any other theory of
//-- liability) for any loss or damage of any kind or nature
//-- related to, arising under or in connection with these
//-- materials, including for any direct, or any indirect,
//-- special, incidental, or consequential loss or damage
//-- (including loss of data, profits, goodwill, or any type of
//-- loss or damage suffered as a result of any action brought
//-- by a third party) even if such damage or loss was
//-- reasonably foreseeable or Xilinx had been advised of the
//-- possibility of the same.
//--
//-- CRITICAL APPLICATIONS
//-- Xilinx products are not designed or intended to be fail-
//-- safe, or for use in any application requiring fail-safe
//-- performance, such as life-support or safety devices or
//-- systems, Class III medical devices, nuclear facilities,
//-- applications related to the deployment of airbags, or any
//-- other applications that could lead to death, personal
//-- injury, or severe property or environmental damage
//-- (individually and collectively, "Critical
//-- Applications"). Customer assumes the sole risk and
//-- liability of any use of Xilinx products in Critical
//-- Applications, subject only to applicable laws and
//-- regulations governing limitations on product liability.
//--
//-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
//-- PART OF THIS FILE AT ALL TIMES.
//-----------------------------------------------------------------------------
//
// AXI Slave
//
// Verilog-standard:  Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
//   mem_sim_axi_slave
//
//--------------------------------------------------------------------------
// 
// アクセスのデータ幅は、定義されたデータ幅だけに対応する

`default_nettype none

module mem_sim_axi_slave # (
    parameter integer C_S_AXI_ID_WIDTH             = 1,
    parameter integer C_S_AXI_ADDR_WIDTH            = 32,
    parameter integer C_S_AXI_DATA_WIDTH            = 32,
    parameter integer C_S_AXI_AWUSER_WIDTH          = 1,
    parameter integer C_S_AXI_ARUSER_WIDTH          = 1,
    parameter integer C_S_AXI_WUSER_WIDTH           = 1,
    parameter integer C_S_AXI_RUSER_WIDTH           = 1,
    parameter integer C_S_AXI_BUSER_WIDTH           = 1,

    parameter integer C_MEMORY_SIZE                    = 512,    // Word (not byte)
    parameter integer DEFAULT_VALUE                    = 0     // 0 - All ZERO, 1 - Increment Data, 2 - Random Data
) (
    // System Signals
    input wire ACLK,
    input wire ARESETN,

    // Slave Interface Write Address Ports
    input  wire [C_S_AXI_ID_WIDTH-1:0]     S_AXI_AWID,
    input  wire [C_S_AXI_ADDR_WIDTH-1:0]   S_AXI_AWADDR,
    input  wire [8-1:0]                  S_AXI_AWLEN,
    input  wire [3-1:0]                  S_AXI_AWSIZE,
    input  wire [2-1:0]                  S_AXI_AWBURST,
    input  wire [2-1:0]                  S_AXI_AWLOCK,
    input  wire [4-1:0]                  S_AXI_AWCACHE,
    input  wire [3-1:0]                  S_AXI_AWPROT,
    input  wire [4-1:0]                  S_AXI_AWREGION,
    input  wire [4-1:0]                  S_AXI_AWQOS,
    input  wire [C_S_AXI_AWUSER_WIDTH-1:0] S_AXI_AWUSER,
    input  wire                          S_AXI_AWVALID,
    output wire                          S_AXI_AWREADY,

    // Slave Interface Write Data Ports
    input wire [C_S_AXI_ID_WIDTH-1:0]      S_AXI_WID,
    input  wire [C_S_AXI_DATA_WIDTH-1:0]   S_AXI_WDATA,
    input  wire [C_S_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
    input  wire                          S_AXI_WLAST,
    input  wire [C_S_AXI_WUSER_WIDTH-1:0]  S_AXI_WUSER,
    input  wire                          S_AXI_WVALID,
    output wire                          S_AXI_WREADY,

    // Slave Interface Write Response Ports
    output wire [C_S_AXI_ID_WIDTH-1:0]    S_AXI_BID,
    output wire [2-1:0]                 S_AXI_BRESP,
    output wire [C_S_AXI_BUSER_WIDTH-1:0] S_AXI_BUSER,
    output wire                         S_AXI_BVALID,
    input  wire                         S_AXI_BREADY,

    // Slave Interface Read Address Ports
    input  wire [C_S_AXI_ID_WIDTH-1:0]     S_AXI_ARID,
    input  wire [C_S_AXI_ADDR_WIDTH-1:0]   S_AXI_ARADDR,
    input  wire [8-1:0]                  S_AXI_ARLEN,
    input  wire [3-1:0]                  S_AXI_ARSIZE,
    input  wire [2-1:0]                  S_AXI_ARBURST,
    input  wire [2-1:0]                  S_AXI_ARLOCK,
    input  wire [4-1:0]                  S_AXI_ARCACHE,
    input  wire [3-1:0]                  S_AXI_ARPROT,
    input  wire [4-1:0]                  S_AXI_ARREGION,
    input  wire [4-1:0]                  S_AXI_ARQOS,
    input  wire [C_S_AXI_ARUSER_WIDTH-1:0] S_AXI_ARUSER,
    input  wire                          S_AXI_ARVALID,
    output wire                          S_AXI_ARREADY,

    // Slave Interface Read Data Ports
    output wire [C_S_AXI_ID_WIDTH-1:0]    S_AXI_RID,
    output wire [C_S_AXI_DATA_WIDTH-1:0]  S_AXI_RDATA,
    output wire [2-1:0]                 S_AXI_RRESP,
    output wire                         S_AXI_RLAST,
    output wire [C_S_AXI_RUSER_WIDTH-1:0] S_AXI_RUSER,
    output wire                         S_AXI_RVALID,
    input  wire                         S_AXI_RREADY
   
);

    // Value of S_AXI_BRESP
    localparam    RESP_OKAY =        2'b00,
                RESP_EXOKAY =    2'b01,
                RESP_SLVERR =    2'b10,
                RESP_DECERR =    2'b11;
    
    // Value of S_AXI_ARBURST
    localparam    AxBURST_FIXED =    2'b00,
                AxBURST_INCR =    2'b01,
                AxBURST_WRAP =    2'b10;

    localparam    IDLE_WADDR =         1'b0,
                AWREADY_HOLD_OFF =    1'b1;
    reg        waddr_sm_cs;
    reg        awready;
    reg        awid;
    reg        [C_S_AXI_ADDR_WIDTH-1:0]    waddr;
    reg        [2-1:0]    awburst;
    
    localparam    IDLE_WDATA =    1'b0,
                WREADY_ASSERT =    1'b1;
    reg        wdata_sm_cs;
    reg        wready;
    
    localparam    IDLE_WRES =        1'b0,
                BVALID_ASSERT =    1'b1;
    reg        wres_sm_cs;
    reg        [2-1:0]    bresp;
    reg        bvalid;
    
    localparam    IDLE_RADDR =        1'b0,
                ARREADY_HOLD_OFF =    1'b1;
    reg        raddr_sm_cs;
    reg        arready;
    reg        [C_S_AXI_ID_WIDTH-1:0]    arid;
    reg        [C_S_AXI_ADDR_WIDTH-1:0]    raddr;
    
    localparam    IDLE_RDATA =    1'b0,
                RVALID_ASSERT =    1'b1;
    reg        rdata_sm_cs;
    reg        rvalid;
    reg        [C_S_AXI_ID_WIDTH-1:0]    rid;
    reg        [1:0]    rresp;
    reg        [8:0]    rdata_count;
    
    localparam    IDLE_RLAST =     1'b0,
                RLAST_ASSERT =    1'b1;
    reg        rlast_sm_cs;
    reg        rlast;
    
    // instance memory_8bit
    generate
        genvar i;
        
        for (i=(C_S_AXI_DATA_WIDTH/8-1); i>=0; i=i-1) begin : MEMORY_GEN
            memory_8bit #(
                .C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH),
                .C_MEMORY_SIZE(C_MEMORY_SIZE),
                .DEFAULT_VALUE(DEFAULT_VALUE)
            ) memory_8bit_i (
                .clk(ACLK),
                .waddr(waddr),
                .write_data(S_AXI_WDATA[i*8+7:i*8]),
                .write_enable(wready & S_AXI_WVALID),
                .byte_enable(S_AXI_WSTRB[i]),
                .raddr(raddr),
                .read_data(S_AXI_RDATA[i*8+7:i*8])
            );
        end
    endgenerate
    
    // Write Transaction
    assign S_AXI_BUSER = 1'd0;
    
    // waddr State Machine
    // awready is normally 1. if S_AXI_AWVALID is 1 then awready is 0.
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            waddr_sm_cs <= IDLE_WADDR;
            awready <= 1'b1;
            awid <= {C_S_AXI_ID_WIDTH{1'b0}};
            awburst <= 2'd0;
        end else begin
            case (waddr_sm_cs)
                IDLE_WADDR : 
                    if (S_AXI_AWVALID) begin
                        waddr_sm_cs <= AWREADY_HOLD_OFF;
                        awready <= 1'b0;
                        awid <= S_AXI_AWID;
                        awburst <= S_AXI_AWBURST;
                    end
                AWREADY_HOLD_OFF :
                    if (bvalid) begin
                        waddr_sm_cs <= IDLE_WADDR;
                        awready <= 1'b1;
                    end
            endcase
        end
    end
    assign S_AXI_AWREADY = awready;
    
    // waddr
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            waddr <= {C_S_AXI_ADDR_WIDTH{1'b0}};
        end else begin
            if (waddr_sm_cs == IDLE_WADDR & S_AXI_AWVALID)
                waddr <= S_AXI_AWADDR;
            else if (wready & S_AXI_WVALID)
                waddr <= waddr + C_S_AXI_DATA_WIDTH/8;
        end
    end
    
    // wdata State Machine
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            wdata_sm_cs <= IDLE_WDATA;
            wready <= 1'b0;
        end else begin
            case (wdata_sm_cs)
                IDLE_WDATA :
                    if (waddr_sm_cs == IDLE_WADDR && S_AXI_AWVALID) begin // Write transaction start
                        wdata_sm_cs <= WREADY_ASSERT;
                        wready <= 1'b1;
                    end
                WREADY_ASSERT :
                    if (S_AXI_WLAST & S_AXI_WVALID) begin    // Write transaction end
                        wdata_sm_cs <= IDLE_WDATA;
                        wready <= 1'b0;
                    end
            endcase
        end
    end
    assign S_AXI_WREADY = wready;
    
    assign S_AXI_BID = awid;
    // Write Response State Machine
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            wres_sm_cs <= IDLE_WRES;
            bvalid <= 1'b0;
        end else begin
            case (wres_sm_cs)
                IDLE_WRES :
                    if (wdata_sm_cs == WREADY_ASSERT & S_AXI_WLAST & S_AXI_WVALID) begin    // Write transaction end
                        wres_sm_cs <= BVALID_ASSERT;
                        bvalid <= 1'b1;
                    end
                BVALID_ASSERT :
                    if (S_AXI_BREADY) begin
                        wres_sm_cs <= IDLE_WRES;
                        bvalid <= 1'b0;
                    end
            endcase
        end
    end
    assign S_AXI_BVALID = bvalid;
    
    // bresp
    // if S_AXI_AWBURST is INCR then return OKAY else return SLVERR
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0)
            bresp <= 2'b0;
        else begin
            if (waddr_sm_cs == AWREADY_HOLD_OFF) begin
                if (awburst == AxBURST_INCR) // The burst type is Addres Increment Type
                    bresp <= RESP_OKAY; // The Write Transaction is success
                else
                    bresp <= RESP_SLVERR; // Error
            end
        end
    end
    assign S_AXI_BRESP = bresp;

    // Read Transaction
    assign S_AXI_RUSER = 0;
    
    // raddr State Machine
    // arready is normally 1. if S_AXI_ARVALID is 1 then arready is 0.
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            raddr_sm_cs <= IDLE_RADDR;
            arready <= 1'b1;
            arid <= {C_S_AXI_ID_WIDTH{1'b0}};
        end else begin
            case (raddr_sm_cs)
                IDLE_RADDR :
                    if (S_AXI_ARVALID) begin
                        raddr_sm_cs <= ARREADY_HOLD_OFF;
                        arready <= 1'b0;
                        arid <= S_AXI_ARID;
                    end
                ARREADY_HOLD_OFF :
                    if (rvalid & S_AXI_RREADY & S_AXI_RLAST) begin // Read Transaction End
                        raddr_sm_cs <= IDLE_RADDR;
                        arready <= 1'b1;
                    end
            endcase
        end
    end
    assign S_AXI_ARREADY = arready;
    
    // raddr
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            raddr <= {C_S_AXI_ADDR_WIDTH{1'b0}};
        end else begin
            if (raddr_sm_cs == IDLE_RADDR & S_AXI_ARVALID)
                raddr <= S_AXI_ARADDR;
            else if (rvalid & S_AXI_RREADY)
                raddr <= raddr + C_S_AXI_ADDR_WIDTH/8;
        end
    end
    
    // rdata State Machine
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            rdata_sm_cs <= IDLE_RDATA;
            rvalid <= 1'b0;
            rid <= {C_S_AXI_ID_WIDTH{1'b0}};
        end else begin
            case (rdata_sm_cs)
                IDLE_RDATA :
                    if (raddr_sm_cs == IDLE_RADDR & S_AXI_ARVALID) begin 
                        rdata_sm_cs <= RVALID_ASSERT;
                        rvalid <= 1'b1;
                    end
                RVALID_ASSERT :
                    if (rlast & S_AXI_RREADY) begin
                        rdata_sm_cs <= IDLE_RDATA;
                        rvalid <= 1'b0;
                    end
            endcase
        end
    end
    assign S_AXI_RVALID = rvalid;
    assign S_AXI_RID = arid;
    
    //     assign S_AXI_RRESP = RESP_OKAY;
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            rresp <= RESP_OKAY;
        end else if (rdata_sm_cs == RVALID_ASSERT && rid != arid) begin
            rresp <= RESP_SLVERR;
        end
    end
    assign S_AXI_RRESP = rresp;
    
    // rdata_count
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            rdata_count <= 9'd0;
        end else begin
            if (raddr_sm_cs == IDLE_RADDR & S_AXI_ARVALID)
                rdata_count <= {1'b0, S_AXI_ARLEN} + 9'd1;
            else if (rvalid & S_AXI_RREADY)
                rdata_count <= rdata_count - 9'd1;
        end
    end
    
    // rlast
    always @(posedge ACLK) begin
        if (ARESETN == 1'b0) begin
            rlast_sm_cs <= IDLE_RLAST;
            rlast <= 1'b0;
        end else begin
            case (rlast_sm_cs)
                IDLE_RLAST :
                    if (rdata_count == 9'd2 && (rvalid & S_AXI_RREADY)) begin
                        rlast_sm_cs <= RLAST_ASSERT;
                        rlast <= 1'b1;
                    end else if (raddr_sm_cs==IDLE_RADDR && S_AXI_ARVALID==1'b1 && S_AXI_ARLEN==8'd0) begin
                    // 転送数が1の時はデータ転送の最初からrlast を1にする
                        rlast_sm_cs <= RLAST_ASSERT;
                        rlast <= 1'b1;
                    end
                RLAST_ASSERT :
                    if (rvalid & S_AXI_RREADY) begin
                        rlast_sm_cs <= IDLE_RLAST;
                        rlast <= 1'b0;
                    end
            endcase
        end
    end
    assign S_AXI_RLAST = rlast;
    
endmodule

`default_nettype wire


memory_8bit.v を貼っておく。

// 8bit Memory Module

`default_nettype none

module memory_8bit #(
    parameter integer C_S_AXI_ADDR_WIDTH            = 32,
    parameter integer C_MEMORY_SIZE                    = 512,    // Word (not byte)
    parameter integer DEFAULT_VALUE                    = 0     // 0 - All ZERO, 1 - Increment Data, 2 - Random Data
)(
    input    wire    clk,
    input    wire    [C_S_AXI_ADDR_WIDTH-1:0]    waddr,
    input    wire    [7:0]    write_data,
    input    wire    write_enable,
    input    wire    byte_enable,
    input    wire    [C_S_AXI_ADDR_WIDTH-1:0]    raddr,
    output    wire    [7:0]    read_data
);

    // Beyond Circuts, Constant Function in Verilog 2001
    // http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/
    function integer log2;
        input integer addr;
        begin
            addr = addr - 1;
            for (log2=0; addr>0; log2=log2+1)
                addr = addr >> 1;
        end
    endfunction

    function [7:0] mseqf8_0 (input [7:0] din);
        reg xor_result;
        begin
            xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
            mseqf8_0 = {din[6:0], xor_result};
        end
    endfunction
    
    reg        [7:0]    mem    [0:C_MEMORY_SIZE-1];
    wire    [log2(C_MEMORY_SIZE)-1:0]    mem_waddr;
    wire    [log2(C_MEMORY_SIZE)-1:0]    mem_raddr;
    integer i;
    reg    [7:0]   mseq8 = 8'd1;
    
    // initialization
    initial begin
        for (i=0; i < C_MEMORY_SIZE; i=i+1) begin
            if (DEFAULT_VALUE == 0) begin             // All ZERO
                mem[i] = 8'd0;
            end else if (DEFAULT_VALUE == 1) begin     // Increment Data
                mem[i] = i;
            end else begin                          // Ramdom Data
                if (i == 0) begin
                    mem[i] = 1;
                end else begin
                    mem[i] = mseqf8_0(mem[i-1]);
                end
            end
        end
    end
    
    // The Address is byte address
    assign mem_waddr = waddr[(log2(C_MEMORY_SIZE)+log2((C_S_AXI_ADDR_WIDTH/8)))-1:log2((C_S_AXI_ADDR_WIDTH/8))];
    assign mem_raddr = raddr[(log2(C_MEMORY_SIZE)+log2((C_S_AXI_ADDR_WIDTH/8)))-1:log2((C_S_AXI_ADDR_WIDTH/8))];
    
    // Write
    always @(posedge clk) begin
        if (write_enable & byte_enable)
            mem[mem_waddr] <= write_data;
    end
    
    // Read
    // always @(posedge clk) begin
    assign read_data = mem[mem_raddr];
    // end
endmodule

`default_nettype wire

  1. 2015年03月09日 05:59 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

ソロモンの偽証 前編・事件の映画を見てきました

昨日、ソロモンの偽証 前編・事件の映画を見てきました。なかなか良かったです。
主演の中学生の女の子の演技が上手いなと思いました。4月の後編を絶対に見たいです。
  1. 2015年03月08日 21:50 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション2(reg_set_axi_lite_master IP の作製)

”Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション1”の続き。

前回は、AXI4 Slave を持った汎用メモリモデルの mem_sim_axi_slave IPを作製した。今回は、設定レジスタを設定する AXI Lite Master IP の reg_set_axi_lite_master を作製する。

reg_set_axi_lite_master.v の仕様と Verilog HDL コードについては、”AXI VDMAのレジスタ設定用AXI Lite Master IPの作製2(シミュレーション)”を参照下さい。

Vivado 2014.4 で、C:\Users\Masaaki\Documents\Vivado\Zynq\ZYBO\IP_test フォルダに、ZYBO用の reg_set_axi_lite_master プロジェクトを作製した。プロジェクトに入れた Verilog HDL ソースは、reg_set_axi_lite_master.v だ。
Vivado_HLS_lap_filter_90_150308.png

IP 化するために、Tools メニューから Create and Package IP... を選択して、IP化する。

Create and Package IP ダイアログが表示された。

Choose Create Peripheral or Package IP で Package your current project のラジオボタンを選択した。
Vivado_HLS_lap_filter_75_150306.png

Package Your Current Project のIP location を確認した。デフォルトでOK。
Vivado_HLS_lap_filter_91_150308.png

New IP Creation の Finish ボタンをクリックする。
Vivado_HLS_lap_filter_77_150306.png

右のウインドウにPackage IP のタブができた。最初にIdentifiaction が表示されている。Vender を marsee に変更した。
Vivado_HLS_lap_filter_92_150308.png

Compatibility 画面。
Vivado_HLS_lap_filter_93_150308.png

File Groups 画面。
Vivado_HLS_lap_filter_94_150308.png

Customization Parameters 画面。
Vivado_HLS_lap_filter_95_150308.png

Ports and Interface 画面。M_AXI ポートが認識されている。
Vivado_HLS_lap_filter_96_150308.png

Addressing and Memory 画面。Master IP なので、4GBアクセスで問題ない。
Vivado_HLS_lap_filter_97_150308.png

Customization GUI 画面。
Vivado_HLS_lap_filter_98_150308.png

Review and Package 画面で edit packaging settings をクリックした。
Vivado_HLS_lap_filter_99_150308.png

Automatic Behavior -> After Packaging -> Create archive of IP のチェックボックスにチェックが入っていた。これで、IPのZIPファイルが生成される。
Vivado_HLS_lap_filter_100_150308.png

もう一度、Review and Package 画面で Package IP をクリックする。
Vivado_HLS_lap_filter_101_150308.png

marsee_user_reg_set_axi_lite_master_1.0.zip ができていた。
Vivado_HLS_lap_filter_102_150308.png

marsee_user_reg_set_axi_lite_master_1.0.zip の内容を示す。
Vivado_HLS_lap_filter_103_150308.png
  1. 2015年03月08日 04:48 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをシミュレーション1(mem_sim_axi_slave IP の作製)

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する3”の続き。

前回、Vivado HLS 2014.1 で作製したラプラシアンフィルタ IP が動作しなかったので、シミュレーションを行う。シミュレーションをしたのはZedBoardの時で、AXI4 Slave を持った汎用メモリモデル IP の mem_sim_axi_slave と設定レジスタを設定する AXI Lite Master IP の reg_set_axi_lite_master を使用する。詳しくは、”Vivado HLS 2013.4でラプラシアン・フィルタ関数をaxi masterモジュールにする5(単体シミュレーション)”を参照下さい。

今回は、前回シミュレーションした時は、ISE を使用していたので、今回は、Vivado に変更する必要がある。mem_sim_axi_slave と reg_set_axi_lite_master をVivado の IP として作製する。

最初に mem_sim_axi_slave から作製する。
Vivado 2014.4 で、C:\Users\Masaaki\Documents\Vivado\Zynq\ZYBO\IP_test フォルダに、mem_sim_axi_slave プロジェクトを作製した。プロジェクトに入れた Verilog HDL ソースは、mem_sim_axi_slave.v と memory_8bit.v だ。
Vivado_HLS_lap_filter_74_150306.png

mem_sim_axi_slave を IP 化するために、Tools メニューから Create and Package IP... を選択して、IP化する。

Create and Package IP ダイアログが表示された。

Choose Create Peripheral or Package IP で Package your current project のラジオボタンを選択した。
Vivado_HLS_lap_filter_75_150306.png

Package Your Current Project のIP location を確認した。デフォルトでOK。
Vivado_HLS_lap_filter_76_150306.png

New IP Creation の Finish ボタンをクリックする。
Vivado_HLS_lap_filter_77_150306.png

右のウインドウにPackage IP のタブができた。最初にIdentifiaction が表示されている。
Vivado_HLS_lap_filter_78_150307.png

Compatibility 画面。
Vivado_HLS_lap_filter_79_150307.png

File Groups 画面。
Vivado_HLS_lap_filter_80_150307.png

Customization Parameters 画面。
Vivado_HLS_lap_filter_81_150307.png

Ports and Interface 画面。S_AXI ポートが認識されている。
Vivado_HLS_lap_filter_82_150307.png

Addressing and Memory 画面。ワーニングが出ている。4GBアクセスになっていたので、Range Dependency に pow(2,(C_S_AXI_ADDR_WIDTH - 3) + 1) を入力して 1 GBに変更した。
Vivado_HLS_lap_filter_83_150307.png

ワーニングを示す

。[IP_Flow 19-3238] Range of address space is set to a full 4G (Address Block 'reg0' of Memory Map 'S_AXI'). Consider reducing this by setting the range of the address block to a lower number, or alternatively reduce the number of bits on the address line in your HDL's top level file interface and repackage the IP.


Customization GUI 画面。
Vivado_HLS_lap_filter_84_150307.png

Review and Package 画面で edit packaging settings をクリックした。
Vivado_HLS_lap_filter_85_150307.png

Automatic Behavior -> After Packaging -> Create archive of IP のチェックボックスにチェックを入れた。これで、IPのZIPファイルが生成される。
Vivado_HLS_lap_filter_86_150307.png

もう一度、Review and Package 画面で Package IP をクリックする。
Vivado_HLS_lap_filter_87_150307.png

marsee_user_mem_sim_axi_slave_1.0.zip ができている。
Vivado_HLS_lap_filter_88_150307.png

marsee_user_mem_sim_axi_slave_1.0.zip の内容を示す。
Vivado_HLS_lap_filter_89_150307.png

なお、mem_sim_axi_slave.v と memory_8bit.v のVerilog HDLコードについては、”AXI4 Slave インターフェースのメモリ・シミュレーション用 IP の作製2(シミュレーション)”を参照下さい。
  1. 2015年03月06日 06:30 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する3

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する2”の続き。

前回、Vivado HLS 2014.1 を使用したラプラシアンフィルタ IPをVivado 2014.4 で論理合成、インプリメント、ビットストリームの生成を行い、SDKを起動してBOOT.binを作製した。
今回は、BOOT.binをMicro SDカードにコピーして、ZYBOに挿入して電源ONを行った。

次に、Vivado HLS 2014.1 を使用したラプラシアンフィルタ IPを制御する制御ソフトウェアを作るのだが、これは、以前作った lap_fil_hls_1shot.vld.c をほとんどコピーした(lap_fil_hls_1shot_vld.c)。

Makefile も書きなおして、ZYBOの~/Apps/lap_fil_hls_1shot_vld ディスプレイ上でコピーした。

Vivado HLS 2014.1 を使用したラプラシアンフィルタ IPの drivers\lap_filter_axim_top_v1_0\src の C ソーフファイルと C ヘッダファイル、xlap_filter_axim.c、xlap_filter_axim.h、xlap_filter_axim_hw.h、xlap_filter_axim_linux.c をZYBO の同一のフォルダにコピーした。

make コマンドでコンパイルした所、コンパイルエラー発生。原因は XLap_filter_axim 構造体のメンバの名前が書き換わっていたことだ、Vivado 2014.4 では、u32 Bus_axi4ls_BaseAddress; だったが、Vivado 2014.1 では、u32 Lites_BaseAddress; だった。

更に、cam_addr ポートが ap_hs、lap_addr ポートが lap_addr なので、アドレスをセットした後でvld をセットする関数を追加した。


XLap_filter_axim_SetCam_addr(lap_fil_lsalvep, (u32)fb_addr);
XLap_filter_axim_SetCam_addrVld(lap_fil_lsalvep);

XLap_filter_axim_SetLap_addr(lap_fil_lsalvep, (u32)next_frame_addr);
XLap_filter_axim_SetLap_addrVld(lap_fil_lsalvep);


これで make したところ、コンパイル、リンク共に通った。

./cam_disp_uio でカメラを表示してから、./lap_fil_hls_1shot_vld を起動したところ、ラプラシアンフィルタ処理のDONE待ち関数から1秒間帰ってこなかった。
Vivado_HLS_lap_filter_72_150305.png

その部分のコードを下に示す。


while(!(c =(int)XLap_filter_axim_IsDone(lap_fil_lsalvep)))
printf("%x\n", c);
printf("%x\n", c);


どうしてDONE待ちから帰ってこないかわからない?

下に、printf()デバッグコードが入ったlap_fil_hls_1shot_vld.cを示す。

// lap_fil_hls_1shot_vld.c
// by marsee
// 2015/03/03

#include "xlap_filter_axim.h"

#define CMA_START_ADDRESS 0x17800000
#define VIDEO_BUFFER_START_ADDRESS 0x18000000 // Limit 0x18800000, 800*600*4 = 2MBytes * 2
#define LAPLACIAN_FILTER_ADDRESS 0x18200000 // 800*600*4 = 0x1d4c00

int main() {
unsigned int fb_addr, next_frame_addr;
struct timeval start_time, temp1, temp2, end_time;
XLap_filter_axim lap_fil_lsalve, frame_buf, bitmap_dispc;
XLap_filter_axim *lap_fil_lsalvep, *frame_bufp, *bitmap_dispcp;
int c;

gettimeofday(&start_time, NULL);

lap_fil_lsalvep = &lap_fil_lsalve;
frame_bufp = &frame_buf;
bitmap_dispcp = &bitmap_dispc;

// Initialization of bitmap display controller
if (XLap_filter_axim_Initialize(bitmap_dispcp, "bitmap_display_cntrler_axim") != XST_SUCCESS){
fprintf(stderr, "bitmap_display_cntrler_axim open error\n");
exit(-1);
}

// Initialization of frame_buffer
if (XLap_filter_axim_Initialize(frame_bufp, "frame_buffer_bmdc") != XST_SUCCESS){
fprintf(stderr, "frame_buffer_bmdc open error\n");
exit(-1);
}

printf("fb_base_addr = %x\n", frame_bufp->Lites_BaseAddress);

fb_addr = (unsigned int)frame_bufp->Lites_BaseAddress + (unsigned int)(VIDEO_BUFFER_START_ADDRESS-CMA_START_ADDRESS);
printf("fb_addr = %x\n", fb_addr);


// frame buffer for laplacian filter result
next_frame_addr = (unsigned int)frame_bufp->Lites_BaseAddress + (unsigned int)(LAPLACIAN_FILTER_ADDRESS-CMA_START_ADDRESS);
printf("next_frame_addr = %x\n", next_frame_addr);

// Initialization of lap_filter_axim
if (XLap_filter_axim_Initialize(lap_fil_lsalvep, "lap_filter_axim_hls") != XST_SUCCESS){
fprintf(stderr, "lap_filter_axim_hls open error\n");
exit(-1);
}

XLap_filter_axim_SetCam_addr(lap_fil_lsalvep, (u32)fb_addr);
XLap_filter_axim_SetCam_addrVld(lap_fil_lsalvep);
printf("%x\n", XLap_filter_axim_GetCam_addr(lap_fil_lsalvep));

XLap_filter_axim_SetLap_addr(lap_fil_lsalvep, (u32)next_frame_addr);
XLap_filter_axim_SetLap_addrVld(lap_fil_lsalvep);
printf("%x\n", XLap_filter_axim_GetLap_addr(lap_fil_lsalvep));

XLap_filter_axim_Start(lap_fil_lsalvep);

printf("Control signals = %x\n", XLap_filter_axim_ReadReg(lap_fil_lsalvep->Lites_BaseAddress, XLAP_FILTER_AXIM_LITES_ADDR_AP_CTRL));

//exit(1);

while(!(c =(int)XLap_filter_axim_IsDone(lap_fil_lsalvep)))
printf("%x\n", c);
printf("%x\n", c);

// Displayed the laplacian filter image
*(volatile unsigned int *)bitmap_dispcp->Lites_BaseAddress = (unsigned int)LAPLACIAN_FILTER_ADDRESS;

if (XLap_filter_axim_Release(lap_fil_lsalvep) != XST_SUCCESS){
fprintf(stderr, "lap_filter_axim_hls release error\n");
exit(-1);
}

if (XLap_filter_axim_Release(frame_bufp) != XST_SUCCESS){
fprintf(stderr, "frame_buffer_bmdc release error\n");
exit(-1);
}

if (XLap_filter_axim_Release(bitmap_dispcp) != XST_SUCCESS){
fprintf(stderr, "bitmap_display_cntrler_axim release error\n");
exit(-1);
}

// Displayed the laplacian filter image
*(volatile unsigned int *)bitmap_dispcp->Lites_BaseAddress = (unsigned int)next_frame_addr;

// Displayed the procee past time
gettimeofday(&end_time, NULL);
if (end_time.tv_usec < start_time.tv_usec) {
printf("total time = %ld.%6.6ld sec\n", end_time.tv_sec - start_time.tv_sec - 1, 1000000 + end_time.tv_usec - start_time.tv_usec);
}
else {
printf("total time = %ld.%6.6ld sec\n", end_time.tv_sec - start_time.tv_sec, end_time.tv_usec - start_time.tv_usec);
}

return(0);
}

最後に、64行目の exit(1); のコメントを外した状態での結果を示す。
Vivado_HLS_lap_filter_73_150305.png
  1. 2015年03月05日 06:05 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する2

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する1”の続き。

前回は、以前のCソースコード(ZedBoardでラプラシアンフィルタのVivado HLS のラプラシアンフィルタIPを動作させた時)のままで、Vivado HLS 2014.1 を使用してラプラシアンフィルタ IP を作った。
今回は、Vivado HLS 2014.1 で作製したラプラシアンフィルタ IP を ZYBO のVivado 2014.4 にプロジェクトのブロック・デザインの中に入れて論理合成、インプリメント、ビットストリームの生成後、BOOT.binの作製を行う。

V_ZYBO_CAMDfL144_2 プロジェクトを新たに作製した。

V_ZYBO_CMADfLブロック・デザインを作製し、その中にカメラ・コントローラーIPやビットマップ・ディスプレイ・コントローラーIP、Vivado HLS 2014.1 で作製したラプラシアンフィルタ IP を入れてブロック・デザインを作製した。
Vivado_HLS_lap_filter_69_150304.png

HDL Wapperファイルを作製し、制約ファイルを”Vivado HLS 2014.4でラプラシアン・フィルタ関数をaxi masterモジュールにする4(ブロックデザインにVivado HLSのIPを追加、インプリメント)”からコピーしてきた。

論理合成、インプリメント、ビットストリームの生成を行い成功した。
Vivado_HLS_lap_filter_70_150304.png

ハードウェアをエクスポートして、SDKを立ちあげた。

FSBLプロジェクトを作製し、BOOT.bin を生成した。
Vivado_HLS_lap_filter_71_150304.png
  1. 2015年03月04日 04:49 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル3

Vivado HLS 2014.1 でラプラシアンフィルタIPを作って、Vivado 2014.4 のプロジェクトを新規作成し、ブロック・デザインを構築していく過程で、ラプラシアンフィルタ IP のAXI4 Master バスは、カメラ・コントローラー IPとビットマップ・ディスプレイ・コントローラー IP のAXI4 Master が入っている AXI Interconnect に入っている。これをラプラシアンフィルタ IP 独自の AXI Interconnect にして、Zynq PS の AXI HP2 ポートに入れたらどうだろう?と考えた。
とりあえず、これを Vivado HLS 2014.1 で作ったラプラシアンフィルタ IP を試す前にやってみることにした。
なお、”ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル2”の続きということになる。

以前のブロック・デザインの V_ZYBO_CAMDfL を下に示す。
Vivado_HLS_lap_filter_35_150208.png

今回、ラプラシアンフィルタ IP 独自の AXI Interconnect にして、Zynq PS の AXI HP2 ポートに入れた時のブロック・デザインを下に示す。
Vivado_HLS_lap_filter_67_150301.png

これで、論理合成、インプリメント、ビットストリームの生成を行い、ハードウェアをエクスポートして、SDKを立ちあげて、BOOT.bin を生成した。そのBOOT.bin を MicroSDカードの BOOT.bin と入れ替えて ZYBO に挿入した。
電源ON で Ubuntu 14.04 LTS が立ち上がる。
SSHでログインして、Apps/lap_fil_hls_1shot ディレクトリに cd する。
./cam_disp_uio を起動する。これでカメラの表示がONとなる。
./lap_fil_hls_1shot でラプラシアンフィルタ IP を起動してラプラシアンフィルタ処理を行った所、変換処理には約 27 秒かかるもののラプラシアンフィルタの変換を行っている間にディスプレイの画面が乱れなくなった。
Vivado_HLS_lap_filter_68_150302.png

画面の乱れは、ビットマップ・ディスプレイ・コントローラー IP のDMA が間に合ってなくて、表示ピクセルを溜めておく非同期FIFO が Empty になってしまったのだと思う。
カメラ・コントローラー IP の AXI4 バスの使用率は 800 x 600 ピクセル画像の 15 fps なので、800 x 600 x 15 fps x 4 byte = 28.8 Mbyte/sec (Write Only)
ビットマップ・ディスプレイ・コントローラー IP のAXI4 バスの使用率は、800 x 600 ピクセル画像の 60 fps なので、800 x 600 x 60 fps x 4byte = 115.2 Mbyte/sec (Read Only)
ラプラシアンフィルタ IP のAXI4 バス幅は32ビットで、どの位、バスを専有してるか未知数だが、フルにメモリ帯域を使ったとして計算してみると、100 MHz x 4 byte (32ビット幅) = 400Mbyte/sec (Read/Write 同じ)

3つの合計で Write は、28.8 + 400 = 428.8 Mbyte/sec、Read は 115.2 + 400 = 515.2 Mbyte/sec となった。

Zynq の AXI_HP0, AXI_HP2 のデータ・バス幅は64ビット幅で 100MHz なので、1ポートあたりのバス帯域は、100 MHz x 8 byte (64ビット幅) = 800 Mbyte/sec (Read/Write 同じ)

Write のバス帯域使用率は、428.8 / 800 x 100 = 53.6 %
Read のバス帯域使用率は、512.2 / 800 x 100 = 64.0 %

Read のバス帯域使用率は 64 % となった。割と使用率が高いが、ビットマップ・ディスプレイ・コントローラー IP のDMA が間に合わないのはおかしい気もする。ラプラシアンフィルタ IP のバス帯域使用率は、最大値を見込んでいるのであるし、64 % よりも低いと思われる。
局所的にバス帯域が使われてしまったのだろうか?非常に興味深い。

(追記) Vivado HLS で合成したラプラシアンフィルタの処理時間が27秒かかるバグの原因は、古いバグありラプラシアンフィルタのCソースコードを使用したためでした。正しいラプラシアンフィルタのCソースコードについては、”Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”をご覧ください。

とりあえず、バグ無しのラプラシアンフィルタ処理を実行した経過については、”ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル4(うまく行った)”をご覧ください。
  1. 2015年03月02日 04:28 |
  2. AXI4バス
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS 2014.1で生成したラプラシアンフィルタIPをZYBOのカメラ表示システム上で使用する1

ZYBO Linux (Ubuntu 14.04 LTS) 上でMakefile を作ってラプラシアンフィルタIPの制御ソフトをコンパイル2”の続き。

前回は、Vivado HLS 2014.4 で生成したラプラシアンフィルタ IP を ZYBO のカメラ表示システムに追加してテストした。正常にラプラシアンフィルタ処理後の画像が表示されたが、28 秒程度かかり、しかもその間、表示画像が乱れていた。
Vivado HLS 2014.4 は、Vivado HLS 2014.1 からVivado HLS 2014.4 の間で、AXI4バスを生成するディレクティブが変更されたことでも分かるように、大きく変更されたのでは無いかと思う。
今回は、Vivado HLS 2014.1 を使用して、以前のCソースコードのままでやってみようと思う。思い返してみれば、ZYBO でVivado HLS のIP を動作させたことは無かった。

Vivado HLS 2014.1 のプロジェクトを作製して、以前のVivado HLS 用のラプラシアンフィルタのCソースコードをプロジェクトに入れた。そして、高位合成して、IP化を行った。
Vivado_HLS_lap_filter_66_150301.png

このCソースコードの cam_addr は ap_hs インターフェース、lap_addr は ap_vld インターフェースに設定してあるので、cam_addr と lap_addr を ap_none に設定してある Vivado HLS 2014.4 と比べて、Control signal のアドレスが増えている。下に、xlap_filter_axim_hw.h のコメント部分を引用する。

// ==============================================================
// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
// Version: 2014.1
// Copyright (C) 2014 Xilinx Inc. All rights reserved.
//
// ==============================================================

// LiteS
// 0x00 : Control signals
// bit 0 - ap_start (Read/Write/COH)
// bit 1 - ap_done (Read/COR)
// bit 2 - ap_idle (Read)
// bit 3 - ap_ready (Read)
// bit 7 - auto_restart (Read/Write)
// others - reserved
// 0x04 : Global Interrupt Enable Register
// bit 0 - Global Interrupt Enable (Read/Write)
// others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
// bit 0 - Channel 0 (ap_done)
// bit 1 - Channel 1 (ap_ready)
// others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
// bit 0 - Channel 0 (ap_done)
// bit 1 - Channel 1 (ap_ready)
// others - reserved
// 0x10 : Control signal of cam_addr
// bit 0 - cam_addr_ap_vld (Read/Write/COH)
// bit 1 - cam_addr_ap_ack (Read)
// others - reserved
// 0x14 : Data signal of cam_addr
// bit 31~0 - cam_addr[31:0] (Read/Write)
// 0x18 : Control signal of lap_addr
// bit 0 - lap_addr_ap_vld (Read/Write/SC)
// others - reserved
// 0x1c : Data signal of lap_addr
// bit 31~0 - lap_addr[31:0] (Read/Write)
// 0x20 : Data signal of ap_return
// bit 31~0 - ap_return[31:0] (Read)
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)


xlap_filter_axim.c にも以下の関数が追加されている。

void XLap_filter_axim_SetCam_addr(XLap_filter_axim *InstancePtr, u32 Data)
u32 XLap_filter_axim_GetCam_addr(XLap_filter_axim *InstancePtr)
void XLap_filter_axim_SetCam_addrVld(XLap_filter_axim *InstancePtr)
u32 XLap_filter_axim_GetCam_addrVld(XLap_filter_axim *InstancePtr)
u32 XLap_filter_axim_GetCam_addrAck(XLap_filter_axim *InstancePtr)
void XLap_filter_axim_SetLap_addrVld(XLap_filter_axim *InstancePtr)
u32 XLap_filter_axim_GetLap_addrVld(XLap_filter_axim *InstancePtr)


最後に、Vivado HLS 2014.1 で高位合成を行うためのCソースコードの laplacian_filter.c を貼っておく。

(追記) Vivado HLS で合成したラプラシアンフィルタのバグの原因は、古いバグありラプラシアンフィルタのCソースコードを使用したためでした。正しいラプラシアンフィルタのCソースコードについては、”Vivado HLS 2014.4で生成したラプラシアンフィルタIPをシミュレーション3(原因が分かった)”をご覧ください。
  1. 2015年03月01日 05:14 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0