Verilator の導入(C++モード) の履歴(No.3)
更新Verilator†
marsee さんからの情報で Verilator というフリーのシミュレータを知ったので、 自分のノート PC の cygwin 環境に導入して、C++ モードのシミュレーションをやってみました。
結論としては、C++ モードでのシミュレーションはあまりに使いづらいので、 ちゃんと SystemC を勉強しないとだめそうです?
続きとして 電気回路/HDL/SystemC の導入 を書きました。
情報源†
http://lexim.co.jp/verilator.html
http://wiki.sweetcafe.jp/doku.php?id=systemc:verilator
http://www.veripool.org/projects/verilator/wiki/Manual-verilator
cygwin 環境の整備†
- gcc-core
- g++
- perl
- flex
- bison
- make
を入れておく必要がありました。
ちゃんと使うには SystemPerl も入れないといけないのですが、 今回は C++ モードのみのテストということで、省いています。
ダウンロード&インストール†
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++ に変換してみる†
電気回路/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++ でテストベンチを書く†
Verilator はイベントドリブンではないそうで、 生の 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 の導入 を書きました。
コメント†
無題†
[marsee] (2010-10-29 (金) 14:02:15)
こんにちは。
すごくタイムリーな記事をありがとうございます。自分でやる手間が省けてうれしいです。呟いてみるもんですね。。。(だれか反応してくれるかと思っていのですが、反応がないようなので、いつかやってみようと思っていました)