FC2カウンター FPGAの部屋 2017年10月20日
FC2ブログ

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

FPGAの部屋

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

2017年度Zynq+Vivado HLS勉強会概要

今度、筑波大学でやる予定の「2017年度Zynq+Vivado HLS勉強会概要」です。

2017年度Zynq+Vivado HLS勉強会概要

2017年度にZynqとVivado HLSの使い方を勉強する勉強会を開きます。回数は半日7回とします。なお資料は
(とりあえず秘密です。。。)
から見ることができます。このURLや資料はお友達やWebに拡散しないようにお願いします。
Windows版のVivado 2017.3(必ずVivado 2017.3をインストールしてください。他のバージョンでは結果が異なります)をインストールし、ZYBOのボードファイルをインストールしてください。ZYBOのボードファイルのインストール方法については、FPGAの部屋のブログの“ZYBO Z7-20 のボードファイルをVivado 2017.2 にインストールする”をご覧ください。この操作を行うと、ZYBOのボードファイルもインストールすることができます。ただし、Vivado 2017.3にインストールしてください。
http://marsee101.blog19.fc2.com/blog-entry-3926.html

第7回ではLinuxを使用してデバイスツリー・ソースをコンパイルします。よって、VirtualBoxかVMwareでUbuntu 16.04をインストールしてください。その際に
sudo apt-get install device-tree-compiler
でデバイスツリー・コンパイラをインストールしてください。

1. 第1回目(2時間程度)No1のフォルダに資料があります。実習はありません
(ア) Zynqの概要
(イ) AXIインターフェース

2. 第2回目(半日程度)資料-No2フォルダ
(ア) Vivado HLS勉強会1(基礎編)(ZYBO実機を使用します)
① Vivado HLSの基本的に使い方を学習します。簡単な乗算回路のIPを作ります。組み合わせ回路を作ります。
② Vivado HLSで作ったIPを使用して、VivadoでIPIを使って乗算回路にしてZYBOで実際に動作させます。

3. 第3回目(半日程度)資料-No3フォルダ
(ア) Vivado HLS勉強会2(レジスタの挿入とPIPELINEディテクティブ)
① 第2回目で作成した乗算回路にレジスタを挿入します。
② パイプライン処理の方法を学習します。
③ Vivado HLSでディスプレイ・コントローラを作ってみます。

4. 第4回(半日程度)資料-No4フォルダ(ZYBO実機を使用します)
(ア) Vivado HLS勉強会3(AXI4 Lite Slave)
① 乗算回路をAXI4 Lite Slaveインターフェース対応にします。
② Vivado HLSで作ったIPを使用して、VivadoでIPIを使って乗算回路にしてZYBOで実際に動作させます。

5. 第5回(半日程度)資料-No5フォルダ
(ア) Vivado HLS勉強会4(AXI4 Master)
① ラプラシアンフィルタを題材にAXI4 Masterの実装方法を学習します。
② ディテクティブやCの構造による性能の違いを学習します。

6. 第6回(半日程度)資料-No6フォルダ
(ア) Vivado HLS勉強会5(AXI4 Stream)+任意精度型固定小数点データ型+HLSビデオライブラリ
① 第5回目のラプラシアンフィルタをAXI4 Streamで実装します。AXI4 Streamが一番性能が出やすくお得です。
② 任意精度型固定小数点データ型+HLSビデオライブラリについて説明します。資料が作れて実習できれば良いのですが、講義だけになってしまうかも?です。

7. 第7回(半日程度)資料-No7フォルダ(ZYBO実機を使用します)
(ア) Vivado HLSのIPをLinuxから使用する(資料は未作成です)
① 第4回目で作成した乗算回路をLinuxから使用する方法を学習します。
② SDKでBOOT.binを作成し、devicetreeやuImageとともにSDカードに書き込みます。
③ SDカードの第2パーティションには私のUbuntu 14.04のRootFSを入れておいて、ZYBO上でUbuntuを起動します。
④ Vivado HLSのドライバを使って乗算回路IPをソフトで制御するためにMakefileを作ってコンパイル実行します。
⑤ LinuxのCMA領域を使用するudmabufについて学習します。


