Ubuntu Weekly Recipe

第475回 廉価なFPGA開発ボード「Zybo」をUbuntuからプログラムする

この記事を読むのに必要な時間:およそ 11 分

みなさん,FPGA使ってますか?

スマートフォンの普及によって,ARMデバイスは本当に身近な存在になりました。近頃のスマートフォンは一昔前では考えられないほどいいCPU/SoCを搭載しているため,Twitterから3Dゲームに至るまで,手のひらにおさまる大抵の用途において十分に真価を発揮します。ところが「ひたすら行列計算を行いたい」⁠画像認識や機械学習をより低消費電力で回したい」といった,ちょっと特殊なシチュエーションになると,スマホに搭載されているARM CPU/SoCでは遠からず「性能の限界」がやってきます。この限界を突破するために,FPGAに手を出すのは生き物のサガと言っても差し支えないでしょう。すみません,ちょっと言い過ぎました。

今回はそんな「ちょっと特殊なシチュエーション」に憧れる人に向けて,廉価なFPGA開発ボードの使い方を紹介します。

Digilent製FPGA開発ボード「Zybo」

Digilent製FPGA開発ボード「Zybo」は2万円強で買える初心者向けのFPGA開発ボードです※1)⁠Zyboにはメインプロセッサとして「謎の半導体メーカー」Xilinx社のZynq-7000シリーズが載っています。Zynqはいわゆる「APSoC」とか「SoC FPGA」ともいわれるカテゴリのチップで,Atrix-7相当のFPGAとARMのCPUコアであるCortex-A9がひとつにまとめられたSoCです。これにより一般的なARMボードのように使いながら,周辺機器からの信号をFPGAに処理させるといった使い方が可能になります。

※1
FPGA(Field Programable Gate Array)とは「配線は現場で起きているんだ!」系のICです。ロジックセルと呼ばれる回路を何度も配線しなおすことが可能なので,特定の機能をもたせた回路を簡単に作ることができます。論理回路のプロトタイピングやASICではペイしない程度の少量生産の基板で使われているようです。
  • CPU:650MHz デュアルコア Cortex-A9
  • ロジックスライス:4400個(1個あたり6入力LUTと8個のフリップフロップのロジックセルが4つ)
  • ブロックRAM:240KB
  • メモリ:DDR3 512MiB
  • ストレージ:128Mb QSPI Flash ROM,microSDカードコントローラー
  • Ethernet:1Gbit/100Mbit/10Mbit
  • オーディオ:ヘッドフォン出力,マイクロフォン・ライン入力ジャック
  • インターフェース:HDMI(sink/source)⁠VGA,USB 2.0(OTG)⁠UART,JTAG
  • その他:スイッチ4個,ボタン6個,LED5個

廉価版のFPGAがベースになっているためロジックスライス数は4400個と少なめです。⁠ぼくのかんがえたさいきょうのロジックかいろ」をプログラミングしたいのであれば,より高機能・高価格のFPGAが必要になるかもしれません。あくまでFPGAの学習用だと割りきりましょう。

Zyboには,microUSBのJTAG・UART共用端子がついています。つまり「お高い」ダウンロードケーブルを購入しなくても,周囲に転がっているUSBケーブルを使えばFPGAへの書き込みができるというわけです。Zybo以外に用意すべきものは,次のとおりです。

  • PCとZyboをつなぐためのUSBケーブル(Zybo側がmicroUSB端子)
  • HDMI・VGAケーブル(ディスプレイを使う場合のみ)
  • microSDカード(microSDカードから起動する場合)
  • 5V 2.5Aの内径2.1mm・center-positiveなプラグのついたACアダプター(USBから給電しない場合)

USBケーブル以外は「あると便利」程度であり,とりあえず動かすだけであれば不要です。電源はUSBからも給電できますし,JTAGを使ったりSPI Flashに書き込むことでmicroSDがなくてもシステムを起動できます。

ちなみにZybo自体は比較的古い製品です。Arty Z7PYNQ-Z1などおなじZynq-7000ベースの新しいボードも出ていますので,今ならそちらを買う手もあるでしょう。原則として,この記事に書かれている内容は他のZynq系ボードでも適用可能です。

電源投入のテスト

さっそく電源をいれてみましょう。QSPI Flash ROM※2には最初から「ちゃんと動く」データが書き込まれているため,何もプログラムしていなくても動くようになっています。

※2
QSPI(Quad SPI)SPI(Serial Peripheral Interface)の2本ある全二重のデータ線を4本に増やし,半二重方式でパラレルにデータを送るインターフェースです。Zyboに搭載されているCypless製のFlashデバイスS25FL129Pは,Quadモードに設定することでHoldピンやWriteProtectピンをデータピンに流用できる仕組みになっているようです。つまり「パラレル通信するSPIデバイス」になります。

まずは電源ソースを設定するJ15ピンを,USBとVU5V0がショートするようにつなぎます。ACアダプターを使う場合は,USBではなくWALLをショートさせます。ちなみにVU5V0とGNDを利用してバッテリーを接続することも可能です。アイドル状態で5V0.2A消費とのことなので,かんたんなものを動かすうちはUSB給電で十分ですが,本格的に使う場合はACアダプターを用意しましょう。

図1 USB給電に変更した状態

画像

次にJP5ピンを使ってブートデバイスを変更します。シルク印刷にあわせて真ん中の2ピンをショートさせれば,QSPI Flash ROMからのブートになります。

図2 SPIブートに変更した状態

画像

