Menu

Verilog $dumpfileと$dumpvars:VCD波形の生成

testbenchにVCD波形出力を追加する方法。$dumpfile$dumpvars、スコープ選択、そして結果ファイルをGTKWaveやブラウザエディタで表示する方法。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

本当に欲しい波形

$displayはテキストを出力します。クイックなsanityチェックには問題ないですが、タイミング問題のあるカウンタや、止まった状態機械をデバッグする瞬間、 が欲しくなります。電圧として時間に渡って描かれたsignal、スクロール可能、ズーム可能、任意の遷移にドロップできるカーソル付き。

その絵が VCDファイル です。「value change dump」、IEEEがオリジナルのVerilog仕様で標準化したテキストフォーマットです。すべてのモダンなシミュレータはこれを書け、すべてのモダンな波形ビューアは読めます。生成するコストはtestbench内の2行です。

2行

initialブロック内(通常刺激を持つ同じもの)に追加します:

$dumpfile("dump.vcd");
$dumpvars(0, test);
  • $dumpfile は出力ファイルに名前を付けます。任意のパスを渡してください。ディレクトリがなければシミュレータの作業ディレクトリに着地します。
  • $dumpvars(0, test) は「testスコープとすべてのサブスコープのすべてのsignalを、無制限の深さで、再帰的に記録する」と言います。

それがセットアップの全部です。シミュレーションを実行すると、GTKWaveまたはブラウザエディタのWaveformタブで開けるdump.vcdができます。

完全な例

実行してください。Waveformタブに3つのsignal(clkresetcount)が、シミュレーション全時間に渡って描かれます。任意の点にカーソルをドロップして、その時間のsignal値を読めます。1クロックサイクルを調査するためにドラッグズームできます。

$dumpvarsの最初の引数が何をするか

$dumpvars(depth, scope)scopeとそれが含むすべてのサブインスタンスを歩き、depthレベル深くまでsignalを記録します。depth値:

  • 0 - 無制限。scopeとすべてのネストされたサブmoduleのすべてのsignalが記録される。
  • 1 - scope内に直接宣言されたsignalのみ。サブmoduleは記録されない。
  • 2 - scopeプラス1レベルのサブmodule。
  • N - scopeプラスN-1レベルのサブmodule。

実際には、$dumpvars(0, test)がほぼすべてのtestbenchが使うものです。すべてを捕捉するのは安価(VCDは遷移だけを保存し、安定stateを保存しない)で、デバッグの途中で必要なsignalがダンプされていないことを発見したくありません。

非常に大きな設計があってVCDが大きすぎる場合、選択的にダンプできます:

$dumpvars(0, dut.inner_module);     // 興味深いサブmoduleだけ
$dumpvars(0, dut.regs);             // レジスタファイルだけ

$dumpvarsを複数回呼び出してスコープを蓄積できます。

特定のsignalをダンプ

$dumpvarsはスコープ全体ではなく特定のsignalのリストを取ることもできます:

$dumpvars(0, test.clk, test.reset, dut.count);

これは3つのsignalだけを記録します。設計が巨大で、ほんの一握りのsignalしか気にしないときに有用です。小さな設計では、すべてをダンプする方がシンプルです。

シミュレーション中のダンプ制御

$dumpvarsとペアになる2つのタスク:

  • $dumpoff - ダンプを一時停止。それ以上の変化はVCDに入らない。
  • $dumpon - ダンプを再開。
initial begin
    $dumpfile("dump.vcd");
    $dumpvars(0, test);

    // ... 興味深い領域 ...

    #1000 $dumpoff;
    // ... VCDに入れたくない長い退屈な領域 ...
    #5000 $dumpon;

    // ... 別の興味深い領域 ...
end

長いテストの「100万サイクル実行する」退屈な部分をスキップして、5GBのVCDファイルを生成しないようにする方法です。

結果を見る

主な方法は2つ:

ブラウザエディタで

このページのエディタはVCDをインラインでレンダリングします。シミュレーションを実行し、Waveformタブに切り替えると、signalが左側に階層付きで、右側にドラッグ可能なカーソル付きで現れます。トレースの任意の場所をクリックしてカーソルをドロップすると、その時間のsignal値がsignal名の横に小さなピルとして表示されます。

GTKWaveで

