PYNQ-Z1 の ビットストリームを Vivado 2016.4 で再ビルドする対処療法

## はじめに

PYNQ の PL 部のビルド環境一式は github で公開されていて、自分でカスタマイズすることが出来ます。github で公開されている環境は Vivado 2016.1 用のものであり、Vivado 2016.4 でビルドしようとしたら色々と問題がありました。この記事では、PYNQ の PL 部を Vivado 2016.4 で再ビルドする際に遭遇した問題への対処療法を防備録として示します。
なお、あくまでも現時点(2017/1/26)での対処療法です。こうすればエラーが出なくなったというだけで、対象方法を間違っている場合があります(私は PYNQ を持っていないので実機での確認はしていません)。また、Vivado のバージョンが変わったり、問題となった IP のバージョンが変わることで解決されるかもしれません。
この件で何か情報をお持ちの方はコメントください(これが本音)。

## ダウンロード

github からダウンロードしてください。

* [https://github.com/Xilinx/PYNQ](https://github.com/Xilinx/PYNQ)

```
shell$ git clone https://github.com/Xilinx/PYNQ
shell$ cd PYNQ
```

## Vivado 2016.1 で再ビルド

現在 github で公開されているリポジトリは Vivado 2016.1 用です。
Vivado 2016.1 を起動して、Tcl Console を開いて次のように入力すればビットストリームが出来ます。

```
cd <cloneしたディレクトリ>/Pynq-Z1/vivado/base
source ../../bitstream/base.tcl
```

## Vivado 2016.4 で再ビルド

Vivado 2016.4 を起動して前節のように入力しても、次のようなエラーが出て失敗します。

```
ERROR: [BD_TCL-109] This script was generated using Vivado <2016.1> and is being run in <2016.4> of Vivado.
Please run the script in Vivado <2016.1> then open the design in Vivado <2016.4>.
Upgrade the design by running "Tools => Report => Report IP Status...", then run write_bd_tcl to create an updated script.
```

このエラーは Pynq-Z1/bitstream/base.tcl を次のように修正すれば回避できます。

```Tcl:Pynq-Z1/bitstream/base.tcl(修正前)
################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2016.1
set current_vivado_version [version -short]
```

```Tcl:Pynq-Z1/bitstream/base.tcl(修正後)
################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2016.4
set current_vivado_version [version -short]
```

## microblaze のバージョンをアップグレード

Vivado 2016.4 では Xilinx 社の提供する microblaze という IP のバージョンが Vivado 2016.1 では 9.6 でしたが、Vivado 2016.4 では 10.0 にアップグレードされています。従って Pynq-Z1/bitstream/base.tcl も新しいバージョンを指定する必要があります。microblaze は3箇所で使われています。それぞれ次のように Pynq-Z1/bitstream/base.tcl を修正してください。

```diff:
1282c1282
<   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:9.6 mb ]
---
>   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:10.0 mb ]
1522c1522
<   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:9.6 mb ]
---
>   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:10.0 mb ]
1693c1693
<   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:9.6 mb ]
---
>   set mb [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:10.0 mb ]
```

## Block Design 生成時のエラー対応

base.tcl 実行時に次のようなエラーが出て Block Design の生成に失敗します。

```
CRITICAL WARNING: [IP_Flow 19-973] Failed to create IP instance 'system_dvi2rgb_0_0'. Error during customization.
ERROR: [#UNDEF] Error found in parameter dependencies in XGUI files. Invalid parameters found in dependency constraints of 'BUSIF_ENABLEMENT.ASYNCRST' 

ERROR: [BD 5-7] Error: running create_bd_cell  -vlnv digilentinc.com:ip:dvi2rgb:1.6 -type ip -name dvi2rgb_0 .
ERROR: [Common 17-39] 'create_bd_cell' failed due to earlier errors.

    while executing
"create_bd_cell -type ip -vlnv digilentinc.com:ip:dvi2rgb:1.6 dvi2rgb_0 "
    (procedure "create_hier_cell_video" line 77)
    invoked from within
"create_hier_cell_video [current_bd_instance .] video"
    (procedure "create_root_design" line 193)
    invoked from within
"create_root_design """
    (file "base.tcl" line 3382)
```

なんだかよく判らないエラーですね。私にもわかりません。どうやら dvi2rgb という Digilent 社が提供している IP になにか問題があるようです。
実はこのエラーは Pynq-Z1/vivado/ip/dvi2rgb_v1_6/component.xml という IP-XACT 仕様のファイルを次のように修正すると回避出来ます。


* AsyncRst の `<spirit:vendorExtensions>` ～  `</spirit:vendorExtensions>` を削除する

```xml:Pynq-Z1/vivado/ip/dvi2rgb_v1_6/component.xml(修正前)
    <spirit:busInterface>
      <spirit:name>AsyncRst</spirit:name>
      <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
      <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
      <spirit:slave/>
      <spirit:portMaps>
        <spirit:portMap>
          <spirit:logicalPort>
            <spirit:name>RST</spirit:name>
          </spirit:logicalPort>
          <spirit:physicalPort>
            <spirit:name>aRst</spirit:name>
          </spirit:physicalPort>
        </spirit:portMap>
      </spirit:portMaps>
      <spirit:parameters>
        <spirit:parameter>
          <spirit:name>POLARITY</spirit:name>
          <spirit:value spirit:id="BUSIFPARAM_VALUE.ASYNCRST.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_HIGH</spirit:value>
        </spirit:parameter>
      </spirit:parameters>
      <spirit:vendorExtensions>
        <xilinx:busInterfaceInfo>
          <xilinx:enablement>
            <xilinx:isEnabled xilinx:resolve="dependent" xilinx:dependency=" ">false</xilinx:isEnabled>
          </xilinx:enablement>
        </xilinx:busInterfaceInfo>
      </spirit:vendorExtensions>
    </spirit:busInterface>
```

```xml:Pynq-Z1/vivado/ip/dvi2rgb_v1_6/component.xml(修正後)
    <spirit:busInterface>
      <spirit:name>AsyncRst</spirit:name>
      <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
      <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
      <spirit:slave/>
      <spirit:portMaps>
        <spirit:portMap>
          <spirit:logicalPort>
            <spirit:name>RST</spirit:name>
          </spirit:logicalPort>
          <spirit:physicalPort>＋
            <spirit:name>aRst</spirit:name>
          </spirit:physicalPort>
        </spirit:portMap>
      </spirit:portMaps>
      <spirit:parameters>
        <spirit:parameter>
          <spirit:name>POLARITY</spirit:name>
          <spirit:value spirit:id="BUSIFPARAM_VALUE.ASYNCRST.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_HIGH</spirit:value>
        </spirit:parameter>
      </spirit:parameters>
    </spirit:busInterface>
```

実は上記の修正だけでは、同じような問題が今度は SyncRst でも発生します。こちらのほうも修正する必要があります。

* SyncRst の `<spirit:vendorExtensions>` ～  `</spirit:vendorExtensions>` を削除する

```xml:Pynq-Z1/vivado/ip/dvi2rgb_v1_6/component.xml(修正前)
    <spirit:busInterface>
      <spirit:name>SyncRst</spirit:name>
      <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
      <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
      <spirit:slave/>
      <spirit:portMaps>
        <spirit:portMap>
          <spirit:logicalPort>
            <spirit:name>RST</spirit:name>
          </spirit:logicalPort>
          <spirit:physicalPort>
            <spirit:name>pRst</spirit:name>
          </spirit:physicalPort>
        </spirit:portMap>
      </spirit:portMaps>
      <spirit:parameters>
        <spirit:parameter>
          <spirit:name>POLARITY</spirit:name>
          <spirit:value spirit:id="BUSIFPARAM_VALUE.SYNCRST.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_HIGH</spirit:value>
        </spirit:parameter>
      </spirit:parameters>
      <spirit:vendorExtensions>
        <xilinx:busInterfaceInfo>
          <xilinx:enablement>
            <xilinx:isEnabled xilinx:resolve="dependent" xilinx:dependency=" ">false</xilinx:isEnabled>
          </xilinx:enablement>
        </xilinx:busInterfaceInfo>
      </spirit:vendorExtensions>
    </spirit:busInterface>
```

```xml:Pynq-Z1/vivado/ip/dvi2rgb_v1_6/component.xml(修正後)
    <spirit:busInterface>
      <spirit:name>SyncRst</spirit:name>
      <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/>
      <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/>
      <spirit:slave/>
      <spirit:portMaps>
        <spirit:portMap>
          <spirit:logicalPort>
            <spirit:name>RST</spirit:name>
          </spirit:logicalPort>
          <spirit:physicalPort>
            <spirit:name>pRst</spirit:name>
          </spirit:physicalPort>
        </spirit:portMap>
      </spirit:portMaps>
      <spirit:parameters>
        <spirit:parameter>
          <spirit:name>POLARITY</spirit:name>
          <spirit:value spirit:id="BUSIFPARAM_VALUE.SYNCRST.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_HIGH</spirit:value>
        </spirit:parameter>
      </spirit:parameters>
    </spirit:busInterface>
```

## 論理合成時のエラー対応

前節の対応で Block design を生成することは出来ますが、今度は論理合成時に次のようなエラーが出て失敗します。

```
INFO: [Synth 8-638] synthesizing module 'ChannelBond' [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/ChannelBond.vhd:74]
INFO: [Synth 8-256] done synthesizing module 'ChannelBond' (7#1) [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/ChannelBond.vhd:74]
INFO: [Synth 8-256] done synthesizing module 'TMDS_Decoder' (8#1) [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/TMDS_Decoder.vhd:96]
INFO: [Synth 8-638] synthesizing module 'EEPROM_8b' [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/EEPROM_8b.vhd:85]
	Parameter kSampleClkFreqInMHz bound to: 200 - type: integer 
	Parameter kSlaveAddress bound to: 7'b1010000 
	Parameter kAddrBits bound to: 7 - type: integer 
	Parameter kWritable bound to: 0 - type: bool 
	Parameter kInitFileName bound to: 720p_edid.txt - type: string 
ERROR: [Synth 8-3302] unable to open file '720p_edid.txt' in 'r' mode [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/EEPROM_8b.vhd:90]
ERROR: [Synth 8-421] mismatched array sizes in rhs and lhs of assignment [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/EEPROM_8b.vhd:115]
ERROR: [Synth 8-285] failed synthesizing module 'EEPROM_8b' [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/EEPROM_8b.vhd:85]
ERROR: [Synth 8-285] failed synthesizing module 'dvi2rgb' [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/dvi2rgb.vhd:110]
ERROR: [Synth 8-285] failed synthesizing module 'system_dvi2rgb_0_0' [g:/work/PYNQ/Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ip/system_dvi2rgb_0_0/synth/system_dvi2rgb_0_0.vhd:80]
---------------------------------------------------------------------------------
Finished RTL Elaboration : Time (s): cpu = 00:00:13 ; elapsed = 00:00:15 . Memory (MB): peak = 338.871 ; gain = 127.531
---------------------------------------------------------------------------------
RTL Elaboration failed
INFO: [Common 17-83] Releasing license: Synthesis
39 Infos, 5 Warnings, 0 Critical Warnings and 6 Errors encountered.
synth_design failed
ERROR: [Common 17-69] Command failed: Synthesis failed - please see the console or run log file for details
INFO: [Common 17-206] Exiting Vivado at Thu Jan 26 13:21:58 2017...
```

なにやらファイルが見つからないと言っています。実は dvi2rgb では EEPROM をエミュレートするモジュール(EEPROM_8b.vhd)があるのですが、その ROM の内容を 720p_edid.txt とか 900p_edid.txt という名前のテキストファイルで持っていて、EEPROM_8b.vhd が論理合成時にそのファイルを読み込んで ROM を生成するようになっています。で、論理合成時にこのテキストファイルが見つからないと文句を言っているわけです。
720p_edid.txt などは VHDL のソースコードと同じディレクトリ Pynq-Z1/vivado/ip/dvi2rgb_v1_6/src/ にあります。
Vivado 2016.1 では IP をプロジェクトに取り込む際に VHDL/Verilog-HDL 以外のテキストファイルも取り込んでくれたのですが、何故か Vivado 2016.4 では取り込んでくれなくなりました（バグ？　仕様変更？）。いろいろ試してみましたが、どうやっても VHDL/Verilog-HDL 以外のファイルを取り込むことができませんでした。~~Vivado 2016.4 で VHDL/Verilog-HDL 以外のテキストファイルをプロジェクトに取り込む方法を知っている方はお知らせください。~~ コメントであるように userFileType を mif にすることでプロジェクトに取り込めるようになるそうです。aster_ism さん、ありがとうございました。

~~ここでは、あくまでも対処療法ですが、このエラーが発生した後に強引にこれらテキストファイルをプロジェクトにコピーして対処することにしました。
問題はコピー先のディレクトリですが、残念ながら、Vivado 2016.4 になってから IP を取り込む際のディレクトリがなにやら４文字の意味不明(16ビットを16進数表記？)な名前になってしまいました。まずはどのディレクトリに dvi2rgb が取り込まれたか知る必要があります。
上記のエラーログの内容から、EEPROM_8b.vhd は Pynq-Z1/vivado/base/base/base.srcs/sources_1/bd/system/ipshared/050c/src/ にあることが判ります。このディレクトリに 720p_edid.txt をコピーします。~~

こうして論理合成を再開すると(プロジェクトを再構築すると×)、今度は論理合成が通ります。


## タイミング違反を解消する

[「PYNQ-Z1 の ビットストリームを再ビルドしたときのタイミング違反を無くす @Qiita」](http://qiita.com/ikwzm/items/980ab4c4f1fe2d166d2c) にて Vivado 2016.2 で再ビルドした際のタイミング違反への対応を説明しています。タイミング違反に関しては Vivado 2016.4 でも Vivado 2016.2 と同様の対処が必要です。詳細は[「PYNQ-Z1 の ビットストリームを再ビルドしたときのタイミング違反を無くす @Qiita」](http://qiita.com/ikwzm/items/980ab4c4f1fe2d166d2c) を参照してください。