「PROG UART」と書かれたmicroUSB端子にUSBケーブルを接続し,SW4のスイッチを「ON」に変更しましょう。PGOOD LED(LD11)が赤点灯し,DONE LED(LD10)が緑点灯したら起動完了です。HDMIケーブルをディスプレイにつなぐと,カラフルなテストパターンが表示されます。

そのままPCからシリアルコンソールに接続してみましょう。PCにUSBケーブルを接続し,電源を入れたタイミングで2つのシリアルコンソールデバイスが作られているはずです。以下で言うところの,ftdi_sioドライバーが使われているデバイスがそれにあたります。

$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/8p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
    |__ Port 3: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 6: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 6: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 8: Dev 7, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 480M
    |__ Port 8: Dev 7, If 1, Class=Vendor Specific Class, Driver=ftdi_sio, 480M
    |__ Port 9: Dev 4, If 0, Class=Vendor Specific Class, Driver=pl2303, 12M

UART/JTAG用のICとしてFTDIのデュアルチャンネルUART/FIFO ICであるFT2232Hが搭載されています。他にUSB接続のUARTデバイスを繋いでいない環境であれば,おそらく/dev/ttyUSB0/dev/ttyUSB1が作られていることでしょう。前者がJTAG経由のプログラミング用で,後者がUART用のデバイスです。udevadmコマンドでプロパティを見れば,⁠Digilent」と書かれているはずです。

$ udevadm info --name=/dev/ttyUSB0 | grep Digilent
S: serial/by-id/usb-Digilent_Digilent_Adept_USB_Device_210279A42C65-if00-port0
E: DEVLINKS=/dev/serial/by-path/pci-0000:00:14.0-usb-0:8:1.0-port0 /dev/serial/by-id/usb-Digilent_Digilent_Adept_USB_Device_210279A42C65-if00-port0
E: ID_MODEL=Digilent_Adept_USB_Device
E: ID_MODEL_ENC=Digilent\x20Adept\x20USB\x20Device
E: ID_SERIAL=Digilent_Digilent_Adept_USB_Device_210279A42C65
E: ID_VENDOR=Digilent
E: ID_VENDOR_ENC=Digilent

screenコマンドをインストールしていれば,次のようにシリアルコンソールを開くことができます。

$ sudo screen /dev/ttyUSB1 115200
zynq> uname -a
Linux (none) 3.10.0-xilinx-14974-gb286654-dirty #12 SMP PREEMPT Tue Nov 5 21:58:53 PST 2013 armv7l GNU/Linux
zynq> cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 1299.25
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0

processor       : 1
model name      : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 1299.25
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0

Hardware        : Xilinx Zynq Platform
Revision        : 0000
Serial          : 0000000000000000

この状態でボード上の「PS-SRST」ボタンを押すと,システムがリセットします。その結果,次のようにU-Bootとカーネルの起動ログが表示されます※3)⁠

※3
UARTデバイスはメインスイッチの電源が入っていないと,PC側から認識されません。U-Bootのログを表示したい場合は,電源を入れてコンソールを開いたあとにリセットボタンを押してください。
U-Boot 2013.04-dirty (Nov 14 2013 - 11:56:14)

Memory: ECC disabled
DRAM:  512 MiB
WARNING: Caches not enabled
MMC:   zynq_sdhci: 0
SF: Detected S25FL129P_64K with page size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   Gem.e000b000
Hit any key to stop autoboot:  0
Copying Linux from QSPI flash to RAM...
SF: Detected S25FL129P_64K with page size 64 KiB, total 16 MiB
## Booting kernel from Legacy Image at 03000000 ...
   Image Name:   Linux-3.10.0-xilinx-14974-gb2866
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3126272 Bytes = 3 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 02000000 ...
   Image Name:
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    3692769 Bytes = 3.5 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 02a00000
   Booting using the fdt blob at 0x02a00000
   Loading Kernel Image ... OK
OK
   Loading Ramdisk to 1f7cf000, end 1fb548e1 ... OK
   Loading Device Tree to 1f7c9000, end 1f7ce1e9 ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.10.0-xilinx-14974-gb286654-dirty (Sham@TheFootball) (gcc version 4.6.1 (Sourcery CodeBench Lite 2011.09-50) ) #12 SMP PREEMPT Tue Nov 5 21:58:53 PST 2013
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: Xilinx Zynq Platform, model: Xilinx Zynq Platform
(中略)
EXT2-fs (ram0): warning: mounting unchecked fs, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem) on device 1:0.
devtmpfs: mounted
Freeing unused kernel memory: 172K (c0552000 - c057d000)
Starting rcS...
++ Mounting filesystem
++ Setting up mdev
++ Configure static IP 192.168.1.10
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting dropbear (ssh) daemon
++ Exporting LEDs & SWs
rcS Complete
zynq>

上記ログにもあるようにルートファイルシステム(ramdisk)は3MiB程度になっています。ほぼBusyBoxだけで構成されているものの,ちゃんとしたLinuxシステムです。ちなみにpsコマンドを実行すると,起動ログにもあるようにtelnetdやHTTPサーバー,ftpdにSSHサーバー(dropbear)が動いていることもわかります。

  525 root       0:00 telnetd -l /bin/sh
  531 root       0:00 httpd -h /var/www
  532 root       0:00 tcpsvd 0:21 ftpd ftpd -w /
  538 root       0:00 dropbear

個々のパーツやその機能については,Zyboのリファレンスマニュアル(PDF)を参照してください。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入