


UVMの環境構築!(10) Test (テストコンポーネント)

UVMの環境構築!(9) Environment

UVMの環境構築第5回では、コレクターの定義(作成)方法について解説していきます。
なお、ソースコードはGitHubに公開しています。
目次
UVMの環境構築!シリーズの目次は、第1回 解説編の一番下をご覧ください。
コレクターはuvm_componentを継承して定義します。uvm_collectorというのはUVMでは定義されていません。
UVMでは、モニターが
と定義されています。その他モニターでは、レスポンスのチェックやカバレッジ計算を行うため、非常に盛りだくさんです。
そこで、DUTのレスポンスのサンプリング→トランザクションに変換→他のコンポーネントに送信 を専門に行うコンポーネントとしてコレクターを定義し、モニターから分離するのが一般的となっています。
DUTのレスポンスの取得はvirtual interfaceを使用します。DUTのポートに接続したinterfaceと、コレクターに定義したvirtual interfaceはつながっています(やり方はmy_collector_base.svで説明します)。したがって、DUTのポートの信号が変化すると、コレクターのvirtual interfaceの信号にも反映されます。
コレクターを定義する際は、DUTによらずお決まりで書くことがあります。したがって、次の手順で記述するとよいです。
それでは、ソースコードを見ながら、コレクターの定義方法について説明します。
my_collector_base.sv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class my_collector_base #(type TR = uvm_seqeuence_item) extends uvm_component; VIF_COLLECTOR vif; uvm_analysis_port #(TR) analysis_port; /* Constructor */ function new(string name, uvm_component parent); super.new(name, parent); analysis_port = new("analysis_port", this); endfunction /* Connect phase */ function void connect_phase (uvm_phase phase); super.connect_phase(phase); if (!uvm_config_db #(VIF_COLLECTOR)::get(this, get_full_name(), "vif", vif)) `uvm_error("VIF_NOT_SET", {"No interface assigned to ", get_full_name(), ".vif"}); endfunction /* Run phase */ task run_phase(uvm_phase phase); collect_response(); endtask /* Sub class must implement this behaviour */ virtual task collect_response(); endtask endclass |
1 | typedef virtual my_if VIF_COLLECTOR; |
my_collector_baseを継承して、DUTに対応したmy_collectorを定義します。
my_collector.sv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class my_collector extends my_collector_base #(my_item); `uvm_component_utils(my_collector) /* Constructor */ function new(string name, uvm_component parent); super.new(name, parent); endfunction /* Collect response in Run phase */ task collect_response (); my_item data; data = my_item::type_id::create("response"); forever begin @(vif.cb) begin if (vif.start == 1'b1) begin data.a_in = vif.a_in; data.b_in = vif.b_in; data.rst = vif.rst; end if (vif.rst == 1'b0) begin /* Reset released */ if (vif.valid == 1'b1) begin data.mult_out = vif.mult_out; analysis_port.write(data); end end end end endtask endclass |
今回は、コレクターの定義方法について解説しました。シリーズを通してご覧いただけると、UVM検証環境が構築できるようになりますので、ぜひ他のコンポーネントの解説もご覧ください。
シリーズ目次はこちら