Verilator の導入(C++モード) の変更点

更新


[[公開メモ]]

#contents

* Verilator [#g0a2ffa0]

(2010-10-30) ようやく Verilator の本質が分かってきたので、記述を見直しました。

marsee さんからの情報で Verilator というフリーのツールを知ったので、
自分のノート PC の cygwin 環境に導入して、使ってみました。

Verilator は verilog で書かれた「論理合成可能な」モジュールを
C++ / SystemC / SystemPerl のいずれかに変換するためのツールです。

変換した後のコードは g++ でコンパイルした後、
テストベンチコードとリンクしてシミュレーションに用いることができます。
verilator はコンパイル用の makefile も自動生成してくれるので、
とても便利に使えます。

ここでは verilog コードを C++ に変換し、シミュレーションしてみました。

結論としては、生の C++ でシミュレーションするのはあまりに面倒なので、
ちゃんと SystemC を勉強しないとだめそうです?

続きとして [[電気回路/HDL/SystemC の導入]] を書きました。

* 情報源 [#xfaf629a]

http://lexim.co.jp/verilator.html

http://wiki.sweetcafe.jp/doku.php?id=systemc:verilator

http://www.veripool.org/projects/verilator/wiki/Manual-verilator

http://www.embecosm.com/appnotes/ean6/embecosm-or1k-verilator-tutorial-ean6-issue-1.pdf

* cygwin 環境の整備 [#e5fc5188]

- gcc-core
- g++
- perl
- flex
- bison
- make

を入れておく必要がありました。

ちゃんと使うには SystemC や SystemPerl も入れないといけないのですが、
今回は C++ への変換のみをテストするということで、省いています。

* ダウンロード&インストール [#j2a3b457]

(2011/06/04 追記)~
下記では VERILATOR_ROOT だけ設定して ./configure していますが、
SystemC や SystemPerl をインストールし、
以下の環境変数を設定してからインストールすることで、
構築済みの verilator を使う際にこれらの環境変数を毎回指定しなくても
良くなるようです。

また、make test したときのテスト項目も増えているようでした。

 SYSTEMC            = ~/systemc/systemc-2.2.0/
 SYSTEMC_ARCH       = cygwin
 SYSTEMPERL         = /usr/lib/perl5/site_perl/5.10/i686-cygwin/SystemC/
 SYSTEMPERL_INCLUDE = ~/.cpan/build/SystemPerl-1.335-t4zlPN/src/
 VERILATOR_ROOT     = /home/osamu/verilator-3.812
 VERILATOR_ROOT     = ~/verilator-3.812

参考にして下さい。(SYSTEMC_ARCH は systemc コードのコンパイル時に TARGET_ARCH 
として渡されるのだと思います)
[[電気回路/HDL/SystemC の導入]]、[[電気回路/HDL/SystemPerl の導入]] 
についてはこれらのリンクをたどって下さい。

 LANG:console
 $ wget http://www.veripool.org/ftp/verilator-3.804.tgz
  => verilator-3.804.tgz
 $ tar fxz verilator-3.804.tgz
 $ ls 
  verilator-3.804/
 $ cd verilator-3.804/
 $ export VERILATOR_ROOT=`pwd`
 $ ./configure
  checking for gcc... gcc
  checking for C compiler default output file name... a.exe
  checking whether the C compiler works... yes
  checking whether we are cross compiling... no
  checking for suffix of executables... .exe
  checking for suffix of object files... o
  checking whether we are using the GNU C compiler... yes
  checking whether gcc accepts -g... yes
  checking for gcc option to accept ISO C89... none needed
  checking for g++... g++
  checking whether we are using the GNU C++ compiler... yes
  checking whether g++ accepts -g... yes
  checking for a BSD-compatible install... /usr/bin/install -c
  checking that C++ compiler can compile simple program... yes
  checking for perl... /usr/bin/perl
  checking for flex... /usr/bin/flex
  checking for bison... /usr/bin/bison
  checking how to run the C++ preprocessor... g++ -E
  checking for grep that handles long lines and -e... /usr/bin/grep
  checking for egrep... /usr/bin/grep -E
  checking for ANSI C header files... yes
  checking for sys/wait.h that is POSIX.1 compatible... yes
  checking for sys/types.h... yes
  checking for sys/stat.h... yes
  checking for stdlib.h... yes
  checking for string.h... yes
  checking for memory.h... yes
  checking for strings.h... yes
  checking for inttypes.h... yes
  checking for stdint.h... yes
  checking for unistd.h... yes
  checking fcntl.h usability... yes
  checking fcntl.h presence... yes
  checking for fcntl.h... yes
  checking for unistd.h... (cached) yes
  checking for inttypes.h... (cached) yes
  checking sys/file.h usability... yes
  checking sys/file.h presence... yes
  checking for sys/file.h... yes
  checking sys/time.h usability... yes
  checking sys/time.h presence... yes
  checking for sys/time.h... yes
  checking sys/un.h usability... yes
  checking sys/un.h presence... yes
  checking for sys/un.h... yes
  checking math.h usability... yes
  checking math.h presence... yes
  checking for math.h... yes
  checking for stdint.h... (cached) yes
  checking mingw/stdint.h usability... no
  checking mingw/stdint.h presence... no
  checking for mingw/stdint.h... no
  checking for size_t... yes
  checking for uint_t... no
  checking for ulong_t... no
  checking for size_t... (cached) yes
  checking whether struct tm is in sys/time.h or time.h... time.h
  checking for inline... inline
  configure: creating ./config.status
  config.status: creating Makefile
  config.status: creating src/Makefile
  config.status: creating src/Makefile_obj
  config.status: creating include/verilated.mk
  config.status: creating src/config_build.h
  config.status: src/config_build.h is unchanged
  
  Now type 'gmake'
 $ gmake
  ash: gmake: command not found
  
 $ make
  … (6分程度)
  
  Build complete!
  
  Type 'make test' to test.
  
 $ make test
  …
  
  Tests passed!
  
  Type 'make install' to install documentation.
  
 $ make install
  …
  
  Installed!
  
  Fod documentation see 'man verilator' or 'verilator --help'
  For forums and to report bugs see http://www.veripool.org/verilator
 $ ls /usr/local/bin/verilator*
  /usr/local/bin/verilator*          /usr/local/bin/verilator_bin_dbg.exe*
  /usr/local/bin/verilator_bin.exe*  /usr/local/bin/verilator_profcfunc*
 $ verilator
  Usage:
          verilator --help
          verilator --version
          verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
          verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
          verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
          verilator --lint-only    [top_level.v]...

* bin2bcd.v を C++ に変換してみる [#c4565035]

[[電気回路/HDL/2進からBCDへの変換回路]] にあるコードを使っています。

 LANG:console
 $ cd bin2bcd
 $ ls
  bin2bcd.v
 $ verilator -cc bin2bcd.v
  %Warning-WIDTH: bin2bcd.v:318: Operator ASSIGNDLY expects 4 bits on the Assign R
  HS, but Assign RHS's SUB generates 32 bits.
  %Warning-WIDTH: Use "/* verilator lint_off WIDTH */" and lint_on around source t
  o disable this message.
  %Warning-WIDTH: bin2bcd.v:326: Operator SHIFTL expects 35 bits on the LHS, but L
  HS's ARRAYSEL generates 32 bits.
  %Warning-WIDTH: bin2bcd.v:332: Operator ASSIGNDLY expects 4 bits on the Assign R
  HS, but Assign RHS's CONCAT generates 5 bits.
  %Warning-WIDTH: bin2bcd.v:333: Operator SUB expects 35 bits on the LHS, but LHS'
  s VARREF 'numerator' generates 32 bits.
  %Warning-WIDTH: bin2bcd.v:333: Operator ASSIGNDLY expects 32 bits on the Assign
  RHS, but Assign RHS's SUB generates 35 bits.
  %Warning-WIDTH: bin2bcd.v:335: Operator ASSIGNDLY expects 4 bits on the Assign R
  HS, but Assign RHS's CONCAT generates 5 bits.
  %Warning-WIDTH: bin2bcd.v:331: Operator GTE expects 35 bits on the LHS, but LHS'
  s VARREF 'numerator' generates 32 bits.
  %Error: Exiting due to 7 warning(s)
  %Error: Command Failed /home/osamu/verilator-3.804/verilator_bin -cc --top-modul
  e bin2bcd bin2bcd.v
 $ verilator -cc -Wno-lint bin2bcd.v
 $ ls
  bin2bcd.v   obj_dir/
 $ ls obj_dir/
  Vbin2bcd.cpp  Vbin2bcd.mk         Vbin2bcd__Syms.h  Vbin2bcd__verFiles.dat
  Vbin2bcd.h    Vbin2bcd__Syms.cpp  Vbin2bcd__ver.d   Vbin2bcd_classes.mk

lint で警告が出るとコンパイルしてくれないようで、
lint 警告を無視するオプションをつけたところ、
正しく verilog -> c++ の変換ができました。

* C++ でテストベンチを書く [#e327916d]

Verilator で生成される C++ コードを使って
生の C++ でテストベンチを書こうとすると、
かなりやっかいなことになるようです。

http://www.veripool.org/projects/verilator/wiki/Manual-verilator

の Connecting to C++ を参考にしました。

bin2bcd_test.cpp

 LANG:cpp
 #include <iostream>
 #include <verilated.h>          // Defines common routines
 #include "Vbin2bcd.h"           // From Verilating "bin2bcd.v"
 
 unsigned int main_time = 0;     // Current simulation time
 
 double sc_time_stamp () {       // Called by $time in Verilog
     return main_time;
 }
 
 int main(int argc, char** argv) {
 
     Verilated::commandArgs(argc, argv);   // Remember args
 
     Vbin2bcd *top = new Vbin2bcd();       // Create instance
     
     top->rst = 1;                         // Set some inputs
     top->clk = 0;
     top->bin = 123;
 
     while (!Verilated::gotFinish()) {
         
         if ((main_time % 5) == 0)
             top->clk = !top->clk;         // Toggle clock
 
         if (main_time > 10)               // Release reset
             top->rst = 0;
                                           // Assert start flag
         top-> start = 105 < main_time && main_time < 115;
         
         top->eval();                      // Evaluate model
 
                                           // Wait for done
         if (main_time>200 && top->busy == 0)
             break;
 
         main_time++;                      // Time passes...
 
     }
                                           // Read the output
     cout << hex << showbase << top->bcd << endl;
     
     top->final();               // Done simulating
     //    // (Though this example doesn't get here)
 }

テストベンチコードを --exe に指定して verilator 
を呼ぶことでソースコードが生成され、それを make 後に実行します。

 LANG:console
 $ verilator -cc -Wno-lint bin2bcd.v --exe bin2bcd_test.cpp
 $ cd obj_dir/
 $ make -j -f Vbin2bcd.mk Vbin2bcd
  g++  -I. -MMD -I/home/osamu/verilator-3.804/include -I/home/osamu/verilator-3.804
  /include/vltstd -DVL_PRINTF=printf -DVM_TRACE=0 -DVM_COVERAGE=0 -c -o bin2bcd_tes
  t.o ../bin2bcd_test.cpp
  g++    bin2bcd_test.o verilated.o Vbin2bcd__ALL.a -o Vbin2bcd -lm -lstdc++ 2>&1 | 
  c++filt
 $ ./Vbin2bcd.exe
  0x123

ということで、正しい答えが得られることが分かりましたが・・・

 LANG:cpp
 while (!Verilated::gotFinish()) {

のループを使ってテストベンチを書くのはつらすぎるので、
ちゃんと SystemC を勉強して、出直そうと思います。

続きとして [[電気回路/HDL/SystemC の導入]] を書きました。

* 関連記事 [#uac815a9]

#ls2(電気回路/HDL/Verilator);
#ls2(電気回路/HDL/System);

* コメント [#f2f7940f]

#article_kcaptcha
**参考にさせていただいています [#q8a9eb22]
>[marsee] (2011-05-22 (日) 07:40:06)~
~
Verilatorの記事を参考にさせていただいています。とても参考になります。ありがとうございます。私のブログにも過程を書きたいと思っています。よろしくお願いします。~
質問があるのですが、XilinxのCoregenで作ったIPのシミュレーションをやってみたことがありますか?~

//
- 残念ながらありません。上でも書いたのですが Verilator は 【verilog で書かれた「論理合成可能な」モジュールを変換する物】 と考えているので、verilog コードが手に入るものであれば可能じゃないかと思うのですが・・・ -- [武内(管理人)] &new{2011-05-22 (日) 09:03:40};
- この記事を参考にして、ブログを書かせていただきました。http://marsee101.blog19.fc2.com/blog-entry-1807.html よろしくお願いします。 -- [marsee] &new{2011-05-23 (月) 06:51:38};
- ISE の Verilog ソースファイルを使うことで可能ではないかと。思われます -- [アプロ] &new{2011-06-07 (火) 10:48:01};

#comment_kcaptcha

**無題 [#re9c6e7b]
>[marsee] (2010-10-29 (金) 14:02:15)~
~
こんにちは。~
すごくタイムリーな記事をありがとうございます。自分でやる手間が省けてうれしいです。呟いてみるもんですね。。。(だれか反応してくれるかと思っていのですが、反応がないようなので、いつかやってみようと思っていました)~

//

#comment_kcaptcha

Counter: 18896 (from 2010/06/03), today: 4, yesterday: 0