SiteTop - IcurusVerilog - InvalidVCD

シミュレーション時に正しくVCD-Dumpされない信号の対策

見えない信号

IcarusVerilogに限らず、Verilogシミュレーションでは多くの場合、 $dumpfile, $dumpvarsコマンドを用いて信号の波形をとることになると思う。
$dumpvarsコマンドで生成したVCDファイルは、GTKWaveやIVIなどので見られるわけだが、 IcarusVerilogで出力したVCDファイルは時々おかしいことがある。
Verilog記述のどこにも間違いがなく、IcarusVerilogの実行手順も間違いが無いはずなのに、 いくつかの信号の値が0に固定されてしまっている。
また、0固定と表示された信号を入力しているモジュールが正常に動作していることから、 おかしいのはVCDファイルの内容だけのようである。
いろいろ比較した結論として、次のように考えられる。
1本のレジスタ(reg)を複数のwireとして参照していると、IcarusVerilogがサボって その中のひとつしかダンプ結果を書き出さない。
この仮説に従うと、症状を回避するには、全ての配線のダンプを出力するようにIcarusVerilogを設定するか、 観測したい信号の数を絞って、同じレジスタを2回観測しないようにするしかないと考えられる。
ところが、IcarusVerilogのコマンドラインオプションを見る限り、ダンプの詳細を指定するオプションは無いように思われる。

ダンプ対象を絞る

$dumpvars()は、ダンプ対象として、

の中から一つないし複数をとる。何も指定しないと、呼び出したmoduleとそのサブモジュール上にある 全てのwire, regをダンプすることになる。
したがって、安易に引数なしで実行・サブモジュールを指定して実行などをした場合、正しくDumpされない可能性が高くなる。
とは言っても、いちいち見たい信号をベタ書きしていたら手間がかかってしまう。
そこで、中身のないモジュールを作成し、観測したい信号を全てそこに入力すればよいと考える。

中身のないモジュールを手書きするのも面倒なので、wire, reg型の信号を抽出してモジュールを作成するツールを作成した。 実行には、Perlが必要である。実行すると、SpyUnitというモジュールの定義とインスタンス宣言文が 作成されるので、モジュール定義を適当な場所に配置し、インスタンス宣言をコピーペーストしてやればよい。 後は、$dumpvars(0, spyunit1)で信号が観測できる。生成されたspyUnitをカスタマイズすることで、被観測信号をさらに限定することができる。