シミュレーションをローカルで実行した(iverilog -o sim test.vしてからvvp sim)場合、結果のVCDを開きます:

gtkwave dump.vcd

GTKWaveはファイルをロードし、左にスコープtreeを表示し、右の波形エリアにsignalをドラッグするのを待ちます。マルチビットsignalを右クリックして表示フォーマット(バイナリ、16進、10進、アナログ)を変更します。下部の検索ボックスを使って特定の時間やsignal遷移にジャンプします。

一般的なパターン

小さなtestbenchヘルパー

ほとんどのtestbenchファイルはこの正確なブロックで始まります。すべてを1つのinitialにまとめて短く保てます:

initial begin
    $dumpfile("dump.vcd");
    $dumpvars(0, test);

    // ... 刺激 ...

    $finish;
end

条件付きダンプ

失敗テストのみVCD出力が欲しいテスト環境で:

initial begin
    if (DUMP_VCD) begin
        $dumpfile("dump.vcd");
        $dumpvars(0, test);
    end
    // ... 刺激 ...
end

DUMP_VCDはコマンドラインから設定するか、テストモードに応じて定義するparameterです。リグレッションスイートでディスク容量を節約します。

メモリダンプ

メモリ(unpacked配列)はデフォルトでは$dumpvarsによってダンプされません。巨大になりうるからです。欲しい場合は明示的に$dumpvars(0, dut.memory)を使うか、一部のシミュレータでは$dumpmemを使ってください。

よくある間違い

空のVCDファイル。 $dumpfileまたは$dumpvarsを忘れたか、signalが変わる前にシミュレーションが$finishを呼びました。セットアップ後少なくとも数時間単位は実行してください。

波形にsignalが見当たらない。 渡したスコープがそれらを含みませんでした。$dumpvars(0, dut)dut内のものだけを記録します。testbenchがtestレベルでsignalを駆動しているなら、それらは現れません。常にtestbenchスコープからダンプしてください:$dumpvars(0, test)

VCDファイルが巨大。 急速に変化する幅広いsignalを持つ長いシミュレーションは多くのVCD行を生成します。3つの修正:より狭いスコープをダンプする、退屈な部分の周りで$dumpoff/$dumponを使う、FST(iverilogとGTKWaveの両方が-fstフラグでサポート)のようなよりコンパクトなフォーマットに切り替える。

次に読むもの

この章の最後のドキュメントTimescale and Delaysは、`timescaleディレクティブと#delayが実際に壁時計時間にどうマップされるかを説明します。それが終わると、ドキュメントを最初から最後まで完了したことになります。

よくある質問

VerilogのVCDファイルとは?

VCDはValue Change Dumpの略で、シミュレーション中のすべてのsignal遷移を記録するテキストフォーマットです。シミュレータは時刻0で各signalの初期値を書き込み、その後すべての変化をタイムスタンプ付きで書き込みます。GTKWaveのような波形ビューアがファイルを読み、スクロール・ズーム可能なグラフィカルタイミング図としてレンダリングします。

VerilogでVCDファイルを生成するには?

testbenchのinitialブロック内に2つのシステムタスクを追加します。$dumpfile("dump.vcd");は出力ファイルに名前を付け、$dumpvars(0, top_module);top_module以下のすべてのsignalを記録します。シミュレーション終了後に、任意の波形ビューアで開けるdump.vcdファイルができます。

Verilogの$dumpvars(0, ...)の意味は?

$dumpvars(depth, instance)instanceから開始し、depthレベル深く再帰しsignalを記録します。$dumpvars(0, test)は「testスコープとすべてのサブスコープのすべてのsignalを再帰的に」を意味します。深さ0は特別で、無制限を意味します。$dumpvars(1, test)test内のsignalだけを記録し、インスタンス化されたサブmoduleは記録しません。

VerilogのVCDファイルが空になるのはなぜ?

3つの可能性のある原因:$dumpfile/$dumpvarsをまったく呼ばなかった。signalが変わる前にシミュレーションが$finishに当たった(dump呼び出し後少なくとも数時間単位は実行してください)。$dumpvarsに渡したスコープが実際の階層と一致しない。動作する最小シーケンスは$dumpfile("dump.vcd"); $dumpvars(0, test); #10; $finish;です。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める