参加者の方には後で、PDFファイルを送ります。
  1. 2017年10月20日 10:12 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

ZYBO Z7-20上のUbuntu 14.04でカメラ画像にガボール・フィルタを動作させる

ZYBO Z7-20上のUbuntu 14.04でカメラ画像をBMPファイルに変換する”の続き。

ZYBO Z7-20上のUbuntu 14.04でカメラ画像からBMPファイルを生成する cam_capture_bmp でBMP ファイルが生成できることが分かった。今回は、ZYBO Z7-20上のUbuntu 14.04 でガボール・フィルタを動作させてみようと思う。

gabor_fil_left_dmaw.c と gabor_fil_right_dmaw.c のUIO をオープンする部分を変更した。
ZYBO_Z7_147_171017.png

そして、gabor_fil_left_dmaw.c と gabor_fil_right_dmaw.c をコンパイルしたら通った。
gabor_fil_left_dmaw と gabor_fil_right_dmaw を起動した。
ZYBO_Z7_148_171017.png

元画像はこれで、
ZYBO_Z7_149_171017.jpg

左白線検出用ガボール・フィルタの出力を示す(gabor_fil_left_dmaw)。
ZYBO_Z7_150_171017.jpg

右白線検出用ガボール・フィルタの出力を示す(gabor_fil_right_dmaw)。
ZYBO_Z7_151_171017.jpg

gabor_fil_left_dmaw.c を貼っておく。

//
// gabor_fil_left_dmaw.c
// Created on: 2016/09/28
//      Author: marsee
//
// Refered to http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2014_4/ug902-vivado-high-level-synthesis.pdf
//
// 2017/10/17 : for ZYBO Z7-20
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>

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

#define HORIZONTAL_PIXEL    800
#define ALL_CHAR_OF_1LINE   (HORIZONTAL_PIXEL/8)
#define VERTICAL_PIXEL      600
#define ALL_CHAR_OF_ROW     (VERTICAL_PIXEL/8)
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXEL*VERTICAL_PIXEL*4)
#define ALL_DISP_CHARACTOR  (HORIZONTAL_PIXEL*VERTICAL_PIXEL)

