Vivado Simulator(xsim)でのロジックシミュレーションおよびデバッグ

AMD(Xilinx)のFPGA開発キットであるVivadoに付属している標準のロジックシミュレータVivado Simulator(xsim)はライセンスフリーで使える。なのでFPGA開発に限らず、特に個人でRTLのロジックシミュレーションをやりたい様な場合には大変重宝する。世の中にはフリーで使えるシミュレータは他にもあるが、今日のRTL開発やテストベンチ開発では必須となったSystemVerilogを十分にサポートしているものはVivado Simulator以外にはない（あったら教えて！）。しかも、UVM（Universal Verification Methodology）までにも対応している。なんて寛容な。大変ありがたい。（2024/8/31追記：[Metrics社のDsim Desktop](https://www.metrics.ca/)と言うシミュレータがフリーで使える事を教えてもらいました。SVAやDPI-C、UVMもフリーで使えます！言語サポートも十分です。）
しかし、Vivado Simulator(xsim)を使ったSystemVerilog（等）のロジックシミュレーションの方法を紹介したまとまった記事があまりない。なのでその方法を紹介しておこうと思う。
ここで紹介する方法はプロジェクトファイル等は使わず、全てコマンドでの実行方法のみ。また、Linuxの環境を想定する。Windowsは知らん。以下、テストベンチトップのモジュール名はtb_topを想定。

### ■ 事前設定
まず、事前に以下を実行し、xvlog/xelab/xsimコマンドがPATHへ追加される様にしておく。

```shell:bash
% source <Vivado Install Directory>/settings64.sh
```

```shell:csh
> source <Vivado Install Directory>/settings64.csh
```

以下/tools/Xilinx/Vivado/2022.2/にVivadoがインストールされている場合で、シェルにbashを使用している場合の例

```bash:例
% source /tools/Xilinx/Vivado/2022.2/settings64.sh
```

`~/.bashrc`や`~/.cshrc`に以下の様に記述して自動で最新バージョンを設定するようにしておくと良いだろう。

```bash:~/.bashrc
#---------- Xsim ----------------------------------------------
source `ls -t1d /tools/Xilinx/Vivado/* | head -n 1`/settings64.sh
```

```shell:~/.cshrc
#---------- Xsim ----------------------------------------------
source `ls -t1d /tools/Xilinx/Vivado/* | head -n 1`/settings64.csh
```

上記PATH設定はやらなくても良いが、やらない場合にはそれぞれ`<Vivado Install Directory>/bin/`にあるコマンドを直接実行する必要がある。

シミュレーションの実行およびデバッグの仕方として以下大きく分けて３種類のやり方がある。
1. コマンドでSimのBatch実行後、ログを確認
2. GUIを立ち上げてInteractiveにSimを実行
3. 信号波形データダンプでSim実行した後GUIで確認

以下でそれぞれやり方を説明。

### ■ BATCH実行
#### ＜2 step実行＞
アナライズ後に-Rオプションを付けてエラボレーションを行い、その後xsimが即時に自動で実行される。規模の小さいデザイン等をちょっとお試しで実行してログを確かめるだけならこれが一番簡単でお手軽。
```shell
% xvlog --sv <SystemVerilog Files>
% xelab tb_top -R
```

#### ＜3 Step実行＞
xsimに何かしらのオプションを付けて実行する場合に、エラボレーションの後にxsimを明示的に実行する。その際に--runallオプションを付けてSimulationを自動で最後まで実行させる。
```shell
% xvlog --sv <SystemVerilog Files>
% xelab tb_top
% xsim tb_top --runall <Option> 
```

#### ＜Standalone実行＞
上の3 stepでの実行に似ているが、Simulationの実行にxsimを使うのではなく、事前に生成したスタンドアローンの実行ファイルを使う。xsimのライセンスチェックは不要なので高速。Sim実行速度自体もxsimを使う場合より高速。その代わりデバッグオプションとかが付けられない。なのでデバッグ方法はログでの確認のみ。上記の3 step実行をやるぐらいならstandaloneでやった方が良い。このstandaloneの方法はあまり説明されていないのだが、絶対におススメする。
xelab実行時にシェルスクリプトの./axsim.shが自動で生成されるのでそれを実行すれば良い。オプションも受け付ける。中身は生成された実行ファイル./xsim.dir/work.tb_tp/axsimをたたいているだけ。なのでそれを直接実行しても良い。
```shell
% xvlog --sv <SystemVerilog Files>
% xelab tb_top --standalone
% ./axsim.sh <Option>
Or
% ./xsim.dir/work.tb_tp/axsim <Option>
```

### ■ GUI実行
上の3 step実行のエラボレーションの際に--debug all/typical/waveのいずれかを付ける。特にこだわりなければallで良い。その後、xsimの際に--guiを付けてGUIを立ち上げる。シミュレーションの実行はGUI上のTCLコマンドラインからrun allを実行するか、三角のボタンを押して実行。或いはF3ボタンを押す。信号の波形表示はあらかじめ信号をWaveform Windowにドラッグ&ドロップしてからシミュレーションを実行。シミュレーションを最初からやり直す場合にはRestartボタンを押して再度Run。
```shell
% xvlog --sv <SystemVerilog Files>
% xelab tb_top --debug all <Option>
% xsim tb_top --gui <Option> & 
```
GUIの操作の仕方は以下とか参照。

https://qiita.com/mmitti/items/633900ad1d0c1673f413#%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95

### ■ 波形ダンプと表示
#### ＜波形データダンプ＞
GUI実行と同様に、Batchでの3 step実行のエラボレーションの際に--debug all/typical/waveのいずれかを付ける。特にこだわりなければallで良い。その後xsimで実行する際にTCLファイルの指定と、ダンプする波形ファイルの指定を行う。
```sh
% xvlog --sv <SystemVerilog Files>
% xelab tb_top --debug all
% xsim tb_top --tclbatch dump_all.tcl --wdb all.wdb <Option> 
```
TCLファイルにはダンプする信号の指定とrun allとquitを実行するように記述。以下の例では全ての信号をダンプするように指定。
```tcl:dump_all.tcl
log_wave -r *
run all
quit
```
詳細は[Tcl コマンド log_wave の使用](https://docs.amd.com/r/ja-JP/ug900-vivado-logic-simulation/Tcl-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-log_wave-%E3%81%AE%E4%BD%BF%E7%94%A8)を参考。
逆に言うと、Batch実行で波形ダンプするには、この様にTCLファイルを作ってlog_waveでやる必要がある。そのような事をやってくれるコマンド実行のオプションは用意されていないみたい。

#### ＜波形データ表示＞
*.wdbとしてダンプされた波形データは以下の様にして読み込んでGUI表示する。
```shell
% xsim all.wdb --gui <Option> & 
```
ダンプが再実行された場合には立ち上げ直す必要はなく、TCLコマンドラインで上矢印キーを押してダンプデータの読み込みコマンドを再実行すればよい。信号のWavewindown表示も上矢印で再度実行できる。

#### ＜VCDフォーマットで波形ダンプ＞
VCDフォーマットで波形をダンプする事も出来る。その場合は以下の様なTCLファイルを作ってそれを実行する。
```tcl:dump_vcd.tcl
open_vcd
log_vcd  *
run all
close_vcd
quit
```

```sh
% xsim tb_top --tclbatch dump_vcd.tcl <Option> 
```

詳細は[VCD 機能の使用](https://docs.amd.com/r/ja-JP/ug900-vivado-logic-simulation/VCD-%E6%A9%9F%E8%83%BD%E3%81%AE%E4%BD%BF%E7%94%A8)を参考。

VCDファイルは[GTKWave](https://gtkwave.sourceforge.net/)等フリーのツールを使って波形表示できる。

```sh
% gtkwave dump.vcd 
```


### ■ Makefileの例
以上を踏まえて以下の様なMakefileを作ると良いだろう。
ワークディレクトリは何も指定しなければ./xsim.dirと言うのが作られ、そこにいろいろとコンパイルやエラボレーションのファイルが作られる。
スタンドアローン実行用エラボレーションデータとGUIおよびダンプ実行用のエラボレーション用のディレクトリは-snapshotのオプション指定で./xsim.dir/aloneおよび./xsim.dir/debugと言うそれぞれと別のディレクトリを作るようにしてある。Sim実行時にはそれぞれのスナップショット名を指定して実行する。-snapshotを指定しないとデフォルトではトップのモジュール名のtb_topがスナップショット名となる。エラボレーションデータ本体はそれぞれのエラボレーションディレクトリ内にaxsimおよびxsimkというファイル名で作られる。
また、生成したファイルやディレクトリを削除するcleanやxvlog,xelab,xsimの使い方やオプションの説明を表示をするhelpの各コマンドも作ってある。

```makefile:Makefile
#-------------- Config ------------------------
ifdef XILINX_VIVADO
 XVLOG := xvlog
 XELAB := xelab
 XSIM  := xsim
else
 VIVADO_DIR  := /tools/Xilinx/Vivado
 VIVADO_HOME := $(shell ls -td1 $(VIVADO_DIR)/* | head -n 1)
 XVLOG := $(VIVADO_HOME)/bin/xvlog
 XELAB := $(VIVADO_HOME)/bin/xelab
 XSIM  := $(VIVADO_HOME)/bin/xsim
endif

SRC_DIR   := .
SRC_FILES := $(shell ls $(SRC_DIR)/*.sv)

TOP := tb_top
#---------------------------------------------

#------------ Commands -----------------------
run   : alone
once  :
	$(XVLOG) -sv $(SRC_FILES)
	$(XELAB) $(TOP) -R
alone : ./xsim.dir/alone/axsim
	./axsim.sh
gui   : ./xsim.dir/debug/xsimk
	$(XSIM) debug -gui &
dumpwave : ./dump_all.tcl ./xsim.dir/debug/xsimk
	$(XSIM) debug -t $< -wdb all.wdb
viewwave : all.wdb
	$(XSIM) $^ -gui &
dumpvcd  : ./dump_vcd.tcl ./xsim.dir/debug/xsimk
	$(XSIM) debug -t $<
gtkwave  : dump.vcd
    gtkwave $^ &

help  : ./help.txt
    gview $<
    cat   $<

clean :
	rm -rf *.log *.jou *.pb xsim.dir *.sh *.wdb .Xil dump_*.tcl
#---------------------------------------------

#------------ Files --------------------------
./xsim.dir/alone/axsim : $(SRC_FILES)
	$(XVLOG) -sv $^
	$(XELAB) $(TOP) -snapshot alone -standalone

./xsim.dir/debug/xsimk : $(SRC_FILES)
	$(XVLOG) -sv $^
	$(XELAB) $(TOP) -snapshot debug -debug all  

./dump_all.tcl :
	@echo 'log_wave -r *'  > $@
	@echo 'run all'       >> $@
	@echo 'quit'          >> $@

./dump_vcd.tcl :
	@echo 'open_vcd'    > $@
	@echo 'log_vcd  *' >> $@
	@echo 'run all'    >> $@
	@echo 'close_vcd'  >> $@
	@echo 'quit'       >> $@

./help.txt :
	$(XVLOG) --help >  $@
	$(XELAB) --help >> $@
	$(XSIM)  --help >> $@
#---------------------------------------------
```

```shell:使用例
% make run
% make gui
% make dumpwave viewwave
% make dumpvcd gtkwave
```

### ■ 参考リンク
***

https://docs.amd.com/r/ja-JP/ug900-vivado-logic-simulation/%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%89%E3%82%A2%E3%83%AD%E3%83%B3-%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7%E3%81%AE-Vivado-%E3%82%B7%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%AE%E5%AE%9F%E8%A1%8C%E4%BE%8B

本家AMD(Xilinx)の日本語サポートページのプロジェクトを使用しない手順（スタンドアローンモード）の説明。
***

https://fpga.kice.tokyo/fpga/vivado-simulator

Vivado Simulatorのコマンド実行について軽く説明。
***

https://blog.n-hassy.info/2021/08/verilog-simulation-debug/

Vivado Simulatorのコマンドライン実行とGUI実行によるデバッグの方法について説明している。波形ダンプによるデバッグ方法に関しては特に言及無し。
***

http://www.arch.cs.kumamoto-u.ac.jp/~kuga/cad/exp/sys/2020/vga/all_test.html

波形ダンプについて言及有り。この例ではVCDファイルにダンプしてる。
***