3日目は、uvm_testクラスの下にuvm_envクラスを組み込みました。4日目は、同様の記述方法で、一気に残りを組み込んでいきます。
組み込みの順番を考えて、下から作っていきます。コードは、「model/」の下に記述していき、記述したファイルを「sample.svh」に追記していきます。
class sample_driver extends uvm_driver; `uvm_component_utils(sample_driver) function new (string name, uvm_component parent); super.new(name, parent); endfunction task run_phase(uvm_phase phase); uvm_report_info("DRIVER", "Hi"); endtaskendclassclass sample_monitor extends uvm_monitor; `uvm_component_utils(sample_monitor) function new (string name, uvm_component parent); super.new(name, parent); endfunction task run_phase(uvm_phase phase); uvm_report_info("MONITOR", "Hi"); endtaskendclassclass sample_sequencer extends uvm_sequencer; `uvm_component_utils(sample_sequencer) function new (string name, uvm_component parent); super.new(name, parent); endfunction task run_phase(uvm_phase phase); uvm_report_info("SEQR", "Hi"); endtaskendclasssequencerは、最小限の構成で使うときは「定義しなくてもいい」ですが、ちゃんとテストベンチを組み立てようと考えたとき、sequencerも自分でextendsして作成することを推奨します。その理由は、後日の 内容で説明するか、ワンランク上の技術説明の箇所で行います。
uvm_agentクラスは、上記3クラスの上位にあたるので、彼らをインスタンスして生成する記述を追加します。
#太字部分を修正しました。文字列なので、好きなな名前をセットしていいのですが、紛らわしいケースが発生するので、「インスタンス名」にしておくのがお勧めです
class sample_agent extends uvm_agent; `uvm_component_utils(sample_agent) sample_driver driver; sample_monitor monitor; sample_sequencer sequencer; function new (string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); driver = sample_driver::type_id::create("driver", this); //修正 monitor = sample_monitor::type_id::create("monitor", this); //修正 sequencer = sample_sequencer::type_id::create("sequencer", this); //修正 endfunction task run_phase(uvm_phase phase); uvm_report_info("AGENT", "Hi"); endtaskendclassuvm_agentクラスをuvm_envクラスに組み込みます。
class sample_env extends uvm_env; `uvm_component_utils(sample_env) sample_agent agent; function new (string name, uvm_component parent); super.new(name,parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); agent = sample_agent::type_id::create("agent", this); endfunction task run_phase(uvm_phase phase); uvm_report_info("ENV", "Hello ENV"); endtaskendclass黄色いところが、追記した部分です。
model/以下に
がある状態で、「sample_model.svh」を以下のようにします。includeの順番は「下位階層」から行っていきます。なお、「typedef」をうまく使うことで、includeの順番を好きなようにすることもできます。で すが、ここではそれを行いません。
`include "sample_driver.sv"`include "sample_monitor.sv"`include "sample_sequencer.sv"`include "sample_agent.sv"`include "sample_env.sv"コンパイルすると、以下のWarningが出ます。
** Warning: model//sample_driver.sv(1): (vlog-2181) Use of a parameterized class uvm_driver as a type creates a default specialization.
** Warning: model//sample_sequencer.sv(1): (vlog-2181) Use of a parameterized class uvm_sequencer as a type creates a default specialization.
これは、uvm_driverとuvm_sequencerは「parameterized class」となっており、extends時にパラメータを記述していないため、defaultのパラメータが使われるよ?というメッセージです。これについては、後 日のお話で展開しますので、いまは「そういうものだ」と無視してください。
実行すると、以下のようなログが出ます。
# UVM_INFO @ 0: reporter [RNTST] Running test sample_test...# UVM_INFO @ 0: uvm_test_top [TEST] Hello World# UVM_INFO @ 0: uvm_test_top.env [ENV] Hello ENV# UVM_INFO @ 0: uvm_test_top.env.agent [AGENT] Hi# UVM_INFO @ 0: uvm_test_top.env.agent.sample_sequencer [SEQR] Hi# UVM_INFO @ 0: uvm_test_top.env.agent.sample_monitor [MONITOR] Hi# UVM_INFO @ 0: uvm_test_top.env.agent.sample_driver [DRIVER] Hi