Vivado 2018.3でMIGを使うデザインがクラッシュする原因と対策

Vivado 2018.3でMIGを使うデザインがクラッシュするという問題がありました。

下の図のようにMIGを使うデザインで、Synthesizeを行おうとしたり、MIGの設定を開こうとしたり、ひどいときにはプロジェクトを開くと、ログも残さずにクラッシュしてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/122799f3-4f24-2e31-edbf-86904fcb24b4.png)

# 先行する報告
[AR# 71898](https://japan.xilinx.com/support/answers/71898.html)に「MIG 7 Series - パッチ - 2018.3 での既知の問題」というのがありますが、ここに書いてあるパッチを適用しても改善されません。また、[フォーラムの記事](https://forums.xilinx.com/t5/Design-Entry/Vivado-Crash-when-generating-MIG-7series-during-synthesis-in/td-p/982246)でもAR71898を試したが改善しなかったという例が出ています。結局2019.1にアップデートして回避したようなのですが、Vivado 2018.3のMIGにはまだ知られていないバグがあるようです。

# 確実にクラッシュするプロジェクトを作る
原因を確かめるために、まずは確実にクラッシュするプロジェクトを作ります。

## Vivadoで新規プロジェクトを作成
デバイスはSpartan-7の50にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/e2da7ea5-7b89-039f-c914-11bbbce07ec2.png)

## MIGの配置
BlockDesignを作成し、MIGを配置します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/69e933a8-dd25-f38a-8396-99953780a663.png)

## MIGの設定ダイアログを開いてカスタマイズ
配置した直後は、クロックとリセットしかないMIGなので、ダブルクリックして設定画面を開き、Nextを押し押し最後まで設定します。カスタマイズする必要はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/5853ce57-1955-83b7-72f2-83b44ecb052a.png)

## ポートの出現
最後までカスタマイズすると、いろいろな入出力ポートが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/9b34a04d-76ef-d7ff-b28e-b3e063165465.png)

## 保存
Vivadoで一度セーブします。

## 論理合成をしてみる
何も特別なことをしていないMIG使用デザインですが、実は、この時点で諸悪の根源であるバグが埋め込まれています。
I/Oポートを付けたり、AXIのソースを付け加えたりして論理合成を開始するとクラッシュするでしょう。運が良ければ動くかもしれませんが。

# 原因の究明
## MIGの設定の中身はどこ？
MIGはユーザが設定した内容をmig_a.prjというファイルに保存します。(mig_b.prjというのもありますが、おそらく1つの前の状態がバックアップされるものではないかと思います。)

prjは ** <プロジェクトフォルダ>\<プロジェクト名>.srcs\sources_1\bd\design_1\ip\design_1_mig_7series_0_0 ** にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/e26f3de2-f564-b579-46c9-3e11d835b7de.png)


## prjの中身
VivadoのSourceの中のConfigration Filesの中にあるmig_a.prjをクリックすると、フォルダを開くかと聞かれるので開くと、そこにあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/a8153ec3-dec6-398d-ffdb-37cc449db613.png)

prjの中身はXMLファイルのようで、その先頭は以下のような内容になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/6273c273-8314-0691-5d1f-5a1cc3cbf855.png)
これだけ見るとそんなに悪くはなさそうに見えます。

```mig_a.prj:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project NoOfControllers="1">
  <ModuleName>design_1_mig_7series_0_0</ModuleName>
  <dci_inouts_inputs>1</dci_inouts_inputs>
  <dci_inputs>1</dci_inputs>
  <Debug_En>OFF</Debug_En>
・・・
```

## バイナリで見てみる
ところが、バイナリエディタで開いてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/e0068968-f446-eeb8-0589-77399fb74653.png)

**<?xml**の前に、EF BB BFという3バイトのゴミがくっついていました。

どうやらこのゴミが悪さをしているようで、Synthesizeの開始時やプロジェクトのオープンの際にクラッシュしてしまうようです。バイナリエディタを使って綺麗に取り除くと、クラッシュしなくなります。

# どうやって発見したのか？
どうやって気が付いたかというと、Vivado 2018.2で作ったプロジェクトをVivado 2018.3にアップグレード際にはこの問題が発生しなかったので、そのBlockDesignをTcl化してDIFFしてみました。TCL化BlockDesignの中ではmig_a.prjを生成する関数があるのですが、要するにprjファイルをベタに埋め込んでputsでファイルに書き込んでいるのですが、そこにゴミが映っていたのです。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542455/1b089831-9af3-4e2e-ef84-c03986a2dce2.png)
このDIFFで見つけることができました。

# まとめ
この3バイトのゴミはには以下の特徴があります。

* Vivado 2018.3でのみ発生する (2018.1、2018.2では発生しない。2019.1は未確認)
デバイスのファミリによらない。Spartan-7だけでなくKintex-7、ZYNQ、Artix-7でも発生する。* MIG 4.2でのみ発生すると考えられる。
* AR71898のパッチを当てても改善しない
* この3バイトのゴミの内容は変わることがある
* パソコンの問題ではない（少なくとも3台のPCで検証した）

今は2019.2が流行しているので2018.3を使う機会は少ないかもしれませんが、困っている人がいたら是非prjファイルの先頭をバイナリエディタで見るということを伝えてあげてください。