ModelSimでVivado IPをシミュレーションする方法

タイトル通りModelSimを使ったVivado IPのコンパイル方法です。
ModelSim以外にもSynopsys VCS(VCSMX)やCadence NC-Verilog等のシミュレータでも同じ方法でいけます。

# 環境

今回は無償で使えるModelSim-Altera Starter Editionを使って解説します。
またVivadoの操作はGUIでの解説をしていますがもちろんTCLコマンドからでも同じようにできます。

# 適当なIPを生成する

IP Catalogから適当なIPを生成します。
今回は"AXI Uartlite"を生成しました。

生成したIPのディレクトを覗くと下記のようになってるかと思います。

```bash
.
└── axi_uartlite_0
    ├── axi_uartlite_0_board.xdc
    ├── axi_uartlite_0_ooc.xdc
    ├── axi_uartlite_0.veo
    ├── axi_uartlite_0.vho
    ├── axi_uartlite_0.xci
    ├── axi_uartlite_0.xdc
    ├── axi_uartlite_0.xml
    ├── doc
    │   └── axi_uartlite_v2_0_changelog.txt
    ├── hdl
    │   ├── axi_lite_ipif_v3_0_vh_rfs.vhd
    │   ├── axi_uartlite_v2_0_vh_rfs.vhd
    │   ├── lib_cdc_v1_0_rfs.vhd
    │   ├── lib_pkg_v1_0_rfs.vhd
    │   └── lib_srl_fifo_v1_0_rfs.vhd
    ├── sim
    │   └── axi_uartlite_0.vhd
    └── synth
        └── axi_uartlite_0.vhd
```

シミュレーションに必要なRTLは`sim/`にあります。

# 試しにコンパイルしてみる

ターゲットはVHDLなので`vcom`でコンパイルします。VerilogHDLなら`vlog`です。

```bash
$ vcom project_1/project_1.srcs/axi_uartlite_0/sim/axi_uartlite_0.vhd
```

するとライブラリがないとエラーがでます。

```bash
** Error: project_1/project_1.srcs/sources_1/ip/axi_uartlite_0/sim/axi_uartlite_0.vhd(56): (vcom-1598) Library "axi_uartlite_v2_0_23" not found.
** Error: project_1/project_1.srcs/sources_1/ip/axi_uartlite_0/sim/axi_uartlite_0.vhd(57): (vcom-1136) Unknown identifier "axi_uartlite_v2_0_23".
** Error: project_1/project_1.srcs/sources_1/ip/axi_uartlite_0/sim/axi_uartlite_0.vhd(59): VHDL Compiler exiting
End time: 11:52:39 on Nov 08,2019, Elapsed time: 0:00:00
Errors: 3, Warnings: 0
```

# ModelSim用のライブラリを作成

出力されたエラーには`axi_uartlite_v2_0_23`がないと出ますが実際には他にも必要があります。
この必要なライブラリはVivadoの`compile_simlib`を使って生成できます。
Tools > Compile Simulation Libraries...をクリックすると設定画面がでます。

SimulatorはModelSimが選択を選択します。
Advancedの`Compile Xilinx IP`にチェックを入れCompileをクリックしライブラリを生成します。
いくつかのライブラリに関してはModelSimのバージョンが古いため失敗します。

![01_msim.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84681/99441d2a-ce38-6cb5-80b1-59c2ee98b8eb.png)

しばらくすると`{project_name}.cache/compile_simlib/modelsim/`に
大量のシミュレーション用ライブラリが生成されます。

# VivadoからModelSimを実行する

VivadoのSettingsを開き、Simulation > Target simulatorからModelSimを選択します。

![02_msim.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84681/c6520d65-8f55-7cb6-242e-8a745b9b08c7.png)

Simulation Sourcesで生成したIPがTOPに選択されていることを確認し、
SIMULATION > Run Simulationを実行します。

成功するとModelSimが立ち上がります。邪魔なので閉じます。

# 検証環境に組み込むには

実際に検証環境に組み込む場合は必要なライブラリをコピーして使うといいと思います。

VivadoからModelSimを実行すると`{project_name}.sim/sim_1/`に
コンパイルとシミュレーションそれぞれのスクリプトが生成されます。

```bash
.
└── sim_1
    └── behav
        └── modelsim
            ├── axi_uartlite_0_compile.do　←これ
            ├── axi_uartlite_0_simulate.do　←とこれ
            ├── axi_uartlite_0.udo
            ├── axi_uartlite_0_wave.do
            ├── compile.log
            ├── compile.sh
            ├── modelsim.ini
            ├── modelsim_lib
            │   ├── msim
            │   │   ├── _info
            │   │   └── xil_defaultlib
            │   │       ├── _info
            │   │       ├── _lib1_0.qdb
            │   │       ├── _lib1_0.qpg
            │   │       ├── _lib1_0.qtl
            │   │       ├── _lib.qdb
            │   │       └── _vmake
            │   └── work
            │       └── _info
            └── simulate.sh
```

`axi_uartlite_0_simulate.do`を開き`-L`オプションで指定されるものが必要なライブラリになります。

`axi_uartlite_0_simulate.do`を参考にコンパイルスクリプトを作成します。
今回は必要ありませんが、VerilogHDLを含むIPでは`glbl`が必要な場合があります。
`glbl`は`Vivado/version/data/verilog/src/glbl.v`をコンパイルします。

またvsimを実行する際には`-L`オプションでライブラリを指定する必要があります。

```bash:compile.sh
vlib work

vmap axi_lite_ipif_v3_0_4   /path/to/simlib_dir/axi_lite_ipif_v3_0_4
vmap lib_pkg_v1_0_2         /path/to/simlib_dir/lib_pkg_v1_0_2
vmap lib_srl_fifo_v1_0_2    /path/to/simlib_dir/lib_srl_fifo_v1_0_2
vmap lib_cdc_v1_0_2         /path/to/simlib_dir/lib_cdc_v1_0_2
vmap axi_uartlite_v2_0_23   /path/to/simlib_dir/axi_uartlite_v2_0_23
vmap secureip               /path/to/simlib_dir/secureip
vmap xpm                    /path/to/simlib_dir/xpm

vcom /path/to/axi_uartlite_0/sim/axi_uartlite_0.vhd

vlog /path/to/Vivado/${vivado_version}/data/verilog/src/glbl.v

vsim -c -voptargs="+acc" \
  -L axi_lite_ipif_v3_0_4 \
  -L lib_pkg_v1_0_2 \
  -L lib_srl_fifo_v1_0_2 \
  -L lib_cdc_v1_0_2 \
  -L axi_uartlite_v2_0_23 \
  -L secureip \
  -L xpm \
  glbl \
  ${top_model} \
  -do "run -all ; quit"
```

# おわりに

今回はModelSimでやりましたが冒頭でも書いたように他のシミュレータでも同じやり方でいけます。
ただし例えばVCSですとsynopsys.setupにすべてのライブラリがマッピングされているため
何が必要なライブラリかひと目でわかりません。
なので一度ModelSimとかで必要なライブラリを確認するといいと思います。

# 参考

* [xilinx ip を含む modelsim でのシミュレーション](http://ippei.hatenablog.com/entry/2014/07/23/202941)