QspiceでVerilog使ってアナデジ混在シミュレーション

## Qspice
LTspiceを開発したこのオジサン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/85d845c8-8ae5-af3e-4cfc-6bdae5c6b8a5.png)

https://www.qorvo.com/design-hub/videos/introduction-of-qspice-simulation-tool

業界では有名人らしいけど、この人がLTspice辞めて[Qspice](https://www.qorvo.com/design-hub/design-tools/interactive/qspice)なる新しいシミュレータを作ったらしいので試してみた。

今回はC++とVerilogをシンボルとして定義できるのが新しい。
Spice系のシミュレータはビヘイビアモデルやデジタル回路との親和性が低かったけど、Qspiceは制御アルゴリズムやアナデジ混在のシミュレーションが容易にできるようになりそう。

こちらが外観
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/16766c04-ecb7-2f39-b7ec-8316c32e8f88.png)

## VerilogシミュレーションはVerilatorのエンジンを使用
[Verilator](https://www.veripool.org/verilator/)はVerilogファイルを一旦マルチスレッドのC++に変換、コンパイルしてDLL化してシミュレーションするので、2つのシミュレータで連携するコシミュレーションなんかと比べて高速に動作するらしい。

Verilator自体はVerilog-A/AMSのサブセットも対応していますが、コンパイルオプションが必要で、Qspiceでは対応していませんでした。Verilatorの詳細は対応言語使用は[こちら](https://veripool.org/guide/latest/languages.html)。

## Verilog取り込み手順
早速だがVerilogを取り込んでシミュレーションしてみたので、その手順を説明する。

1. Schematicファイル上で右クリックして、メニューから「Draw Hierarchical Entry」を選択。左ドラッグすると灰色のボックスができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/583fb4ba-87b0-ab96-3bb3-581e2b9624cc.png)

2. 灰色のボックスを右クリックして「Show Symbol Property」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/c8b1b6f7-45bc-16f1-093e-c4cebfa4a294.png)

3. 右上にプロパティが現れるので、Symbol TypeをØ(.dll)に設定。1st attribute（シンボル名X1の下に表示されている名前）をVerilogモジュール名と合わせる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/eb488cf9-6c87-babf-8686-b0bc7e258933.png)

4. 右クリックして、「Add Port」から入出力ポートを追加して、「Port Type」（入出力の極性）、「Data Type」（データ型）を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/a41e1db1-6743-f779-baf9-1c9716e37847.png)

5. シンボル設定が終わったら、右クリックメニュー「Verilog Interface」⇒ 「Create C++ .DLL Main Template」を選択。C++のインターフェイスファイルが自動生成されるが、これは一切触らなくて良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/3e62e72b-97b1-8f38-e382-f1332ca7f750.png)

6. 続いて同メニューから「Create Verilog Template」を選択。「Open Verilog Source」から既存ファイルを指定しても良いが、Schematic、C++、Verilogの整合性を担保するために、新規作成して既存ファイルからコピペしたほうが良いと思った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/71312b85-6cdb-0f48-8654-c47c3193676c.png)

7. テンプレートにVerilogコードをコピペしたら右クリックでコンパイル（メニュー「Compile Verilog to C++」）する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/fe4564f6-824a-9ce9-e961-1eeaca08991f.png)

8. これでシンボルの設定は終了。あとは入出力の設定だが、デジタル回路にはクロックを入力する必要があるので、Voltage SourceにPulse信号の設定をしてクロック入力とした。あとはデジタル回路の出力にアナログ回路も追加して完成。
細かい説明は割愛するが、OPAmpを使ったローパスフィルタを追加した。
デジタル回路でSin波生成⇒アナログ回路でローパスフィルタという構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/cd1c871a-1796-53d6-8b70-3ad98b9a2cef.png)

9. シミュレーション実行結果
下段から、クロック信号、Sin波生成デジタル回路の周波数入力値、OPAmpの入力、OPAmpの出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/0598ed49-ea28-2312-f7f5-d10908807273.png)


## 所感
プラス
* すごく手軽かつフリーツールでアナデジ混在シミュレーションができるのは良い
* Verilog Interfaceブロックの設定は簡単だし、コンパイルやシミュレーションも軽い
* VerilogのエンジンVerilatorは実績があり信頼性高そうなのも良い
* C++も扱えるので回路におけるビヘイビアモデルを作成するのは簡単になりそう
* 階層化されたVerilogファイルに対応しており、同じパスにファイルを置いておけば自動的に読み込んでコンパイルしてくれる

　
マイナス
* データ型の設定で固定小数点データが扱えないので、例えば16bitデータなんかは0-65535の数値として出力され、アナログ回路との間に何かしら補正回路を入れる必要があった（今回の回路のVoltage Sourceがそれ）
* Bit Vector（任意のビット幅のデータ）で符号付きデータが扱えない。符号付き12bitとかよくあると思うが、それはビット幅拡張してshort(16bit)データとして扱う必要がありそう。今回はVerilog側で符号付き32bitにしてinteger(32bit)にして出力した

## 注意点
* データ型、特にBit Rangeを変更すると、ビット幅がおかしくなるバグがあるようなので、変更するときはポートを一度削除して、C++インターフェイスから作り直したほうが良さそう。
* VerilogはCase sensitiveなのだが、自動生成のC++インターフェイスは全て小文字で記述される。Verilogポートは全部小文字で記述するか、自動生成C++インターフェイスコードを修正するかどちらかの必要がある。

## その他
* なお、Verilog Interfaceに食わせるVerilogコードはMathWorks社のツールを使って自動生成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477651/46c5e54f-9736-2c4a-4da1-d038a49e0471.png)


おわり