FC2カウンター FPGAの部屋 Vivado HLSで作ったラプラシアン・フィルタIPを使ってみる3
FC2ブログ

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

FPGAの部屋

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

Vivado HLSで作ったラプラシアン・フィルタIPを使ってみる3

Vivado HLSで作ったラプラシアン・フィルタIPを使ってみる2”の続き。

まずは、XPSプロジェクトを少し修正した。カメラ・コントローラとビットマップ・ディスプレイ・コントローラのAXI4 Lite Slave の ChipScope AXI Monitor を削除して、ラプラシアン・フィルタIP に ChipScope AXI Monitor を入れた。
HLS_lap_filter_23_131008.png

これで、ISEに戻って、インプリメント、ビットストリームの生成を行って、SDKでBOOT.bin を再生成して、SDカードに入れてブートしてみたが、問題なくブートできた。

次に、ラプラシアン・フィルタIPを使用する様に、ラプラシアン・フィルタのソフトウェアを変更した (lap_filter_hls.c)。

次に進む前に、ラプラシアン・フィルタIPのハードウェア情報が記述されている xlaplacian_filter_hw.h を下に示す。

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

// BUS_A
// 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 x0y0
// bit 0 - x0y0_ap_vld (Read/Write/COH)
// bit 1 - x0y0_ap_ack (Read)
// others - reserved
// 0x14 : Data signal of x0y0
// bit 31~0 - x0y0[31:0] (Read/Write)
// 0x18 : Control signal of x1y0
// bit 0 - x1y0_ap_vld (Read/Write/SC)
// others - reserved
// 0x1c : Data signal of x1y0
// bit 31~0 - x1y0[31:0] (Read/Write)
// 0x20 : Control signal of x2y0
// bit 0 - x2y0_ap_vld (Read/Write/SC)
// others - reserved
// 0x24 : Data signal of x2y0
// bit 31~0 - x2y0[31:0] (Read/Write)
// 0x28 : Control signal of x0y1
// bit 0 - x0y1_ap_vld (Read/Write/SC)
// others - reserved
// 0x2c : Data signal of x0y1
// bit 31~0 - x0y1[31:0] (Read/Write)
// 0x30 : Control signal of x1y1
// bit 0 - x1y1_ap_vld (Read/Write/SC)
// others - reserved
// 0x34 : Data signal of x1y1
// bit 31~0 - x1y1[31:0] (Read/Write)
// 0x38 : Control signal of x2y1
// bit 0 - x2y1_ap_vld (Read/Write/SC)
// others - reserved
// 0x3c : Data signal of x2y1
// bit 31~0 - x2y1[31:0] (Read/Write)
// 0x40 : Control signal of x0y2
// bit 0 - x0y2_ap_vld (Read/Write/SC)
// others - reserved
// 0x44 : Data signal of x0y2
// bit 31~0 - x0y2[31:0] (Read/Write)
// 0x48 : Control signal of x1y2
// bit 0 - x1y2_ap_vld (Read/Write/SC)
// others - reserved
// 0x4c : Data signal of x1y2
// bit 31~0 - x1y2[31:0] (Read/Write)
// 0x50 : Control signal of x2y2
// bit 0 - x2y2_ap_vld (Read/Write/SC)
// others - reserved
// 0x54 : Data signal of x2y2
// bit 31~0 - x2y2[31:0] (Read/Write)
// 0x58 : 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)

