Ultra96V2でとりあえずLinuxを動かす (1) ※2021.1

# Ultra96V2でとりあえずLinuxを動かす
本記事では、自分用のメモとしてAvnet社製のUltra96V2でVivadoでHW Componentを作成から、Linux上でvaddサンプルプログラムを動かすまでを記載します。
使用するOSとツールのバージョンは以下の通りです。

 - Ubuntu 20.04.3
 - Vivado 2021.1
 - Vitis 2021.1
 - PetaLinux 2021.1

また、以上のツールのインストール方法はここでは記載しませんので、適宜Xilinxホームページから落としてきてください。
ちなみに、フローについては以下のチュートリアルを参考にしています。

https://github.com/Xilinx/Vitis-Tutorials

チュートリアルに倣い、フォルダー構成は以下の通りにします。

```
- ultra96v2
  - ultra96v2_platform
  - ultra96v2_plnx
  - ultra96v2_pkg
```

上記フォルダーの説明は以下のとおりです。

 - ultra96v2_platform : Vivadoの作業用フォルダ
 - ultra96v2_plnx     : PetaLinuxの作業用フォルダ
 - ultra96v2_pkg      : Vitisの作業用フォルダ

なお私はXilinxのツールやUltra96V2は愚か、Qiitaの記事を書くのはこれが初めてになりますので所々不備があるかと思いますが、その際はご指摘いただけると幸いです。

## VivadoでHW Componentの作成
### BDFファイルの導入
まず最初にBoard Definition Files (BDF) を落とします。

https://github.com/Avnet/bdf

上記サイトからDownload ZIPを押してBDFを落とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/c04554fc-8495-7ce4-3030-6494957c669d.png)

落としたbdf-master.zipを`<Vivadoインストールフォルダ>/Vivado/2021.1/data/boards/board_files/`に解凍します。

### Vivadoプロジェクトの作成
Vivadoを起動します。起動したら`Create Project`を押してultra96v2_platformフォルダ上にプロジェクトを作成します。

![Vivado_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/91887567-9963-4294-7a22-f25134f4e1e3.png)

最初のページはNextを押して飛ばします。次のページではプロジェクト名とプロジェクトフォルダの指定を行います。
project名はultra96v2とします。`Create project subdirectory`のチェックを外しましょう。

![Vivado_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/34ecf7bb-ecbe-8d09-a8bb-c0bfda0057e5.png)

Project TypeではRTL Projectを選択します。`Do not specify sources at this time`と`Project is an extensible Vitis Platform`のチェックをつけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/64740e13-51dc-11ff-4065-c242a1b5f0d4.png)


ボードの選択になります。`Ultra96-V2 Single Board Computer`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/5e4ce665-127b-6c51-5639-c375bc26a987.png)

プロジェクトを作成したら、左のFlow Navigatorの`IP INTEGRATOR -> Create Block Design`を選択します。

![Vivado_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/9e2bcd4b-fe2b-c5b5-5ae3-2686bde996fc.png)

デザイン名はultra96v2とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/f75f6aeb-96b4-65b9-1684-bb940ededb53.png)
##Zynq Ultrascale+ MPSoC IPの追加
このような画面になると思いますので、+ボタンを押してIPを追加していきます。

![Vivado_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/55d72d5a-4264-0928-0d6c-8172c606f2cb.png)

zynqと調べれば`Zynq UltraScale+ MPSoC`というのがヒットしますので、選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/83285dcd-8f24-ceb3-6133-e0568dbe31d8.png)

すると、Diagram上にZYNQのIPが追加されると思いますので、次にこちらの設定を行っていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/32b8c2b2-5c53-6293-8e56-4801fb5c1e13.png)

### I/O Configration

ここで参考にするのは主にUltra96V2の回路図になります。
以下のページの`ドキュメント -> Ultra96-V2 Rev1 Schematic`が回路図になります。

https://www.avnet.com/shop/japan/products/avnet-engineering-services/aes-ultra96-v2-g-3074457345644050668/

Diagram上のZYNQのIPをダブルクリックして設定ウィンドウを開きます。
まずMIOの電圧設定を行います。回路図p.10を見るとPS部のIO電源としてはVCC_PSAUXが使用されているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/8f7ddf8a-2d47-e2d1-d42d-b43a597a3af9.png)

