普通の工業大学生がUltra96 V1を使ってPYNQ Overlay Tutorialをしてみた

※M2です．(PYNQは)初心者です．
※この手の記事は山程あって今更感もありますが，毎回やり方を忘れるので，メモ用として残します．
※PYNQ自体の解説記事ではありません．実装内容自体は↓の"Developing Single IP"と同じです．
PYNQ Overlay Tutorial: https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/overlay_tutorial.html
※PYNQの使い方というより，Vivadoの使い方の記事になってしまいました．
※工業大学生です．文章力に期待をしてはいけません．


#はじめに

以下の状態を満たした状態で始めることとします．

- Ultra96 V1上で，PYNQのjupyter-notebookを起動できる．
- Vivado HLS,Vivadoがインストール済み&使用できる．

今回の記事では，Vivadoは2018.3のバージョンのものを用いました．

最終目標は，[PYNQ Overlay Tutorial](https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/overlay_tutorial.html)のadd関数をUltra96 V1上で動かせるようにすることです．

#Vivado HLSを用いてIPコアを作成
[PYNQ Overlay Tutorial](https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/overlay_tutorial.html)に沿って，2つの整数を加算するIPコアを作成します．
Vivado HLSを起動して新しいプロジェクトを作成し，Partsは"xczu3eg-sbva484-1-e"を指定します.

新しいファイルをsourceに追加し，[PYNQ Overlay Tutorial](https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/overlay_tutorial.html)のadd関数をコピペしておきます．このadd関数をトップ関数に指定し，C Synthesisで合成をかけます．
<img width="700" alt="vivado1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/0f39da27-6751-666e-4bea-fd89a4dad71a.png">
合成が完了したら，Export RTLでIPコアを作成します．

#Vivadoを用いてbit streamを作成
Vivadoを起動したら，新しいプロジェクト(RLT Project)を作成し，BoardはUltra96 V1を指定します．
### IPコアをプロジェクトに追加する
前の工程で作成したIPコアをこのプロジェクトに追加できるように設定します．
Tools→Settingsを選択し，Project SettingsからIP→Repositoryを選択します．"+"ボタンを押して，出てきたディレクトリ選択画面の中から，先程作成したVivado HLSプロジェクトの中の"solution1/impl/ip"を選択します．

上手くいくと，以下のようにIPコアが追加されます．
<img width="700" alt="vivado1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/4900c6c3-f90b-45d7-1b3b-3ac80b3fb310.png">


### Block Designを作成する
IP INTEGRAGERのCreate Block Designを選択します．
Diagramの中のadd IP("+"ボタン)を選択し，先程追加したIPコアを指定します．
<img width="700" alt="vivado2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/d5a9553d-fbb6-0b93-d483-e49bb3c8223f.png">

同様にして，Zynq UltraScale+ MPSoCも追加します．
<img width="700" alt="vivado3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/b669fbde-6799-75f5-0669-47bb5ba5a005.png">

以上の操作が完了したら，Run Block Automation → Run Connection Automationを選択し，配線をしてもらいます．
<img width="700" alt="vivado4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/0f0a0276-fa62-2276-4ed5-7ceb0a6a1787.png">


配線が完了したら，保存してBlock Designを閉じます．

### Bitstreamを生成する
Sources→Design Sourcesで先程，作成したブロックデザインを右クリックし，Create HDL Wrapperを選択します．
<img width="559" alt="vivado5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/f31fa510-fe6b-4dfb-50b5-dcdd989421b6.png">

Wrapperができたら，Generate Bitstreamを選択して完了です．
#Ultra96上でOverlayを動かす
`<Vivado プロジェクト>.src/sources_1/bd/design1/hw_handoff/design_1/design_1.hwh`
`<Vivado プロジェクト>.src/sources_1/bd/design1/hw_handoff/design_1/design_1_bd.tcl`
`<Vivado プロジェクト>.runs/impl_1/design_1_wrapper.bit`
の3つのファイルを，まとめてUltra96上の同一ディレクトリ内にコピーしておきます．
これら3つのファイルは念の為，すべて同じ名前(ここでは，design_1.*)にしておきます．

あとは[PYNQ Overlay Tutorial](https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/overlay_tutorial.html)に沿って，overlayを動かしていきます．

```python
from pynq import Overlay

overlay = Overlay('/home/xilinx/design_1.bit')
add_ip = overlay.add_0

add_ip.write(0x10, 4)
add_ip.write(0x18, 5)
add_ip.read(0x20)
```
動きました．

![jupyter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/444398a4-e862-42ea-7da3-2ef65d0c2b63.png)

#感想
Tutorialって行間が広すぎて生きて帰ってくるのが大変ですね．