ソフトウェア環境下においてテスティングフレームワークは、例えばJUnit, GoogleTest など。 しかしハードウェア言語向けのテスティングフレームワークというのは少ない。
以前に少し紹介したのは、cocotbというテスティングフレームワーク、こちらはPythonを使用するフレームワークだ。ブログでも少し紹介した。
それ以外にもう少し発見した。VUnitというVHDL/SystemVerilog用のテスティングフレームワークだ。
ここでは、Verilogをベースにして調査してみよう。まずはインストールから。
cd vunit
sudo python ./setup.py install
これでVUnitのバイナリがインストールされる。
次にサンプルを眺めてみよう。サンプルコードは、 examples/verilog/uart/
に置いてある。
cd vunit/example/verilog/uart python ./run.py Compiling ../../../../../../../usr/local/lib/python2.7/dist-packages/vunit_hdl-2.2.1rc0-py2.7.egg/vunit/verilog/vunit_pkg.sv into vunit_lib ... Compiling src/uart_tx.sv into uart_lib ... Compiling src/uart_rx.sv into uart_lib ... Compiling src/test/tb_uart_tx.sv into tb_uart_lib ... Compiling src/test/tb_uart_rx.sv into tb_uart_lib ... Starting tb_uart_lib.tb_uart_rx.test_tvalid_low_at_start pass (P=1 S=0 F=0 T=5) tb_uart_lib.tb_uart_rx.test_tvalid_low_at_start (1.6 seconds) Starting tb_uart_lib.tb_uart_rx.test_receives_one_byte pass (P=2 S=0 F=0 T=5) tb_uart_lib.tb_uart_rx.test_receives_one_byte (0.1 seconds) Starting tb_uart_lib.tb_uart_rx.test_two_bytes_cause_overflow pass (P=3 S=0 F=0 T=5) tb_uart_lib.tb_uart_rx.test_two_bytes_cause_overflow (0.2 seconds) Starting tb_uart_lib.tb_uart_tx.test_send_one_byte pass (P=4 S=0 F=0 T=5) tb_uart_lib.tb_uart_tx.test_send_one_byte (0.2 seconds) Starting tb_uart_lib.tb_uart_tx.test_send_many_bytes pass (P=5 S=0 F=0 T=5) tb_uart_lib.tb_uart_tx.test_send_many_bytes (0.2 seconds) ==== Summary ================================================================ pass tb_uart_lib.tb_uart_rx.test_tvalid_low_at_start (1.6 seconds) pass tb_uart_lib.tb_uart_rx.test_receives_one_byte (0.1 seconds) pass tb_uart_lib.tb_uart_rx.test_two_bytes_cause_overflow (0.2 seconds) pass tb_uart_lib.tb_uart_tx.test_send_one_byte (0.2 seconds) pass tb_uart_lib.tb_uart_tx.test_send_many_bytes (0.2 seconds) ============================================================================= pass 5 of 5 ============================================================================= Total time was 2.4 seconds Elapsed time was 2.7 seconds ============================================================================= All passed!
こんな調子で実行される。この指定されたrun.py
は何をしているのかということだが、ソースコードに脚注を付けていくと、
from os.path import join, dirname from vunit.verilog import VUnit ui = VUnit.from_argv() src_path = join(dirname(__file__), "src") # ソースファイルの場所を指定できるようにする。 uart_lib = ui.add_library("uart_lib") # UART本体を格納するためのライブラリを定義する uart_lib.add_source_files(join(src_path, "*.sv")) # ライブラリにソースコードを挿入する tb_uart_lib = ui.add_library("tb_uart_lib") # UARTのテストパタンを格納するためのライブラリを定義する tb_uart_lib.add_source_files(join(src_path, "test", "*.sv")) # UARTのライブラリにソースコードを挿入する。 ui.main() # テスト実行
テストパタンの中身
テストパタンの中身をチェックしてみる。例えば、 examples/verilog/uart/src/test/tb_uart_tx.sv
を見てみよう。いくつかのtaskが定義されていることが分かる。
テストケースとテストスイート
TEST_SUITE
はテストスイートを定義する。TEST_SUITE
の中には、テストケースを定義している。テストケースは、テストスイート内に複数定義することが出来る。
テストケースはそのままテストを記述している。
`TEST_SUITE begin `TEST_CASE("test_send_one_byte") begin send(); check_all_was_received(); end `TEST_CASE("test_send_many_bytes") begin for (int i=0; i<7; i++) begin send(); end check_all_was_received(); end end
テストケースでは、いくつかのdefineが使用できる。
TEST_SUITE_SETUP
: 全てのテストスイート共通のセットアップを行う。TEST_CASE_SETUP
: 全てのテストケースの共通のセットアップを行う。CHECK_EQUAL
: アサーションを記述する。TEST_CASE_CLEANUP
: 全てのテストケース共通で、テスト終了後の処理を行う。TEST_SUITE_CLEANUP
: 全てのテストスイート共通で、テスト終了後の処理を行う。WATCHDOG
: タイムアウト設定
これでいくつかサンプル作って試してみたいな。