`includeで読み込むファイルをコンパイル時にdefineで指定

Verilog/SystemVerilogの``` `include ```で読み込むファイルをコンパイル時のdefine指定で変えられないかなぁと思っていろいろ調べたりやってみたのでメモとして残す。

# 1 ``` " " ```なしでファイルパスをそのままマクロに指定

```console
+define+FILE_PATH=../AAA/BBB/XXX.svh
```

## 1-a `includeの``` " " ```内に直接マクロを記述

```verilog
`include "`FILE_PATH"
```

まずこれはダメだった。``` `FLIE_PATH ```自体がそのまんま文字列として認識されるみたい。

## 1-b ``` " ```の前に``` ` ```を追加

https://sites.google.com/site/playsystemverilog/99-wei-fen-lei/macrono-zhongni-wo-maime-rumuniha

とか見ると``` " " ```内でマクロを展開するには``` " ```の前に``` ` ```を付ける必要があるみたい。

```verilog
`include `"`FILE_PATH`"
```

フリーのシミュレータ[DSim Desktop](https://www.metrics.ca/)や[Vivado Simulator (Xsim)](https://japan.xilinx.com/support/download/index.html/content/xilinx/ja/downloadNav/vivado-design-tools.html)ではこの方法でO.Kであったが、なんと商用シミュレータではダメだった。ふつう逆だろ！まあいいや。

## 1-c ``` " " ```を追加した別マクロを定義

```verilog
`define INC_STRING `"`FILE_PATH`"
`include `INC_STRING
```

``` `FILE_PATH ```に``` " " ```を追加したものを別マクロ``` `INC_STRING ```として新たに定義。それを``` `include ```で使う。
これだとDSimでもXsimでも商用シミュレータ達でもO.Kであった。しかし、某マイナー商用シミュレータではN.Gであった。

## 1-d ``` `STRINGIFY(x) ```マクロで文字列化

```verilog
`define STRINGIFY(x) `"x`"
`include `STRINGIFY(`FILE_PATH)
```

```""```を付加して任意の文字列化を行うマクロ``` `STRINGIFY(x)```を定義してそれを``` `FILE_PATH```に適用して``` `include```で使う。
これだと有名商用シミュレータたちおよびマイナー商用ならびにDSim, Xsim全てでO.Kであった。

# 2 ``` " " ```込みでファイルパスをマクロに定義

そもそも``` " " ```込みのマクロの``` `INC_STRING ```自体をシミュレータオプションの+defineで定義すれば良いのではないか。それを同様に`includeのパス指定に渡す。

```verilog
`include `INC_STRING
```

## 2-1 +defineでそのまま``` " ```を使う

```console
+define+INC_STRING="../AAA/BBB/XXX.svh"
```

これはN.G。``` " ```自体は無視されて``` " " ```の中身のみがマクロに定義されてしまう。

## 2-2 シングルクオーテーション(``` ' ```)で囲む

```console
+define+INC_STRING='"../AAA/BBB/XXX.svh"'
```

これならO.K。
以下を参考記事。

https://community.cadence.com/cadence_technology_forums/f/functional-verification/42230/macro-in-include-compiler-directive

## 2-3 ``` " ```を``` \ ```でエスケープ

```console
+define+INC_STRING=\"../AAA/BBB/XXX.svh\"
```

これでもO.Kだった。
以下を参考記事。

https://stackoverflow.com/questions/62589055/attempting-to-change-include-statement-at-compile-time-run-time-for-verilog-code

# 実行環境例

以上を踏まえて、以下に(dsimでの)実行環境例を示す。
シミュレータオプションの+defineで``` `FILE_PATH ```と``` `INC_STRING ```のどちらでも指定できるよう両対応にした。

```verilog:tb.sv
`ifdef FILE_PATH
    `define INC_STRING `"`FILE_PATH`"
`endif

`STRINGIFY(x) `"x`"

module tb;

//`include "./inc.svh"

  initial  begin
`ifdef FILE_PATH
  //`include "`FILE_PATH"    // N.G
  //`include `"`FILE_PATH`"  // O.K or N.G
  //`include "``FILE_PATH``"  // O.K or N.G
  //`include `INC_STRING
    `include `STRINGIFY(`FILE_PATH)
`elsif INC_STRING
    `include `INC_STRING
`else
    $display("FILE_PATH nor INC_STRING is not defined.");
`endif

    $finish();
  end

endmodule
```

```verilog:./inc.svh
    $display("Hello World!!!");
```

```makefile:Makefile
SIM := dsim

path :
	$(SIM) tb.sv +define+FILE_PATH=./inc.svh

#str : # N.G 
#	$(SIM) tb.sv +define+INC_STRING="./inc.svh"

str1 : 
	$(SIM) tb.sv +define+INC_STRING='"./inc.svh"'

str2 : 
	d$(SIM) tb.sv +define+INC_STRING=\"./inc.svh\"

noinc :
	$(SIM) tb.sv
```

FILE_PATH指定で実行
``` > make path ```

INC_STRING指定で実行
``` > make str1 ```
or
``` > make str2 ```

includeなしで実行
``` > make noinc ```

又、以下EDA Playgroundへのリンク
[`include with macro](https://www.edaplayground.com/x/6w7u)


# 参考記事

https://sites.google.com/site/playsystemverilog/99-wei-fen-lei/macrono-zhongni-wo-maime-rumuniha

https://blog.csdn.net/ocarvb/article/details/137009942

https://stackoverflow.com/questions/15373113/how-to-create-a-string-from-a-pre-processor-macro?answertab=createdasc#tab-top

https://community.cadence.com/cadence_technology_forums/f/functional-verification/42230/macro-in-include-compiler-directive

https://stackoverflow.com/questions/62589055/attempting-to-change-include-statement-at-compile-time-run-time-for-verilog-code