p.15の回路図を見るとVCC_PSAUXは1.8Vとのことですので、I/O Configurationを選択して以下の図の通りLVCMOS18を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/0beb175e-a23c-2005-76f4-13be2483fd01.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/90aacaf1-f934-dbef-82b1-9fec222a6928.png)

それでは次にペリフェラルの設定を行っていきます。流石に回路図をいちいち掲載するのは面倒なので、結果だけ示します (使用しているペリフェラルを設定していくだけです)。ちなみに40、60ピンヘッダーに接続されているペリフェラルに関しては設定を行いません。必要最低限の設定を行いたいと思います。

#### SD
`Low Speed -> Memory Interfaces -> SD`の設定です。SD0とSD1を使用していますので、以下の通り設定を行います。SD0、SD1共にSlot TypeはSD 2.0となりますので設定を変更します。IOピンに関しても図の通り設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/ddb79289-c174-6357-f864-8c14000c2d26.png)

#### UART
`Low Speed -> I/O Peripherals -> UART`の設定です。図の通りIOの設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/8e39e68f-8189-1fe0-c40f-33b6c7797368.png)

#### GPIO
`Low Speed -> I/O Peripherals -> GPIO`の設定です。図の通り有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/63820758-db66-d391-e68b-4709d85b0fd9.png)

#### USB
`High Speed -> USB`の設定です。GT Laneの設定を変更します。
USB Resetの設定をどうすればいいかは情報を見つけられませんでしたが、デフォルトのBoot Pinで動作しましたので、変更は加えません。詳しい方いましたら情報ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/2d2ad787-9733-e494-e21f-6cc1549873a1.png)

#### Display Port
`High Speed -> DisplayPort`の設定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/53d59015-cb1a-af56-38d8-0c66a22bfb28.png)

### Clock Configuration
次にクロック設定を行います。
#### Input Clocks
Input Clocksの設定では、GT Laneのリファレンスクロックのみを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/bb791f46-c895-9449-683c-c2a16249d57e.png)

#### Output Clocks
こちらの設定は自動設定ではなかなか上手く設定してくれませんでしたので、手動で設定を行います(bspのプラットフォームを参考にした)。基本はRequested FreqとActual Frequencyを一致させることが目標です。

まず`Enable Manual Mode`にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/61e3bf7e-c92a-667d-50d6-c9b1b289fc94.png)

##### PLL
PLLは以下の分周比を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/45f4ada0-b64b-aa78-0efd-c327ac89db91.png)

##### Low Power Domain Clocks
`Low Power Domain Clocks -> Peripherals/IO Clocks`の設定を図のように変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/268786d2-1759-9fad-4dfb-3e93bf01f5e0.png)


##### Full Power Domain Clocks
`Full Power Domain Clocks`は以下の通り設定を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/e6d15afb-c025-9570-86c6-09d36c17cdd1.png)

##### Advance Clocks
`Advance Clocks`は以下の通り設定を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/2d4bdfe3-5d4a-b5b3-9130-679b4d5bafe7.png)

### DDR Configuration
DDRの設定は以下の通り変更をします。tRC等のタイミングの設定はどうしたら良いかわからなかったのでデフォルトのままです。情報持っている方いたら教えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/6177c57e-6ca0-8379-9cb5-73596b2b1dac.png)

### PS-PL Configration
PS部とPL部を繋ぐインターフェース部の設定になります。割り込みを一つ追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/d8863ec4-ce43-8bf9-bf98-89d1c6330164.png)

Zynq IPの設定は以上になります。OKを押しましょう。

## Clocking Wizard IPの追加
次にデザインのクロックの設定を行います。Clocking Wizard IPを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/20256d5b-1a2e-55d2-163b-19ada98cf192.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/87cb8d9e-5bfd-0cf6-e5bd-90efa1ea55c8.png)

今回はテストプログラムであるvaddを動作させるだけですので、出力クロックは1つだけ設定します。
周波数は300MHzとしておきます (特にこだわりは無い。動くかな？)。
また、リセットの極性を合わせるためReset TypeをActive Lowに設定します。
![Vivado_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/dbe76d74-696c-54a7-9118-d71cbaa4747c.png)

配線します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/218dc77c-adff-c511-d1c8-a8914c15f782.png)

## Processor System Reset IPの追加
Clocking Wizardで出力したクロックに同期したリセット信号を生成します。Clock Exportで必要とのことです(具体的にはわからない)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/f3e44654-1a53-ccb4-205c-1cd47cd88489.png)

