Vivadoのプロジェクトをgitで管理するための最小限のファイル構成

みなさん、Vivaってますか？

Windows上でVivadoで設計していると

* リモートサーバのLinuxとかでも使えるよう、Tclとかバッチモードを覚えたいな～
* Vivadoのプロジェクトを最小限のファイルにしてgitで管理したいな～
* IPソースを修正して、Update IPとかやって、Generate BitStreamを押すという単調なボタン操作の繰り返しを自動化したいなぁ～

ということを感じたことはないでしょうか。

今回から数回にわけて、VivadoのTCLやプロジェクト管理とバージョン管理などについて、よりスマートな方法を紹介していきたいと思います。
クラウドに時間で借りた高速なLinuxサーバにSSHでログインしてコンパイルして結果だけ受け取るなんていう使う方もできてしまいます。

今回の記事ではTCLの操作やGUI操作がたくさん出てきますが、**最終的には全部スクリプト化するので不要になります。だから覚える必要はありません。ぼーーーっと読み流してください。**
スクリプトをブラックボックスにしないために、どういう原理なのかを説明するために解説します。

## なんでこんなにプロジェクトがでかいのだ

Vivadoでプロジェクトを作っていると、あっという間に数百MBのサイズになってしまいます。
自分で書いたソースはごくわずかなのに、XILINXが提供しているIPや一時ファイルで膨れ上がります。そのような巨大なフォルダをgitで管理するのは賢くないので、Vivadoのプロジェクト再生成できるような最小限のgitで管理するべきファイルは何かということを考えてみました。

# 今回使う評価ボードとサンプルプロジェクト

今回の記事で使用したのは特殊電子回路から発売されている[Artix-7ボード](http://www.tokudenkairo.co.jp/art7/)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/555db11e-0b99-597b-d5fa-d34aa3c0e2d6.png)

このボードの標準デザインにはEZ-USB FX3とDDR3メモリをAXIバスでつないだものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/5f858f03-dcbc-5b7c-243f-5f016e62439a.png)

このプロジェクトには以下のような要素があります。

* 自社製IP (USB FX3インタフェース、パターンジェネレータ)
* XILINXのIP (xlconstant、clk_wizなど)
* 自分で定義したインタフェース
* ブロックデザイン
* MIG
* RTLのソースを直接ブロックデザインに貼ったもの

なお、USB FX3インタフェースの中では、XILINXのFIFOを使っています。
いろいろな要素が入っているし、IPの中にIPが入っています。

# 最小限のファイルは何か？

gitで管理するべき最小限のファイルは以下のとおりです。

* プロジェクトを生成するためのtclファイル (WriteTclで作成)
* 自分のIP
    * RTLソース
    * component.xml
    * IP中のXILINX IP名/IP中のXILINX IP名.xci
    * xgui/IP名_バージョン.tcl
* インタフェース
* インタフェース名.xml
* インタフェース名_rtl.xml
* ボードデザインのwrapper.vhd
* MIGの設定ファイル (mig_a.prj)
* ブロックデザインに直貼りするRTLソース
* 制約ファイル(*.xdc)

## プロジェクトファイル .xpr は管理しない

意外と思われるかもしれませんが、**Vivadoのプロジェクトである.xprは必ずしも管理する必要はありません**。
むしろない方がよいです。なぜならば、xprにはファイルのパスが書かれていて、他のPCに持っていったときにパスを変えなければならないからです。それに自分で書いたものではないので肥大化します。チェックサムとかがgitのdiffにひっかかるのも目障りです。

xprを管理するのではなく、xprを生成するTCL(ティクル)を管理するという発想の転換が必要になります。

### TCLは避けて通れない
TCLというのは、めっちゃ古いスクリプト言語で、はっきりいって低級言語です。足し算も素直に書けないくらいのレベルの貧弱な言語です。
> でも、なぜかEDAツールではよく使われています。
> オブジェクトがつかめたり、リストが使えたりするので、なんとかやっていけるし、今更変えられないのでしょう。早くPythonとかに置き換わればいいのに。

TCLを使って、「新規プロジェクト作成」「デバイスは何々」「あんなソースを追加」「こんなソースを追加」というユーザが行うような操作を自動化したものを作って、それを管理するということになります。

面倒で複雑怪奇なTCLを自分で書く必要はありません。TclファイルはWriteTclで作成できるからです。（詳しいやり方は後述）

