FC2カウンター FPGAの部屋 Vivado HLS 2014.4 で合成したラプラシアンフィルタIPの高速化2(PIPELINEディレクティブ)
fc2ブログ

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

FPGAの部屋

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

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

コメント

頭で考えても、合成のパイプラインがどのように展開されるているのかわかりません。
この辺りは、実際に自分で試してみるしかないんでしょうね。

流れを見ていると、ループ文の内部を小さく、分岐を減らすと高速化できそうな(Z80とかV30の高速化テクニックw)

というわけで、こんなの作ってみました。
■■■■■■
■●■■■■
■■■■■■
↓↓↓↓↓↓
××▲▲▲ <- 予め9画素を加算しておく(sum_buf)
~~~

(●*8+●-▲) でフィルタ

// 予め2ライン分読み出しておく
for (a=0; a<1; a++){ // 2ライン分
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]); // カラーから白黒へ
}
}
for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){
lap_buf[b] = 0; // [0]と[HORIZONTAL_PIXEL_WIDTH]の両端をクリア
}
for (y=1; y<VERTICAL_PIXEL_WIDTH-1; y++){
// line_bufは4ライン分確保する
fl = (y-1) & 3;
sl = y;
tl = (y+1) & 3;
al = (y+2) & 3; // 加算バッファ
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 (x=0; b<HORIZONTAL_PIXEL_WIDTH; x++){
line_buf[tl][x] = conv_rgb2y(line_buf[tl][x]); // カラーから白黒へ
}
lsum1 = 0; // 先に9画素分の加算を行って[al][n]に保存
lsum2 = 0;
for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
lsum3 = line_buf[fl][x] + line_buf[sl][x] + line_buf[tl][x];
line_buf[al][x] = lsum1 + lsum2 + lsum3;
lsum1 = lsum2;
lsum2 = lsum3;
}
// 加算し過ぎている分を引いて重みづけ
for (x=1; x<HORIZONTAL_PIXEL_WIDTH-1; x++){
lap_fil_val = line_buf[sl][x]*8 + line_buf[sl][x] - line_buf[al][x+1];
if (lap_fil_val<0) lap_fil_val = 0;
else if (lap_fil_val>255) lap_fil_val = 255;
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));
}
// 最終ラインは0でnullした方が良い
  1. 2015/03/25(水) 11:08:35 |
  2. URL |
  3. おる #-
  4. [ 編集 ]

おるさん、こんにちは。

仙台に行っていたので、お返事が遅くなりました。コードまで書いて頂いて、ありがとうございました。後でやってみたいと思います。
  1. 2015/03/27(金) 04:18:11 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

コメントの投稿


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

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/3105-623a1288
この記事にトラックバックする(FC2ブログユーザー)