以下のように配線しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/ca19c3ec-e685-20a9-0eca-e2a0d8e0048c.png)

## AXI Interconnect IPの追加
このIPは後述するAXI Interrupt Controller IPとの接続ために用います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/ebc92349-ffc2-4bcf-0f75-8eb41bec4199.png)


Master Interfaceの数を1つにします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/c8d66fd2-f4c5-0af5-68a1-3f1e0c57af8f.png)
配線します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/5fc69422-3be7-5175-57d6-413714163efa.png)

## AXI Interrupt Controller IPの追加
カーネル -> プラットフォームへの割り込みのため、AXI Interruput Controller IPを追加します。なお、カーネルとプラットフォーム間の割り込みの対応付けはV++リンカーが自動で行ってくれるみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/c90f6952-65f6-ee6a-3957-c1892ddbc891.png)
`Interrupt Output Connection`をSingleに設定します。
![Vivado_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/0f095466-c2b6-82d3-96e6-41d4df679f62.png)
配線します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/584adb7a-d848-5e07-f66f-fdfa0a1b412f.png)

忘れていましたが、maxihpm0_lpd_aclkとclk_out1を接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/8540f0bf-e720-35f0-c79b-cccd99978ff4.png)

## Platformの設定
Platform Setupを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/6110af4a-be52-e1b1-0b31-013805343130.png)
AXI Portの設定を行います。SP Tagはスレーブインターフェースに対して記述するようです。V++(Vitisのコンパイラ)の設定でこれらのインターフェースが選択できるようにこちらのTagを命名する必要があるようです。ユーザー定義ですので、適当に命名しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/e5648b6c-9618-3187-c9f0-c73d4fa8ce82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/f30f9c05-e7bb-052c-c2cd-4a0ca96052a7.png)
次に、プラットフォーム <-> カーネル間のクロック設定を行います。ここで設定できるクロックはProcessor System Reset IPを用いて同期リセットを生成したクロックのみになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/18ca1ba2-aa49-df89-718c-227679549b28.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/9fbd3837-2255-bc86-1d08-5c28d05a6e24.png)
次にInterruptの設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/04e2cb6e-719b-227d-1ae8-9812e445110b.png)
Platform Nameは適当に入力しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/f5961541-edcb-9672-7392-bd57f28fc81f.png)

以上の設定が終わったらDiagramに戻り、Validationを行います。

![Vivado_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/de330f87-90b8-bc13-5bf2-7981163ce53f.png)

すると、このようにAXI Intterupt Controllerのintrポートに何も接続されていないとWarningが出ますが、これは後にV++のリンカーが勝手に接続してくれますので、問題無いとのことなので無視。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/e8df2884-c802-be6f-ee8e-c9fc905a7971.png)
## XSAファイルのエクスポート
次に、Design Sources内のultra96v2を右クリックして`Create HDL Wrapper...`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/8c452cf9-2a7c-6629-7de9-6ec0aff874dc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/8e89d717-90f7-86a8-24b9-7a8a20fc6daa.png)

次にBlock Designの生成を行います。Flow Navigatorの`Generate Block Design`を選択します。
![Vivado_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/f5ffaf74-b372-0727-6b22-a67c0f39c481.png)
Systhesis OptionsをGlobalに変更し、Generateボタンを押します。
![Vivado_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/41208409-ae40-d0c0-e3e1-bb1b4c41cf89.png)

終わったらメニューバーから`File -> Export -> Export Platform...`を選択します。
Platform TypeはHardwareを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/c4a8e8a5-f5a4-c70b-7ab6-23f4c6494630.png)
Platform StateはPre-synthesisを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/b13e169f-8dbe-9e0d-ae78-d52e3ece4135.png)
ここは何も変更しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/d52aa23b-b845-6629-f24c-aaa672abf753.png)
こちらも特に変更は加えません。
![Vivado_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149874/ab085c7f-4196-faae-c7b9-563bd91254be.png)

Finishを押します。

するとプロジェクトの作業フォルダに`ultra96v2_wrapper.xsa`が生成されているはずです。

以上でVivadoのHW Component作成は終わりです。

## 次の記事
本記事は以上までとなります。次はPetaLinuxを用いてLinuxカーネルの構築を行いたいと思います。

https://qiita.com/alkarhythm/items/72398a561c7c28931ed7