はじめに
UVMを使っていると必ず出てくるuvm_config_db。
なんとなく、テストベンチでInterfaceをデータベースに登録して、クラスの中で呼び出すんだなぁと漠然と思っていました。
今回は様々な条件で使用してみて理解を深めます。
また、本サンプルコードのインクルードファイルを置き換えることで動作するようになっています。
module top;
`include "uvm_macros.svh"
import uvm_pkg::*;
`include "sample.svh" // これ。
endmodule
使い方
uvm_config_db#(<型>)::set(<UVMの階層>, <インスタンス名>, <フィールド名>, <setする値>);
uvm_config_db#(<型>)::get(<UVMの階層>, <インスタンス名>, <フィールド名>, <getしたものを入れる変数>);
体感ですが、
<uvmの階層>.<インスタンス名>.<フィールド名>
みたいな感じで値がsetされていそうです。
sample0.svh
int a, b;
initial begin
uvm_config_db#(int)::set(null, "fuga", "val1", 1);
uvm_config_db#(int)::set(null, "fuga", "val2", 2);
void'(uvm_config_db#(int)::get(null, "fuga", "val1", a));
void'(uvm_config_db#(int)::get(null, "fuga", "val2", b));
$display("%d", a);
$display("%d", b);
end
// 出力
// 1
// 2
null.fuga.val1に1, null.fuga.val2に2をsetして取り出しました。
sample1.svh
null.fuga.val1に2回setしてみます。
int a, b;
initial begin
uvm_config_db#(int)::set(null, "fuga", "val1", 1);
uvm_config_db#(int)::set(null, "fuga", "val1", 2);
void'(uvm_config_db#(int)::get(null, "fuga", "val1", a));
$display("%d", a);
end
// 出力
// 2
上書きされました。
sample2.svh
別な型で同じ場所にsetしてみます。
int a;
string b;
initial begin
uvm_config_db#(int)::set(null, "fuga", "val", 1);
uvm_config_db#(string)::set(null, "fuga", "val", "hello");
void'(uvm_config_db#(int)::get(null, "fuga", "val", a));
void'(uvm_config_db#(string)::get(null, "fuga", "val", b));
$display("%d", a);
$display("%s", b);
end
// 1
// hello
同じ場所でも、型が違うと違うところにsetされています。
sample3.svh
uvm_component環境で使用します。
class sample_test extends uvm_test;
`uvm_component_utils(sample_test)
int a;
function new(string name="sample_test", uvm_component parent=null);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
void'(uvm_config_db#(int)::get(null, "", "hoge", a));
$display("%d", a);
endtask
endclass
initial begin
uvm_config_db#(int)::set(null, "", "hoge", 1);
run_test("sample_test");
end
// 出力
// 1
sample4.svh
getせずに直接値を渡します。
class sample_test extends uvm_test;
int a;
`uvm_component_utils_begin(sample_test)
`uvm_field_int(a, UVM_ALL_ON)
`uvm_component_utils_end
function new(string name="sample_test", uvm_component parent=null);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
$display("%d", a);
endtask
endclass
initial begin
uvm_config_db#(int)::set(null, "", "a", 2);
run_test("sample_test");
end
// 出力
// 2
sample5.svh
uvm_componentを階層構造にします。
class sample_env extends uvm_env;
int a;
`uvm_component_utils_begin(sample_env)
`uvm_field_int(a, UVM_ALL_ON)
`uvm_component_utils_end
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
$display("Env %d", a);
endtask
endclass
class sample_test extends uvm_test;
int a;
`uvm_component_utils_begin(sample_test)
`uvm_field_int(a, UVM_ALL_ON)
`uvm_component_utils_end
sample_env env;
function new(string name="sample_test", uvm_component parent=null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = sample_env::type_id::create("env", this);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
$display("Test %d", a);
endtask
endclass
initial begin
uvm_config_db#(int)::set(null, "uvm_test_top.env", "a", 3);
uvm_config_db#(int)::set(null, "uvm_test_top", "a", 4);
run_test("sample_test");
end
// 出力
// Test 4
// Env 3
まとめ
uvm_config_dbについて調べました。
コメント