## gitで管理することのメリット
今回のプロジェクトであれば、以下のテキストファイルから元のVivadoのプロジェクトを復元できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/647f6f9e-52ca-e5db-7b2c-a70312af48c5.png)
BitStreamの生成が終わった時点でのプロジェクトフォルダのサイズは200MBytesくらいあったのに対して、上記で管理しているファイルは全部で490kByteくらいなので、本質は500分の1のサイズだと言えるでしょう。プロジェクトの大半はツールが自動的に生成している一時ファイルなのです。

# ブロックデザイン(*.bd)の作り方

上のファイル一覧を見ると、ブロックデザインが入っていないことに気が付くかと思います。

ブロックデザインは.bdというファイルで、中身はJSON形式でセルの配置や座標などが書かれています。
しかし、bdのファイルを利用するには付随するディレクトリやbxmlといったファイルも一緒になければなりません。
このbdに付随するディレクトリが大きく、100MBytesくらいになります。ファイルの種類も多くバイナリなのでgitで管理するには不向きです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/43bb211f-d734-81f5-afa0-3ccdf045ebb8.png)

そこで、BDファイルをそのままgitで管理するのではなく、プロジェクトファイルと同じく**bdを生成するTclを作る**ことを考えます。
その方法には2種類あります。

## Write Tclで生成する方法
まずはFile->Project->Write Tclを行う方法です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/bd9ba1f7-cef2-c183-cf2b-abe3f51976a6.png)

このコマンドは、プロジェクトを完全に再生成してくれるTclファイルを生成してくれます。
オプションダイアログでCopy sources to new projectと、Recreate Block Design Using Tclのチェックを入れておくと、
出来上がったtclファイルの中でBDファイルを再生成してくれるようになります。tclの中にBDの元が入る感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/a2d84658-3e6e-4bbf-8401-b55d9c5924bb.png)

こうして作られたxprを生成するTCLは、**create_project.tcl**という名前にしておくとわかりやすいですね。欠点は、ただでさえごちゃごちゃしているプロジェクトTCLの中に、BDが入ってしまうこと。わけのわからないファイルになってしまいます。
> 本来、プロジェクトTCLってのは、「デバイスは何にするか」「プロジェクトソースにどんなファイルを登録するか」を書き記したものなんです。BDを含めるなんて邪道です。


## Export Block Designで作る方法
BDを生成するもうひとつの方法は、File->Export->Export Block Designです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/5d7d83e0-ea54-fd55-a589-738c1e2bbaf4.png)

これで生成されたTclファイルを、空のプロジェクトで実行するとBlock Designにいろいろな部品を配置して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/00d184a5-5729-2ac1-e146-a2599d58289f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/f73ed340-8c77-b9cb-5a83-09904b54afcc.png)

モジュール間をつなぐところまでやってくれます。

つまり人が手作業で行っていたことをTclで自動化し、ゼロからbdを再生成してくれるわけです。
また、これらの方法で作られたBDの中にはXILINXのIPも含まれるので、xlconstandやxlslice、xlconcatなどはすべて入っています。
# まとめ
Write TclやExport Block Designを行うと、プロジェクトやブロックデザインを1つのtclファイルに還元してくれます。
これと、自分で作ったRTLソースや、XDCをgitで管理すればよいことになります。

Block DesignやTCLを生成するやり方は少なくとも2つ(以上)あって、

* **Write Tcl**を行うとTcl化プロジェクト(create_project.tcl)が作成される。
    * Tcl化プロジェクトはプロジェクト生成時にbdファイルをインポートする動作もする。
    * Recreate Block Designをチェックするとbdファイルも1つのtclにまとめることができる。
* **Export Block Design**を行うと、BD生成Tclが作成され、ここから元のBlock Designが完全に復元できる。
    * Block Designとプロジェクトを分離して別々に管理できる。
    * BD生成Tclには、Block Designのモジュールの配置や、MIGの設定、配線、IPの設定などが書かれている

一番最強なのは、まずExport Block DesignでBDファイルのTCLを作成し、それをインポートする形でプロジェクトのTCLを作ることです。
そうすると、プロジェクトとブロックデザインが別々ファイルとしてgitで管理できるのですが、Write Tclを実行する前にBDが出来ていないとインポートできないので、復元時にはこの2つのTCLを入り組んだ形で同時に実行しなければなりません。
それはVivadoの機能だけではできません。

## 結論
本日のところの結論は、**Write Tclをすれば全部入りのTCLができるから、それと自分で作ったIP、インタフェース、RTL、XDCをGITで管理すればよい**ということです。

 全自動化スクリプトは後の章で紹介します。

[第2章に続く](https://qiita.com/nahitafu/items/de4b295ea60ce6173a83)