あまりやる気の無かったメソドロジに手を出すことにしました。
これはそのおぼえがきです。
##なぜUVMか
- 資料が充実してきた。
- VMMとかAVMとかOVMとかのように、これ以上メソドロジの名前が変わることは無かろう。
- Verification IPがUVMを前提にインスタンスさせることが多い。
- 仕事の案件、政治的関係。
以上により、今、UVMに少し力を入れることは時間の無駄では無かろうと判断しました。
##UVMに必要な知識と感じるもの
OOPですかねー。継承とオーバーライドは不可避っぽい。
C++とかの知識があるといいと思いますが、個人的にはPythonとかやっているといいかもしれません。
ここでは、SystemVerilogに関する知識があるという前提で書いていきます。
##UVMの特徴
- Layeredなテストコード構造により、効率的にテストを流すことができる。
- テスト実行手順が決められているので、それに従えば無理なくテスト環境を構築できる。
- 上記により決められた手順に沿ってお決まりの宣言をする(いわゆる、おまじない)だけで、テストは一応完成する。
- コードが汚くなる。
実際のところ、資料をただ読むだけでなく、自分でコードを書いてシミュレータで動かさないと個人的には理解できないですね。
ということで、コードを書いていくことにしました。
##UVMの資料
Verification AcademyのBasic UVMの各コースに日本語のPDF資料があるので参考になります。
https://verificationacademy.com/courses/basic-uvm
##まずはHello Worldから
検証対象(DUT)はまず置いておいて、UVMのテストで完結するコードを書いてみます。
`include "uvm_macros.svh"
import uvm_pkg::*;
module tb();
class base_test extends uvm_test;
`uvm_component_utils(base_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
`uvm_info("TEST", "Hello, Wold.", UVM_MEDIUM);
phase.drop_objection(this);
endtask
endclass
class ext_test extends base_test;
`uvm_component_utils(ext_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
`uvm_info("TEST", "Extended Hello, Wold.", UVM_MEDIUM);
phase.drop_objection(this);
endtask
endclass
initial
run_test();
endmodule
まずはUVMのベースクラスであるuvm_testを継承して簡単なテストクラス(base_test)を作ります。
次にuvm_component_utilsにそのテストクラス名を入れ、テストを登録します( ;が入らないことに注意 )。
コンストラクターとして、function newがあり、引数はあのまま(おなじない)、super.new()でベースクラスもインスタンスします。
次に、run_phaseというtask(おまじない)を作成し、uvm_info($displayみたいなもの)でメッセージを出力します。
`uvminfoの前後に「phase...(this)」がありますが、実はこのコードでは不要です。これは、検証モジュールが増えて並列に走っているときにsmaphore的にリソースをゲットするためのステートメントです( たぶん )
ext_baseクラスはbase_testクラスを継承しています。run_phaseはオーバーライドされます。
テスト実行にはrun_test()を宣言します(おなじない)。
##動かし方
動作確認してませんが、各資料を読みあさる限り、こんなオプションでイケルと思います。バージョンによってはオプションをさらに盛る必要があるかもしれません。
###VCSの場合
vcs \
-R \
-full64 \
-sverilog \
-ntb_opts uvm \
hello_world.sv \
+UVM_TESTNAME=base_test
###Incisiveの場合
irun \
-64 \
-uvm \
hello_world.sv \
+UVM_TESTNAME=base_test
###QuestaSimの場合
vlib work
vlog hello_world.sv
vsim -64 -c tb -do "run -all" +UVM_TESTNAME=base_test
##実行結果
UVM_INFOから始まって、「Hello, Wold.」が表示され、シミュレーション実行号のサマリーでFATALやERRORがカウントされなければオッケーです。
+UVM_TESTNAMEオプションもおまじないで、+UVM_TESTNAME=ext_testと変更すると、ext_testクラスで記述されたテストが実行、つまり「Extended Hello, Wold.」と表示されます。
##おわりに。
メソドロジをやって感じるのは、ピン接続で簡単にできることもわざわざ面倒な手順でやらなくてはいけないことですね。小規模な回路でテストするのだったら不要と思います。
大規模な回路をチーム開発でたくさんのテストシナリオを流す時に、初めてその生産性の高さがわかるのかもしれません。そこまで気力が保つかどうかですね。
そもそも日本でSystemVerilogが要るかどうかはさておき、 気が向いたら継続して残していこうと思います。