#define XLAPLACIAN_FILTER_BUS_A_ADDR_AP_CTRL 0x00
#define XLAPLACIAN_FILTER_BUS_A_ADDR_GIE 0x04
#define XLAPLACIAN_FILTER_BUS_A_ADDR_IER 0x08
#define XLAPLACIAN_FILTER_BUS_A_ADDR_ISR 0x0c
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y0_CTRL 0x10
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y0_DATA 0x14
#define XLAPLACIAN_FILTER_BUS_A_BITS_X0Y0_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y0_CTRL 0x18
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y0_DATA 0x1c
#define XLAPLACIAN_FILTER_BUS_A_BITS_X1Y0_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y0_CTRL 0x20
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y0_DATA 0x24
#define XLAPLACIAN_FILTER_BUS_A_BITS_X2Y0_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y1_CTRL 0x28
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y1_DATA 0x2c
#define XLAPLACIAN_FILTER_BUS_A_BITS_X0Y1_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y1_CTRL 0x30
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y1_DATA 0x34
#define XLAPLACIAN_FILTER_BUS_A_BITS_X1Y1_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y1_CTRL 0x38
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y1_DATA 0x3c
#define XLAPLACIAN_FILTER_BUS_A_BITS_X2Y1_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y2_CTRL 0x40
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X0Y2_DATA 0x44
#define XLAPLACIAN_FILTER_BUS_A_BITS_X0Y2_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y2_CTRL 0x48
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X1Y2_DATA 0x4c
#define XLAPLACIAN_FILTER_BUS_A_BITS_X1Y2_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y2_CTRL 0x50
#define XLAPLACIAN_FILTER_BUS_A_ADDR_X2Y2_DATA 0x54
#define XLAPLACIAN_FILTER_BUS_A_BITS_X2Y2_DATA 32
#define XLAPLACIAN_FILTER_BUS_A_ADDR_AP_RETURN 0x58
#define XLAPLACIAN_FILTER_BUS_A_BITS_AP_RETURN 32

COH = Clear on Handshake の ap_start とx0y0_ap_vld ~ x2y2_ap_vld は振る舞いが違っていた。
laplacian_filter_BUS_A_if.v を見ると、ap_start は、ready が来ると、auto_restartの値をロードしていた。x0y0_ap_vld ~ x2y2_ap_vld は 1 にセットされた次のクロックで 0 にリセットされていた。

// ap_start
always @(posedge ACLK) begin
    if (~ARESETN)
        ap_start <= 1'b0;
    else if (w_hs && waddr == ADDR_AP_CTRL && WSTRB[0] && WDATA[0])
        ap_start <= 1'b1;
    else if (O_ap_ready)
        ap_start <= auto_restart; // clear on handshake/auto restart
end


// _x0y0_ap_vld
always @(posedge ACLK) begin
    if (~ARESETN)
        _x0y0_ap_vld <= 1'b0;
    else if (w_hs && waddr == ADDR_X0Y0_CTRL && WSTRB[0] && WDATA[0])
        _x0y0_ap_vld <= 1'b1;
    else if (I_x0y0_ap_ack)
        _x0y0_ap_vld <= 1'b0; // clear on handshake
end


それに応じてソフトウェアを修正して、動作させることが出来た。更に、”時間・時刻処理について(4)”を参照させて頂いて、gettimeofday()の使用に関するバグを修正した。

Vivado HLSで作製したラプラシアン・フィルタIPを使用したラプラシアン・フィルタ・ソフトウェアの実行時間は以下のようになった。

zynq> ./lap_filter_hls.elf
rmmap_cnt = 469
wmmap_cnt = 469
total time = 1.945109 sec
zynq> ./lap_filter_hls.elf
rmmap_cnt = 469
wmmap_cnt = 469
total time = 1.943671 sec
zynq> ./lap_filter_hls.elf
rmmap_cnt = 469
wmmap_cnt = 469
total time = 1.944409 sec
zynq> ./lap_filter_hls.elf
rmmap_cnt = 469
wmmap_cnt = 469
total time = 1.944262 sec
zynq> ./lap_filter_hls.elf
rmmap_cnt = 469
wmmap_cnt = 469
total time = 1.944169 sec


約1.94秒となった。完全にソフトウェアで実行した前回の 1.94 / 0.39 ≒ 5 倍になった。
予想通り遅くなってしまった。ラプラシアン・フィルタの9個の要素をレジスタに書いたり、ハンドシェークをするのに時間がかかってしまったのだと思う。これは後で、ChipScopeを使用して検証したい。
  1. 2013年10月08日 05:56 |
  2. Co-design
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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