2.6 config_db - manual
文章目录
前言
本文以uvm-1.2/examples/simple/configuration/manual为例,主要介绍在config_db机制中,如何通过set和get函数,在UVM的各个组件之间传递参数。另外,这个例子还展示了两种不同的方法,打印UVM的树状拓扑结构。
一、基本介绍
这个测试用例的UVM树状拓扑结构和2.5节一样,在top下面例化了两个组件A和B,其中A下面例化了两个C,B下面例化了一个C,具体的组件层次结构和参数如下所示。2.5节没有get函数,是通过满足一定的条件,在build_phase中,通过调用super.build_phase,自动调用了get函数;和2.5节不一样的是,在这个测试用例中,A,B和C组件中通过手动调用get函数,获取set函数传递的参数。
----------------------------------------------------
Name Type Size Value
----------------------------------------------------
topenv my_env - @362
inst1 A - @381
u1 C - @402
v integral 32 'h1e
s integral 32 'h10
myaa aa_string_string 3 -
myaa[bar] string 3 bye
myaa[foo] string 3 boo
myaa[foobar] string 6 boobah
u2 C - @411
v integral 32 'h5
s integral 32 'h10
myaa aa_string_string 3 -
myaa[bar] string 3 bye
myaa[foo] string 2 hi
myaa[foobar] string 5 howdy
debug integral 1 'h1
inst2 B - @390
u1 C - @433
v integral 32 'ha
s integral 32 'h0
myaa aa_string_string 3 -
myaa[bar] string 3 bye
myaa[foo] string 2 hi
myaa[foobar] string 5 howdy
debug integral 1 'h1
debug integral 1 'h0
----------------------------------------------------
这里简单介绍一下config_db机制中的set函数和get函数。
1、写信set函数
1)第一个和第二个参数联合起来组成目标路径,与此路径符合的目标才能收信。
2)第一个参数必须为uvm_component 的实例的指针。
3)第二个参数是相对于此实例的路径。
4)既然是第一个和第二个参数联合起来的,set 也可以是下面:
2、收信get函数
1)第一个参数必须为uvm_component 的实例的指针。
2)第二个参数是相对于此实例的路径。如果第一个设置为 this,第二个可以是空的字符串。
3)第三个参数必须和set中的严格一样。
4)get也可以这样,比如driver的build_phase:
二、代码分析
代码共5个文件,包括:top.sv,my_env_pkg.sv,classA.svh,classB.svh,classC.svh。下面分别介绍这5个文件的代码。
1.top.sv
module top;
import uvm_pkg::*;
import my_env_pkg::*;
my_env topenv;
initial begin
//uvm_default_printer = uvm_default_table_printer;
uvm_top.enable_print_topology = 1;
//set configuration prior to creating the environment
uvm_config_int::set(null, "topenv.*.u1", "v", 30);
uvm_config_int::set(null, "topenv.inst2.u1", "v", 10);
uvm_config_int::set(null, "topenv.*", "debug", 1);
uvm_config_string::set(null, "*", "myaa[foo]", "hi");
uvm_config_string::set(null, "*", "myaa[bar]", "bye");
uvm_config_string::set(null, "*", "myaa[foobar]", "howdy");
uvm_config_string::set(null, "topenv.inst1.u1", "myaa[foo]", "boo");
uvm_config_string::set(null, "topenv.inst1.u1", "myaa[foobar]", "boobah");
topenv = new("topenv", null);
run_test();
end
endmodule
这个文件的代码大部分和2.5节一致,其中值得注意的是,第9行通过设置uvm_top.enable_print_topology这个参数为1,在end_of_elaboration phase结束的时候打印UVM的树状拓扑结构。
2. my_env_pkg.sv
package my_env_pkg;
import uvm_pkg::*;
`include "classA.svh"
`include "classB.svh"
class my_env extends uvm_env;
bit debug = 0;
A inst1;
B inst2;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_config_int::get(this, "", "debug", debug));
uvm_config_int::set(this, "inst1.u2", "v", 5);
uvm_config_int::set(this, "inst2.u1", "v", 3);
uvm_config_int::set(this, "inst1.*", "s", 'h10);
$display("%s: In Build: debug = %0d", get_full_name(), debug);
inst1 = new("inst1", this);
inst2 = new("inst2", this);
endfunction
function string get_type_name();
return "my_env";
endfunction
function void do_print(uvm_printer printer);
printer.print_field("debug", debug, 1);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
uvm_top.print_topology();
#10;
phase.drop_objection(this);
endtask
endclass
endpackage : my_env_pkg
这个文件值得注意的是,第18行手动的调用的get函数。另外,第38行这里提供了第二种打印UVM树状top结构的方法。
3. classA.svh,classB.svh,classC.svh
三个文件的代码分别如下所示,与2.5节的区别是,在build_phase中手动的加入了get函数。
classA.svh
`ifndef CLASSA_SVH
`define CLASSA_SVH
`include "classC.svh"
class A extends uvm_component;
bit debug = 0;
C u1;
C u2;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_config_int::get(this, "", "debug", debug));
uvm_config_int::set(this, "*", "v", 0);
$display("%s: In Build: debug = %0d", get_full_name(), debug);
u1 = new("u1", this);
u2 = new("u2", this);
endfunction
function string get_type_name();
return "A";
endfunction
function void do_print(uvm_printer printer);
printer.print_field("debug", debug, 1);
endfunction
endclass
`endif
classB.svh
`ifndef CLASSB_SVH
`define CLASSB_SVH
`include "classC.svh"
class B extends uvm_component;
bit debug = 0;
C u1;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_config_int::get(this, "", "debug", debug));
uvm_config_int::set(this, "u1", "v", 0);
$display("%s: In Build: debug = %0d", get_full_name(), debug);
u1 = new("u1", this);
endfunction
function string get_type_name();
return "B";
endfunction
function void do_print(uvm_printer printer);
printer.print_field("debug", debug, 1);
endfunction
endclass
classC.svh
`ifndef CLASSC_SVH
`define CLASSC_SVH
class C extends uvm_component;
int v=0;
int s=0;
string myaa [string];
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
string str;
super.build_phase(phase);
void'(uvm_config_int::get(this, "", "v", v));
void'(uvm_config_int::get(this, "", "s", s));
if(uvm_config_string::get(this, "", "myaa[foo]", str)) myaa["foo"] = str;
if(uvm_config_string::get(this, "", "myaa[bar]", str)) myaa["bar"] = str;
if(uvm_config_string::get(this, "", "myaa[foobar]", str)) myaa["foobar"] = str;
endfunction
function string get_type_name();
return "C";
endfunction
function void do_print(uvm_printer printer);
printer.print_field("v", v, 32);
printer.print_field("s", s, 32);
printer.print_array_header("myaa", myaa.num(), "aa_string_string");
foreach(myaa[i])
printer.print_string($sformatf("myaa[%0s]", i), myaa[i]);
printer.print_array_footer();
endfunction
function void set_string_local (string field_name,
string value,
bit recurse=1);
string index;
bit wildcarded;
//call the super function to get child recursion and any registered fields
super.set_string_local(field_name, value, recurse);
index = uvm_get_array_index_string(field_name, wildcarded);
if(!wildcarded && uvm_is_match(field_name, {"myaa[", index, "]"}))
myaa[index] = value;
endfunction
endclass
`endif
总结
通过这个测试用例可以学习到:1、如何利用config_db机制中的set和get函数,在UVM的组件之间传递参数;2、两种不同的方法打印UVM的树状top结构。