int main(){
    int fd1, fd2, fd3, fd6, fd7, fd9, fd10;
    volatile unsigned *axis_switch_0, *axis_switch_1;
    volatile unsigned *gabor_filter_lh_0;
    volatile unsigned *dmaw4gabor_0;
    volatile unsigned *bmdc_axi_lites0;
    volatile unsigned *frame_buffer_bmdc;
    unsigned char  attr[1024];
    unsigned long  phys_addr;

    // axis_switch_0 (UIO2)
    fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0 interface AXI4 Lite Slave
    if (fd2 < 1){
        fprintf(stderr, "/dev/uio2 (axis_switch_0) open error\n");
        exit(-1);
    }
    axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
    if (!axis_switch_0){
        fprintf(stderr, "axis_switch_0 mmap error\n");
        exit(-1);
    }
    
    // axis_switch_1 (UIO3)
    fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1 interface AXI4 Lite Slave
    if (fd3 < 1){
        fprintf(stderr, "/dev/uio3 (axis_switch_1) open error\n");
        exit(-1);
    }
    axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
    if (!axis_switch_1){
        fprintf(stderr, "axis_switch_1 mmap error\n");
        exit(-1);
    }
    
    // gabor_filter_lh_0 (UIO7)
    fd7 = open("/dev/uio7", O_RDWR); // gabor_filter_lh_0 interface AXI4 Lite Slave
    if (fd7 < 1){
        fprintf(stderr, "/dev/uio7 (gabor_filter_lh_0) open error\n");
        exit(-1);
    }
    gabor_filter_lh_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
    if (!gabor_filter_lh_0){
        fprintf(stderr, "lap_filter_axis_0 mmap error\n");
        exit(-1);
    }
    
    // dmaw4gabor_0 (UIO1)
    fd1 = open("/dev/uio1", O_RDWR); // dmaw4gabor_0 interface AXI4 Lite Slave
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 (dmaw4gabor_0) open error\n");
        exit(-1);
    }
    dmaw4gabor_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!dmaw4gabor_0){
        fprintf(stderr, "dmaw4gabor_0 mmap error\n");
        exit(-1);
    }
    
    // Bitmap Display Controller 0 AXI4 Lite Slave (UIO6)
    fd6 = open("/dev/uio6", O_RDWR); // bitmap_display_controller 0 axi4 lite
    if (fd6 < 1){
        fprintf(stderr, "/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open error\n");
        exit(-1);
    }
    bmdc_axi_lites0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
    if (!bmdc_axi_lites0){
        fprintf(stderr, "bmdc_axi_lites0 mmap error\n");
        exit(-1);
    }
    
    // udmabuf0
    fd9 = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled. 
    if (fd9 == -1){
        fprintf(stderr, "/dev/udmabuf0 open error\n");
        exit(-1);
    }
    frame_buffer_bmdc = (volatile unsigned *)mmap(NULL, 5760000, PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
    if (!frame_buffer_bmdc){
        fprintf(stderr, "frame_buffer_bmdc mmap error\n");
        exit(-1);
    }

    // phys_addr of udmabuf0
    fd10 = open("/sys/devices/virtual/udmabuf/udmabuf0/phys_addr", O_RDONLY);
    if (fd10 == -1){
        fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/phys_addr open error\n");
        exit(-1);
    }
    read(fd10, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd10);
    printf("phys_addr = %x\n", (int)phys_addr);
    
    // axis_switch_1, 1to2 ,Select M01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_1[16] = 0x80000000// 0x40 = 0x80000000; disable
    axis_switch_1[17] = 0x80000000// 0x44 = 0x80000000; disable
    axis_switch_1[18] = 0// 0x48 = 0;
    axis_switch_1[0] = 0x2// 0x0 = 2; Commit registers
    
    // gabor filter AXIS Start
    gabor_filter_lh_0[0] = 0x01// Start bit set
    gabor_filter_lh_0[0] = 0x80// Auto Restart bit set
    
    // axis_switch_0, 2to1, Select S01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_0[16] = 0x2// 0x40 = 0x2;
    axis_switch_0[0] = 0x2// 0x0 = 2; Commit registers
    
    // DMA4Gabor frame_buffer1 setting
    dmaw4gabor_0[8] = (int)phys_addr + ALL_DISP_ADDRESS; // Data signal of frame_buffer1

    // bitmap display controller settings
    bmdc_axi_lites0[0] = (int)phys_addr; // Bitmap Display Controller 0 start
  
    munmap((void *)axis_switch_0, 0x10000);
    munmap((void *)axis_switch_1, 0x10000);
    munmap((void *)gabor_filter_lh_0, 0x10000);
    munmap((void *)dmaw4gabor_0, 0x10000);
    munmap((void *)bmdc_axi_lites0, 0x10000);
    munmap((void *)frame_buffer_bmdc, 576000);
    
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd6);
    close(fd7);
    close(fd9);
    
    return(0);
}


gabor_fil_right_dmaw.c はgabor_fil_left_dmaw.c とは、141行目だけが異なっている。
gabor_fil_left_dmaw.c は

bmdc_axi_lites0[0] = (int)phys_addr; // Bitmap Display Controller 0 start

だが、gabor_fil_right_dmaw.c は

bmdc_axi_lites0[0] = (int)phys_addr + ALL_DISP_ADDRESS; // Bitmap Display Controller 0 start

となっている。これは、ガボール・フィルタの左白線検出用パラメータを使用して変換した画像の次のアドレスに右白線検出用パラメータを使用して変換した画像を格納しているからだ。
  1. 2017年10月20日 04:56 |
  2. ZYBO Z7
  3. | トラックバック:0
  4. | コメント:0