FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

XMLとStemsを使ってVerilatorのRTLシミュレーション結果をGtkWaveでアノテーション表示する方法

VerilatorはVerilogコンパイルしてシミュレーションするためのツールだが、波形ログとしてはVCDやFSTなどを出力することができる。VCDはかなり昔から使われている波形保存のためのフォーマット、FSTはVCDと違って圧縮されたより高速アクセスを実現するためのフォーマットだ。

  • VCD : Value Change Dump
    • 波形ファイル。バイナリ圧縮されていないので中身を目視で読むことができる。
  • FST
    • Fast Signal Trace. バイナリ圧縮された波形フォーマット形式。

これに加えて、VerilatorはXMLファイルを出力することができる。XMLファイルにはVerilogの階層構造などの情報が格納されており、Verilogファイルの解析結果などがXML形式で出力される。

$ verilator --version
Verilator 4.008 2018-12-01 rev UNKNOWN_REV
$ verilator --help
        --x-initial-edge            Enable initial X->0 and X->1 edge triggers
        --xml-only                  Create XML parser output
         -y <dir>                   Directory to search for modules

これを使えば、GtkWaveにて波形を表示する際にVerilogファイルとの関係を表示しつつ、現在の信号の値をVerilogファイルにアノテーションしながら表示することができるようだ。やり方を調査してみよう。

  • 使用するVerilator : 4.008 2018-12-01 (後述するが Verilator Version 3系 (3.924 2018-06-12)とはXMLのフォーマットが違うので注意)
  • 使用するGtkWave : v3.3.103

今回は、TileLinkの単体テスト用に使っている環境を使用する。

f:id:msyksphinz:20200107233825p:plain
XMLとStemsを使ったRTLアノテーションのフロー

VerilatorでVerilogの階層構造をXMLで出力する

上記の通り、XML形式のVerilogファイルの階層構造情報を出力したい場合、Verilatorのコンパイルオプションに--xml-onlyを付け加える。

  • Makefile
tilelink-xml: TestHarness.sv verilator_bin
        mkdir -p $(generated_dir_debug)/$(long_name)
        $(VERILATOR) $(VERILATOR_FLAGS) --xml-only -Mdir $(generated_dir_debug)/$(long_name) \
        -o $(abspath $(sim_dir))/$@ $(verilog) $(cppfiles) -LDFLAGS "$(LDFLAGS)" \
        -CFLAGS "-I$(generated_dir_debug) -include $(model_header_debug)"

これでVerilatorによるコンパイル時にXMLファイルが生成される。今回のテスト環境ではgenerated-src-debug/freechips.rocketchip.unittest.TLManyMasterManySlaveTestConfig/VTestHarness.xmlが生成された。

  • generated-src-debug/freechips.rocketchip.unittest.TLManyMasterManySlaveTestConfig/VTestHarness.xml
<?xml version="1.0" ?>
<!-- DESCRIPTION: Verilator output: XML representation of netlist -->
<verilator_xml>
  <files>
    <file id="e" filename="/home/msyksphinz/work/riscv/chisel-development/chisel-hw/TestHarness.sv" language="1800-2017"/>
      ...
  <cells>
    <cell fl="e21582" name="TestHarness" submodname="TestHarness" hier="TestHarness">
      <cell fl="e21590" name="UnitTestSuite" submodname="UnitTestSuite" hier="TestHarness.UnitTestSuite">
        <cell fl="e21517" name="tests_0" submodname="TLOriginalRAMSimpleTest" hier="TestHarness.UnitTestSuite.tests_0">
          <cell fl="e21442" name="SimpleTimer" submodname="SimpleTimer" hier="TestHarness.UnitTestSuite.tests_0.SimpleTimer"/>
...

xml2stemsでstemsファイルに変換する

次にstemsファイルというものを生成する。stemsファイルはGtkWaveでアノテーションを行うためのファイルで、これはXMLファイルから生成する必要がある。これにはxml2stemsというGtkWaveに付属のコマンドを使用するのだが、このコマンドが曲者で、Verilator 4.x系の生成するXMLファイルに対応していない。Verilator 3.x系を使えば問題ないと思うのだが、どうも<module ...>内に指定される要素の数の違いによりxml2stemsが正しくファイルを生成できない様子だった。

とりあえず、GtkWave 3.3.103内のcontrib/xml2stems/xml2stems.ccを改造することで事なきを得た。

diff contrib/xml2stems/xml2stems.cc contrib/xml2stems/xml2stems.cc.orig
76c76
<                                                       if(numqt == 8) break;
---
>                                                       if(numqt == 6) break;
81c81
<                                       if(numqt == 8)
---
>                                       if(numqt == 6)
85c85
<                                                       numqt = 6;
---
>                                                       numqt = 4;
90c90
<                                       if(numqt == 6)
---
>                                       if(numqt == 4)

要するにXMLファイルの要素数が違うのでエラーが発生していたのだが、正直xml2stemsの実装も目に余るひどさなので、XMLファイルを解析するためのライブラリなどを使って書き直したいところだ。

という訳でxml2stemsを使ってgenerated-src-debug/freechips.rocketchip.unittest.TLManyMasterManySlaveTestConfig/VTestHarness.xmlをstemsに変換すると以下のようになる。

xml2stems -V generated-src-debug/freechips.rocketchip.unittest.TLManyMasterManySlaveTestConfig/VTestHarness.xml VTestHarness.stems
  • VTestHarness.stems
++ module TestHarness file /home/msyksphinz/work/riscv/chisel-development/chisel-hw/TestHarness.sv lines 20192 - 20192
++ module TOP file (VerilatorTop) lines 1 - 1
++ comp TestHarness type TestHarness parent TOP
++ comp UnitTestSuite type UnitTestSuite parent TestHarness
++ module UnitTestSuite file /home/msyksphinz/work/riscv/chisel-development/chisel-hw/TestHarness.sv lines 20111 - 20111
++ comp tests_0 type TLManyMasterManySlaveTest parent UnitTestSuite
++ module TLManyMasterManySlaveTest file /home/msyksphinz/work/riscv/chisel-development/chisel-hw/TestHarness.sv lines 20034 - 20034
++ comp SimpleTimer type SimpleTimer parent TLManyMasterManySlaveTest
++ comp lazy_dut type TLManyMasterManySlave parent TLManyMasterManySlaveTest
++ module SimpleTimer file /home/msyksphinz/work/riscv/chisel-development/chisel-hw/TestHarness.sv lines 1 - 1
...

これで必要なファイルはすべて整った。Verilatorでシミュレーションを実行してFSTファイルを生成し、GtkWaveで確認してみよう。

gtkwave -t VTestHarness.stems simx.fst
f:id:msyksphinz:20200107233903p:plain
XMLとStemsを使ったRTLアノテーションの様子。rtlbrowseを使ってRTLとの一致を確認できる。

上手く行ったようだ。これでデバッグをより捗らせることができる。