FC2カウンター FPGAの部屋 2015年02月18日
FC2ブログ

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

FPGAの部屋

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

Vivado and ZYBO Linux勉強会用のソースファイル

Vivado and ZYBO Linux勉強会の必要なソースファイルを貼っておきます。

まずは、LED4ip_v1_0_S_AXI_user_logic追加分.v です。


    reg     [3:0]     LED_Display_Counter;
    reg     [31:0]  LED_Interval_Counter;
    reg     slv_reg_wren_1d;

    // slv_reg_wren_1d generate
    always @(posedge S_AXI_ACLK) begin
        if (~S_AXI_ARESETN)
          slv_reg_wren_1d <= 1'b0;
        else
          slv_reg_wren_1d <= slv_reg_wren;
    end

    //// Conteres
    // LED_Display_Counter
    always @(posedge S_AXI_ACLK) begin : proc_LED_Display_Counter
       if(~S_AXI_ARESETN) begin
            LED_Display_Counter <= 4'd0;
       end else begin
              if (slv_reg_wren_1d && axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]==2'h1) // Counter Load
                  LED_Display_Counter <= slv_reg0[3:0]; // Error, slv_reg1[3:0]
               else if (slv_reg0[0]) begin // Enable
                if (LED_Interval_Counter == 32'd0)
                    LED_Display_Counter <= LED_Display_Counter + 4'd1;
            end
       end
    end
    assign LED4bit = LED_Display_Counter;

    // LED_Interval_Counter
    always @(posedge S_AXI_ACLK) begin : proc_LED_Interval_Counter
       if(~S_AXI_ARESETN) begin
            LED_Interval_Counter <= 32'd0;
       end else begin
            if (slv_reg0[0]) begin // Enable
                if (LED_Interval_Counter == 32'd0)
                    LED_Interval_Counter <= slv_reg3;
                else
                    LED_Interval_Counter <= LED_Interval_Counter - 32'd1;
            end else
                LED_Interval_Counter <= slv_reg3;
       end
    end


led4_axi_lite_slave.c です。

/*
 * led4_axi_lite_slave.c
 *
 *  Created on: 2013/12/16
 *      Author: Masaaki
 */

#include <stdio.h>
#include "xil_types.h"
#include "xparameters.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"

#define XPAR_LED4IP_0_S_AXI_BASEADDR 0x43C00000

extern char inbyte(void);

int main() {
    int inbyte_in;
    int val;

    while(1){
        print("********************** LED4 TEST Start ***********************\n\r");
        print("TeraTerm: Please Set Local Echo Mode.\n\r");
        print("Press '1' to show all registers\n\r");
        print("Press '2' to set LED4 Enable or Disable(Toggle, Command Register)\n\r");
        print("Press '3' to set LED Counter Load Register (4bits, Please input hexadecimal)\n\r");
        print("Press '4' to set LED Interval Register (32bits, Please input decimal)\n\r");
        print("Press '5' to exit\n\r");
        print("Selection : ");
        inbyte_in = inbyte();
        print(" \r\n");
        print(" \r\n");

        switch(inbyte_in) {
            case '1' : // Show all registers
                val = (int)Xil_In32((u32)XPAR_LED4IP_0_S_AXI_BASEADDR);
                printf("Command Register is %x\r\n", val);
                val = (int)Xil_In32((u32)(XPAR_LED4IP_0_S_AXI_BASEADDR+4));
                printf("LED Counter Load Register is %x\r\n", val);
                val = (int)Xil_In32((u32)(XPAR_LED4IP_0_S_AXI_BASEADDR+8));
                printf("LED Monitor Register is %x\r\n", val);
                val = (int)Xil_In32((u32)(XPAR_LED4IP_0_S_AXI_BASEADDR+0xc));
                printf("LED Interval Register is %d (decimal)\r\n", val);
                break;
            case '2' : // Set LED4 Enable or Disable(Toggle, Command Register)
                val = (int)Xil_In32((u32)XPAR_LED4IP_0_S_AXI_BASEADDR);
                if (val & 1) {
                    Xil_Out32((u32)XPAR_LED4IP_0_S_AXI_BASEADDR, (u32)0);
                    print("LED4 count is Disable\n\r");
                } else {
                    Xil_Out32((u32)XPAR_LED4IP_0_S_AXI_BASEADDR, (u32)1);
                    print("LED4 count is Enable\n\r");
                }
                break;
            case '3' : // Set LED Counter Load Register (4bits, Please input hexadecimal)
                print("Please input LED Counter Load Register value (hexadecimal)");
                scanf("%x", &val);
                Xil_Out32((u32)(XPAR_LED4IP_0_S_AXI_BASEADDR+4), (u32)val);
                print(" \r\n");
                break;
            case '4' : // Set LED Interval Register (32bits, Please input hexadecimal)
                print("Please input LED Interval Load Register value (decimal) ");
                scanf("%d", &val);
                Xil_Out32((u32)(XPAR_LED4IP_0_S_AXI_BASEADDR+0xc), (u32)val);
                print(" \r\n");
                break;
            case '5' : // exit
                print("exit\r\n");
                return 0;
        }
        print(" \r\n");
    }

}


led4_axi_lslave_linux.c です。

/*
 * led4_axi_lslave_linux.c
 *
 *  Created on: 2014/12/30
 *      Author: Masaaki
 */

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

char inbyte(void){
    char in_data;
    int ret_val;
    
    in_data = getc(stdin);
    if (in_data == '\n')
        in_data = getc(stdin);
    return(in_data);
};

int main() {
    int inbyte_in;
    int val;
    int fd;
    volatile unsigned int *led4_base;

    // LED4 (UIO0)
    fd = open("/dev/uio0", O_RDWR); // LED4
    if (fd < 1){
        fprintf(stderr, "/dev/uio0 open error\n");
        exit(-1);
    }
    led4_base = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (!led4_base){
        fprintf(stderr, "LED4 mmap error\n");
        exit(-1);
    }
    
    while(1){
        printf("********************** LED4 TEST Start ***********************\n");
        printf("TeraTerm: Please Set Local Echo Mode.\n");
        printf("Press '1' to show all registers\n");
        printf("Press '2' to set LED4 Enable or Disable(Toggle, Command Register)\n");
        printf("Press '3' to set LED Counter Load Register (4bits, Please input hexadecimal)\n");
        printf("Press '4' to set LED Interval Register (32bits, Please input decimal)\n");
        printf("Press '5' to exit\n");
        printf("Selection : ");
        inbyte_in = inbyte();
        printf(" \n");
        printf(" \n");

        switch(inbyte_in) {
            case '1' : // Show all registers
                val = led4_base[0];
                printf("Command Register is %x\n", val);
                val = led4_base[1];
                printf("LED Counter Load Register is %x\n", val);
                val = led4_base[2];
                printf("LED Monitor Register is %x\n", val);
                val = led4_base[3];
                printf("LED Interval Register is %d (decimal)\n", val);
                break;
            case '2' : // Set LED4 Enable or Disable(Toggle, Command Register)
                val = led4_base[0];
                if (val & 1) {
                    led4_base[0] = 0;
                    printf("LED4 count is Disable\n");
                } else {
                    led4_base[0] = 1;
                    printf("LED4 count is Enable\n");
                }
                break;
            case '3' : // Set LED Counter Load Register (4bits, Please input hexadecimal)
                printf("Please input LED Counter Load Register value (hexadecimal)");
                scanf("%x", &val);
                led4_base[1] = val;
                printf(" \n");
                break;
            case '4' : // Set LED Interval Register (32bits, Please input hexadecimal)
                printf("Please input LED Interval Load Register value (decimal) ");
                scanf("%d", &val);
                led4_base[3] = val;
                printf(" \n");
                break;
            case '5' : // exit
                printf("exit\n");
                return 0;
        }
        printf(" \n");
    }
    munmap((void *)led4_base, 0x1000);
}


opencv_pre_install.sh はこの辺りを参照下さい。
  1. 2015年02月18日 06:27 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

Vivado and ZYBO Linux勉強会を開催

2015年(平成27年)2月16日(月)と2月17日(火)で、Vivado and ZYBO Linux勉強会を開催しました。

2015/12/09:追記 ”Vivado and ZYBO Linux勉強会用のソースファイル”にCソースコードなどが貼ってありますので、ご利用下さい。

月曜日のハードウェア編が6人、火曜日のソフトウェア編が3人でした。ちょっと人数的には寂しかったですが、熱心にやって頂きました。
2日目の勉強会はUIOドライバを使ってLEDでカウンタを作るところまでだったので、半日くらいで十分そうでした。ネットがつながっていれば、OpenCVのサンプルのコンパイルまでだと1日あっても終わらないかもしれません?コンパイルに時間が掛かるので。。。
ノートパソコンを持ってきてもらって、VirutalBoxをインストールして、その上にUbuntu14.04LTSをインストールして、その上にLinux版のVivado 2014.4 WebPACK をインストールすることが必須なので、ハードルが高いです。
例えば、どこかで集まって勉強会をやろうと思っても、たぶんこのハードルの高さから無理だと思います。

去年の勉強会は演習にXilinxのZedBoaredのチュートリアルを使っていたので公開できなかったのですが、今回のVivado and ZYBO Linux勉強会の演習は完全にオリジナルです。公開できると思います。

そこで、事前準備のマニュアルはあえて出さず(自力で出来る人が対象ということです)に、VirutalBoxをインストールして、その上にUbuntu14.04LTSをインストールして、その上にLinux版のVivado 2014.4 WebPACK をインストールし、軽量ディスクトップ環境のLXDEをインストール出来る人を対象にVivado and ZYBO Linux勉強会資料をslideshareで公開しようと思います。Linux版のVivado 2014.4のインストールはARMのツールチェーンを簡単に入れられるので必須です。ARMのツールチェーンが無いと、ARMプロセッサ用のU-bootやLinuxカーネルをコンパイルすることができません。
:VirtualBoxの設定ですが、クリップボードの共有とドラッグアンドドロップは双方向にしてあります。CPU数は2、メモリは2GB程度、HDDは50GB程度与えています。なお、Oracle_VM_VirtualBox_Extension_Packをインストールして、USB2.0 (EHCI)コントローラーを有効化しています)

このチュートリアルをやれば、以下のことができます。
但し、ZYBOボードで演習を行いますので、演習を行うにはZYBOボードが必要です。

LED4 AXI LITE SLAVEプロジェクト
Vivado のLEDカウンタのAXI Lite Slave カスタムIPをウィザードで作って、ベアメタルアプリケーションで動作

ZYBO Linuxハンズオン資料
ZYBO 用 u-boot のビルド
SDK で Boot.bin を作製
ZYBO 用 Linux カーネルのビルド
デバイス・ツリーのコンパイル
Micro SD カードのフォーマット
Ubuntu の ROOT File System のコピー
FAT32 パーティションへ必要なファイルをコピー
ZYBO に SD カードを挿して Linux をブート
ユーザーでログイン
LED をカウントアップするソフトウェアを実行(UIO の実習)

勉強会場ではLANがつながっていないので、ここまでだが、ここからはZYBOをLANに接続して行う。

NTP のインストール
SSH のインストール
Xming で X ウインドウを Windows で操作
OpenCV インストール
OpenCV サンプル・プログラムのコンパイル+顔認識アプリの実行
ZYBO 用の Linaro Ubuntu のバージョンを 12.11 から 14.04 LTS にアップグレード(おまけ)
ARMhf の Root File System を入れる(おまけ)

slideshare のVivado and ZYBO Linux勉強資料2 で公開しました。なお、ダウンロードはできなくなっています。どのくらいの方に見ていただいたのか?知りたいのとバグが直ぐに直せるからです。

この資料を作るにあたっては、たくさんのWebサイトを参照させて頂きました。また、たくさんの方にアドバイスを頂きました。本当にありがとうございました。問題がありましたらお知らせ下さい。
資料を作るにあたっては3週間程かかりました。まだ、どうしてこれをやるの?というところが書けてません。私もよくわからないところがありますので、知っている方はコメント欄などでお知らせ下さい。またご意見やバグ情報などをコメントとして教えて頂けると嬉しいです。

最後に、教育機関の方でこの勉強会資料を使って勉強会を開催したいという方に、WordやPowerPointの文章やコードのソースをほしいという方は個別対応でお送りしますので、FPGAの部屋のメールアドレスまでお知らせ下さい。

この勉強会資料はFPGAの部屋のブログに書いたことをまとめたものです。演習以外はブログを見ても同じことができますが、ブログでは試行錯誤しているし、他の話題も混ざっているので、書いた私以外は追うのが難しいと思います。それを、見やすく誰がやっても?できるように書き改めたのが、この勉強会資料です。資料を作るにあたっては、もう一度やり直して確認しているので、現時点では確実にできると思います。

Vivado and ZYBO Linux勉強会用のソースファイルを”Vivado and ZYBO Linux勉強会用のソースファイル”に貼っておきました。

2015/02/21 追記: slideshare で Vivado and ZYBO Linux勉強資料3 を公開しました。こちらは、PowerPoint がスライドにしてあるので、Vivado and ZYBO Linux勉強資料2 よりも見やすいと思います。

最後に slideshare だとコピペが出来ないと思うので、おまけとして長いコマンドをここに貼っておきます。

長いコマンドのコピー・アンド・ペースト用ファイル

1. ZYBO用u-bootのビルド
git clone -b master-next https://github.com/DigilentInc/u-boot-Digilent-Dev.git
make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_zybo_config
make CROSS_COMPILE=arm-xilinx-linux-gnueabi-
cp u-boot u-boot.elf

2. SDKでBoot.bin を作製

3. ZYBO用Linuxカーネルのビルド
git clone -b master-next https://github.com/DigilentInc/Linux-Digilent-Dev.git
make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- xilinx_zynq_defconfig
make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi-
PATH=$PATH:../u-boot-Digilent-Dev/tools/
make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- UIMAGE_LOADADDR=0x8000 uImage

4. デバイス・ツリーのコンパイル
cp arch/arm/boot/dts/zynq-zybo.dts
gedit zynq-zybo.dts

bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1 uio_pdrv_genirq.of_id=generic-uio";
operating-points = <650000 1000000>;
led4_axi_lite_slave@43c00000 {
compatible = "generic-uio";
reg = < 0x43c00000 0x10000 >;
};
scripts/dtc/dtc -I dts -O dtb -o devicetree.dtb zynq-zybo.dts

5. Micro SDカードのフォーマット(必要な人のみ)

6. Micro SDカードにパーティションを作る
sudo fdisk /dev/sdb
sudo mkfs.msdos -n ZYBO_BOOT /dev/sdb1
sudo mkfs.ext4 -L ROOT_FS /dev/sdb2

7. UbuntuのROOT File SystemをMicro SDカードへコピー
wget https://releases.linaro.org/archive/12.11/ubuntu/precise-images/ubuntu-desktop/linaro-precise-ubuntu-desktop-20121124-560.tar.gz
sudo tar --strip-components=3 -C /media/ono/ROOT_FS -xzpf linaro-precise-ubuntu-desktop-20121124-560.tar.gz binary/boot/filesystem.dir

8. FAT32パーティションへ必要なファイルをコピー
 uEnv.txt の入力
uenvcmd=fatload mmc 0 0x03000000 uImage && fatload mmc 0 0x02A00000 devicetree.dtb && bootm 0x03000000 - 0x02A00000

9. ZYBOにSDカードを入れてLinuxをブート

10. ユーザーでログイン

11. LEDをカウントアップするソフトウェアを実行(UIOの実習)
vi led4_axi_lslave_linux.c
cc -o led4_axi_lslave_linux led4_axi_lslave_linux.c
./led4_axi_lsalve_linux
ls -l /dev/uio*
sudo chmod 666 /dev/uio0
./led4_axi_lsalve_linux

12. NTPのインストール
apt-get update
apt-get update
apt-get install ntp
ln -sf /usr/share/zoneinfo/Japan /etc/localtime
sudo vi /etc/ntp.conf

server -4 ntp.nict.jp minpoll 4 maxpoll 10

/etc/init.d/ntp restart

13. SSHのインストール
apt-get install ssh
vi /etc/ssh/sshd_config
/etc/init.d/ssh restart

14. XmingでXウインドウをWindowsで操作

15. OpenCVインストール
sudo apt-get install cmake
wget ftp://ftp.jp.netbsd.org/pub/pkgsrc/distfiles/opencv-2.4.6.1.tar.gz
tar xvzf opencv-2.4.6.1.tar.gz
cd opencv-2.4.6.1
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

16. OpenCVサンプル・プログラムのコンパイル+顔認識アプリの実行
cd ../samples/c
./build_all.sh
./facedetect --cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_eye.xml" --scale=1.3 lena.jpg
  1. 2015年02月18日 04:25 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:8