Ultra96 向け Debian GNU/Linux (v2018.2版) の構築(Sample FPGA Design編)

## はじめに

Ultra96 に Debian GNU/Linux (v2018.2版) を構築する方法について、具体的な方法をいくつかに分けて説明します。

 * [Introduction](https://qiita.com/ikwzm/items/5ae07792143d8018bfea)
 * [Boot Loader](https://qiita.com/ikwzm/items/9c78e83298906447fe5d)
   - __Sample FPGA Design(この記事)__
   - [FSBL   (First Stage Boot Loader)](https://qiita.com/ikwzm/items/fe9d6abda60660fc2f87)
   - [PMUFW  (Platform Manager Unit Firmware)](https://qiita.com/ikwzm/items/00024adf956696dd51c6)
   - [BL31   (ARM Trusted Firmware Boot Loader state 3-1)](https://qiita.com/ikwzm/items/3c0d735cd3a605d269f3)
   - [U-Boot](https://qiita.com/ikwzm/items/11853d8cfdaf373beaef)
   - [BOOT.BIN](https://qiita.com/ikwzm/items/af4420edd262e14feef9)
 * [Linux Kernel](https://qiita.com/ikwzm/items/02af5ac78a558c910e84)
 * [Debian9 Root File System](https://qiita.com/ikwzm/items/be06b07e26cbf05fec2b)

この記事では、ZynqMP の Boot Loader で使うための Sample FPGA Design の構築について説明をします。

## Sample FPGA Design を構築する目的

Vivado SDK では FSBL(First Stage Boot Loader) および PMUFW(Platform Manager Unit Firmware) をビルドするのにハードウェア情報が必要になります。また、Ultra96 では Bluetooth を使うために PS の UART0 の CTS と RTS を PL 側の I/O ピンに接続する必要があります。そのため、ここでサンプルとなるデザインを構築します。

注意: 2018年10月26日現在、Bluetooth と GPIO の動作確認が済んでいません。このサンプルデザインを使って U-Boot と Linux が起動出来ることだけ確認しています。ご了承ください。

## Sample FPGA Design の構成

Bluetooth を使うために PS の UART0 の CTS と RTS を PL 側の I/O ピンに接続しています。ついでに Ultra96 の GPIO も実装してしまいます。

![Fig.1 Ultra96 Sample Design](https://qiita-image-store.s3.amazonaws.com/0/24981/796cac5a-a133-327c-96f3-29966816867b.png "Fig.1 Ultra96 Sample Design")

Fig.1 Ultra96 Sample Design

## 必要な環境

 * Vivado 2018.2
 * Vivado SDK 2018.2

また、Ultra96 用のボード設定ファイルが必要です。Vivado にもとから入っている Ultra96 のボード設定ファイルは問題があるようなので Avnet が github で提供しているボードファイルを使います。次のように Avnet の github からダウンロードして Vivado がインストールされたディレクトリの data/boads/board_files にコピーしてください。

```console
shell$ git clone git://github.com/Avnet/bdf
shell$ sudo cp -R bdf/* /opt/xilinx/Vivado/2018.2/data/boards/board_files/
```

なお、github/Avnet/bdf には現在 ultra96v1/1.2 と ultra96v2/1.0 がリリースされていますが、私がこのプロジェクトを構築した時は ultra96v1/1.2 しか無かったので、このプロジェクトでは ultra96v1/1.2 を使っています。

## Sample FPGA Design の構築

次の URL から git clone でリポジトリをダウンロードして v2018.2.1 をチェックアウトします。

 * [https://github.com/ikwzm/ZynqMP-FPGA-Linux](https://github.com/ikwzm/ZynqMP-FPGA-Linux)

```console
shell$ git clone git://github.com/ikwzm/ZynqMP-FPGA-Linux
shell$ cd ZynqMP-FPGA-Linux
shell$ git checkout v2018.2.1
```

ここでは Vivado の XST(Xilinx Software Command Line Tool) を使って構築する方法を示します。GUI を使って手で入力するのは面倒なので Tcl スクリプトファイルを用意しています。

 * target/Ultra96/build-v2018.2/
   - fpga/
     + create_project.tcl
     + design_1_bd.tcl
     + implementation.tcl
     + export_hardware.tcl
     + design_1_pin.xdc

### Project を作る

create_projet.tcl を Vivado で実行してプロジェクトを作ります。

```console
vivado% cd target/Ultra96/build-v2018.2/fpga/
vivado% vivado -mode batch -source create_project.tcl
```

この FPGA デザインでは、次の図のように I/O Configuration / Low Speed / I/O Peripherals / UART / UART0 を MODEM モードにして CTS と RTS を PL 側に出しています。

![Fig.2 ZynqMP UART0 Setting](https://qiita-image-store.s3.amazonaws.com/0/24981/f9b787ed-659f-0089-78db-67d33303797c.png "Fig.2 ZynqMP UART0 Setting")

Fig.2 ZynqMP UART0 Setting

design_1_pin.xdc ファイルで PL 側の I/O ポートに接続するピン番号を指定しています。

```tcl:design_1_pin.xdc
## UART0
set_property -dict { PACKAGE_PIN B7   IOSTANDARD LVCMOS18 } [get_ports { UART0_CTS }]; 
set_property -dict { PACKAGE_PIN B5   IOSTANDARD LVCMOS18 } [get_ports { UART0_RTS }]; 

## GPIO
set_property -dict { PACKAGE_PIN D7   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[0]  }]; 
set_property -dict { PACKAGE_PIN F8   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[1]  }]; 
set_property -dict { PACKAGE_PIN F7   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[2]  }]; 
set_property -dict { PACKAGE_PIN G7   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[3]  }]; 
set_property -dict { PACKAGE_PIN F6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[4]  }]; 
set_property -dict { PACKAGE_PIN G5   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[5]  }]; 
set_property -dict { PACKAGE_PIN A6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[6]  }]; 
set_property -dict { PACKAGE_PIN A7   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[7]  }]; 
set_property -dict { PACKAGE_PIN G6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[8]  }]; 
set_property -dict { PACKAGE_PIN E6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[9]  }]; 
set_property -dict { PACKAGE_PIN E5   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[10] }]; 
set_property -dict { PACKAGE_PIN D6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[11] }]; 
set_property -dict { PACKAGE_PIN D5   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[12] }]; 
set_property -dict { PACKAGE_PIN C7   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[13] }]; 
set_property -dict { PACKAGE_PIN B6   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[14] }]; 
set_property -dict { PACKAGE_PIN C5   IOSTANDARD LVCMOS18 } [get_ports { GPIO_tri_io[15] }];
```

### ビットストリームの生成

implementation.tcl を Vivado で実行して、デザインの論理合成、配置配線、ビットストリームの生成を行います。

```console
vivado% cd target/Ultra96/build-v2018.2/fpga/
vivado% vivado -mode batch -source implementation.tcl
```

### ハードウェア情報の生成

export_hardware.tcl を Vivado で実行してハードウェア情報を生成します。

```shell
vivado% cd target/Ultra96/build-v2018.2/fpga/
vivado% vivado -mode batch -source export_hardware.tcl
```

このスクリプトを実行することにより、target/Ultra96/build-v2018.2/fpga/project.sdk/design_1_wrapper.hdf が生成されます。

## 謝辞

Ultra96 のボード設定ファイルや Bluetooth で UART0 の CTS/RTS を I/O ピンに接続する件に関しては以下のページと書籍を参考にしました。作者の @hidemi_ishihara さんに感謝します。

  * [「ひでみのアイデア帳」(https://sweetcafe.jp/?*20180704-214319)](https://sweetcafe.jp/?*20180704-214319)
  * [「超苦労した FPGA の薄い本 Yocto Project と立ち上げ編」(https://aquaxis.booth.pm/items/1057564)](https://aquaxis.booth.pm/items/1057564)

## 参考

 * [「VivadoをGUIを使わずに実行するためのTclスクリプト達」@Qiita](https://qiita.com/ikwzm/items/a0120079d2f7f86a5904)
 * [「Vivado でプロジェクトを作る Tcl スクリプト」@Qiita](http://qiita.com/ikwzm/items/666dcf3b90c36d16a0ed)
 * [「Vivadoで論理合成と配置配線を実行するTclスクリプト」@Qiita](http://qiita.com/ikwzm/items/36e5911c155c8303b705)
 * [「Vivadoでハードウェア情報をエクスポートするTclスクリプト」@Qiita](http://qiita.com/ikwzm/items/057d67d4a9e0828663cf)