DSimをコマンドラインから使ってみよう

## はじめに

ちょっと奥さん、聞いてくださる？ 最近[^recently]、SystemVerilogのシミュレーションが全部無料でできちゃうDSimってのが話題なんですってよ。ほら、見てよこの記事[^eda]。

[^eda]: [EDA EXPRESS - デスクトップ利用は無料、大手製品に匹敵する論理シミュレータDSimを手掛けるMetrixのビジネスとは？](https://eda-express.com/news/16425/)

![Screenshot 2024-12-28 194847.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/23d6318d-6804-1436-fea3-501780339a72.png)

> 驚くべきは、この「DSim」はデスクトップ利用は無料でライセンス費用がかからない。「VSCode IDE」に組み込まれており、誰でも容易にセットアップ可能で（Metrix曰く10分以内にシミュレーション可能）、無料ツールにありがちな利用期限やコード量などの制限は一切なく普通に利用できる。

……ってことでね、ええ、今日はこのDSimとやらを試していこうと思います。
グッバイ、[Questa*-Intel® FPGA Starter Edition](https://www.intel.com/content/www/us/en/software/programmable/quartus-prime/questa-edition.html)！元気でな！

[^recently]: Twitterの某界隈でDSimの話題が出始めたのは、[もう半年以上前](https://x.com/taichi600730/status/1788228372910505988)だって？そんなバカな……

## DSimのインストール
下記をページを参考に、VS Code経由でDSimをインストールします。

- [Altair - Install DSim Desktop](https://help.metrics.ca/support/solutions/articles/154000141162-install-dsim-desktop)
- [ハードウェアの気になるあれこれ - DSimに入門してみた（１）](https://tech-diningyo.hatenablog.com/entry/2024/06/19/115200)

Windowsを使っている場合、インストール先は `C:\Users\ユーザー名\AppData\Local\metrics-ca\dsim` になり、ランセンスファイルは `C:\Users\ユーザー名\AppData\Local\metrics-ca\dsim-license.json` に置かれます。

![Screenshot 2024-12-28 121236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/4ee8bfbd-5e9d-f4f9-63e2-747f310a46b7.png)

## 環境変数の設定

DSimのインストール時、`DSIM_LICENSE`や`DSIM_HOME`、`PATH`などの環境変数は自動で設定されません。したがって、シミュレーションを始める前に、これらの環境変数をあらかじめ設定しておく必要があります。DSimのインストール先には、そのためのPowerShellスクリプトやBATファイルが用意されています。

![Screenshot 2024-12-28 122348.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/b9ee596f-755d-b46d-f43f-45a2d3e0fa41.png)

上記の`shell_activate.bat`を利用して環境変数を設定しつつ、シミュレーションを実行するようなスクリプトを書くと、こんなかんじ。

```dosbatch:run.bat
@echo off
set "DSIM_LICENSE=%USERPROFILE%\AppData\Local\metrics-ca\dsim-license.json"
cd "%USERPROFILE%\AppData\Local\metrics-ca\dsim\20240923.7.0"
call shell_activate.bat
cd %~dp0
dsim test.sv +acc -waves waves.vcd
pause
exit
```

`*.mxd`というDSim独自の形式で波形ファイルを出力することもできますが、DSimの波形ビューワーは、現時点ではまだ、real型の変数の表示に対応していないようです。そのため、波形ファイルの出力は`*.vcd`にしておき、[GTKWave](http://gtkwave.sourceforge.net/)を使って波形を確認することにします。

## 簡単なテストベンチの作成と実行
DSimの動作確認のために、Clockがトグルするだけの簡単なテストベンチを作って、

```verilog:test.sv
module test;
  timeunit 1ns;
  timeprecision 1ps;

  bit clk = 1'b0;

  initial begin
    forever begin
      #1ns;
      clk = ~clk;
    end
  end

  initial begin
    $monitor("clk = %0b", clk);
    #5ns;
    $finish();
  end
  
endmodule
```

先ほど用意した`run.bat`でシミュレーションを実行すると、実際に期待通りに動作していることが確認できます。[GTKWave](http://gtkwave.sourceforge.net/)を使って、出力されたVCDファイルを開くと波形も見れます。これでついに、「趣味でSystemVerilogのフル機能が使える環境」ゲットだぜ！[^pika]

[^pika]: [ピッピカチュー！](https://www.youtube.com/watch?v=soM4HD71b6k)

![Screenshot 2024-12-28 131124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/668625e4-faaa-075d-0228-cd9e1402a912.png)

![Screenshot 2024-12-28 131836.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/66e41246-506d-12c4-7244-46206475e891.png)

## おまけ：UVMは使えるの？

なんとおどろき、追加ライセンスなしで、普通に使えちゃうのぜ！

- [vega77 - UVMのお気軽導入](https://qiita.com/vega77/items/0393ba588de26bc805ae)
- [ds54e - Flip-Flopでお手軽UVM](https://qiita.com/ds54e/items/82ed3068505a17064f05)
- [Altair - How To: Use UVM in DSim](https://help.metrics.ca/support/solutions/articles/154000154925-how-to-use-uvm-in-dsim)

```verilog:top.sv
package my_pkg;
  `include "uvm_macros.svh"
  import uvm_pkg::*;

  class simple_test extends uvm_test;
    `uvm_component_utils(simple_test)
    
    function new (string name="simple_test", uvm_component parent=null);
      super.new(name, parent);
    endfunction

    task run_phase (uvm_phase phase);
      phase.raise_objection(this);
      `uvm_info(get_type_name(), "Hello", UVM_MEDIUM)
      `uvm_info(get_type_name(), "World", UVM_MEDIUM)
      phase.drop_objection(this);
    endtask
  endclass
  
endpackage

module top;
  timeunit 1ns;
  timeprecision 1ps;

  import uvm_pkg::*;
  import my_pkg::*;

  initial begin
    run_test();
  end
  
endmodule
```

```dosbatch:run.bat
@echo off
set "DSIM_LICENSE=%USERPROFILE%\AppData\Local\metrics-ca\dsim-license.json"
cd "%USERPROFILE%\AppData\Local\metrics-ca\dsim\20240923.7.0"
call shell_activate.bat
cd %~dp0
dsim -suppress IneffectiveDynamicCast:MissingTimescale -uvm 1.2 +UVM_NO_RELNOTES +UVM_TESTNAME=simple_test top.sv 
pause
exit
```
![Screenshot 2024-12-28 184413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/dde62890-716d-26bb-cd7f-8802b5e27a9a.png)


## さらにおまけ：User-defined nettypeは使えるの？

これも使えました。すごい……[^udn1]
ついに無料でUDN[^udn2]で遊べる時代が来ましたね。
みんなも始めよう、DMS[^udn3]シミュレーション！

- [mizutomo - SystemVerilogで電気回路を解こう](https://qiita.com/mizutomo/items/a369ab5304788c111e4c)
- [Wataru Yamamoto - Real Number Modeling (RNM) 超・初級編](https://www.slideshare.net/slideshow/real-number-modeling-rnm/191888650)

[^udn1]: このUser-defined nettypeという機能、基本的にデジタルのシミュレーションでは使われないので、メジャーどころのシミュレーター（QuestaとかXceliumとか、そのへん） では追加ライセンスを要求されがち。それが無料で使えちゃうってこと。[しゅごおおおいのおおおほほおおおお](https://dic.pixiv.net/a/%E3%81%BF%E3%81%95%E3%81%8F%E3%82%89%E8%AA%9E)

[^udn2]: UDN = User-defined nettypeの略。うどん、じゃないよ、ゆーでぃーえぬだよ。ちなみに、UDR = User-defined resolution、UDT = User-defined typeです。

[^udn3]: DMS = Digital mixed-signalの略。AMS（Analog mixed-signal）simulationと対比するために、よくCadenceが使ってたりする単語。知らんけど。半導体業界、略語多すぎ問題。

```verilog:test.sv
package my_nettype_pkg;
  timeunit 1s;
  timeprecision 1ns;

  function automatic real real_sum_res (real driver[]);
    real total;
    foreach (driver[i]) begin
      total += driver[i];
    end
    return total;
  endfunction

  nettype real real_sum with real_sum_res;
  
endpackage

module test
  import my_nettype_pkg::real_sum;
();
  timeunit 1s;
  timeprecision 1ns;

  // Net
  real_sum i_out;

  // Variable
  real i1 = 0;
  real i2 = 0;

  // Drive i_out net with I1 and I2
  assign i_out = i1;
  assign i_out = i2;

  initial begin
    $monitor("(i1, i2, i_out) = (%4.1f, %4.1f, %4.1f)", i1, i2, i_out);
    repeat (10) begin
      #1ns;
      i1 = 1.0 - $urandom_range(0, 20)*0.1;
      i2 = 1.0 - $urandom_range(0, 20)*0.1;
    end
    #1ns
    $finish();
  end
  
endmodule
```

```dosbatch:run.bat
@echo off
set "DSIM_LICENSE=%USERPROFILE%\AppData\Local\metrics-ca\dsim-license.json"
cd "%USERPROFILE%\AppData\Local\metrics-ca\dsim\20240923.7.0"
call shell_activate.bat
cd %~dp0
dsim test.sv +acc -waves waves.vcd
pause
exit
```

![Screenshot 2024-12-28 175934.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/97458545-c671-8c32-2a51-f8b7fcfb5e85.png)


## おわりに

バタフライダンシング
半径1メーター
撹乱アイムインベーダー[^lun]

[^lun]: この記事は、[この動画](https://www.youtube.com/watch?v=rg_6PlYAzsk)をバックグラウンドで無限ループしながら執筆されました。