目录
具体地,对于方法compare如何写?uvm_pkg例化的对应全局数据操作配置成员是什么?
2.3 uvm_pkg中的全局控制对象uvm_default_comparer
2.5 2.6 uvm_object::print()和copy()
4.3 在顶层uvm_config_test配置变量c1和c2中的var

首先是`uvm_component_utils()注册;然后是new函数,第二个参数是parent,必须调用super.new();最后是build_phase()函数,也是必须调用super.build_phase(p)函数
- class comp1 extends uvm_component;
- `uvm_component_utils (comp1)//注册组件;new函数必须只有两个参数
- function new (string name=:comp1", uvm_component parent=null);//parent是指上一层,当前实例是谁例化的,谁就是这个实例parent
- super.new(name, parent);//继承父类new函数
- $display($sformatf("%s is created", name));//已例化当前类
- endfunction : new
- function void build_phase (uvm_phase phase);
- super.build_phase (phase);
- endfunction: build_phase
- endclass
然后是利用工厂创建对象,也就是例化:
例化component用c2 = comp1::type_id::create ("c2",null);也是两个参数
例化object用o2 = obj1::type_id::create("o2");
- class obj1 extends uvm_object;
- `uvm_object_utils (obj1)
- function new (string name="obj1");//object只有一个参数
- super.new(name);
- $display ($sformatf("%s is created",name));
- endfunction: new
- endclass
-
- comp1 c1, c2;
- obj1 o1,o2;
- initial begin
- c1 = new ("c1");//任何对象的例化最终都是通过new()函数来实现,sv的方法
- o1 = new ("o1");
- c2 = comp1::type_id::create ("c2",null);//这个也是例化的写法,factory提供的方法
- o2 = obj1::type_id::create("o2");
- end
最后就是覆盖了,两种覆盖方法如下
- set_inst_override ( uvm_object_wrapper override_type, string inst_path);
- //uvm_object_wrapper override_type是注册过后的某一个类在工厂中注册时的句柄,用new_type::get_type()找到
set_type_override ( uvm_object_wrapper override_type);
覆盖机制只会影响通过工厂注册并且例化的对象
调用覆盖函数用comp2覆盖com1的函数如下
- orig_type::type_id::set_type_override (new_type::get_type())
- //typedef 静态函数 静态函数
- //用new_type新类型替换原来的类型orig_type::type_id
例码如下.
- module factory_override;
- import uvm_pkg::*;//可直接import和include,编译器已经包含了
- `inculde "uvm_macros.svh"
-
- class comp1 extends uvm_component;//1声明
- `uvm_component_utils(comp1)//2注册
-
- function new (string name="comp1", uvm_component parent= null);//3new函数
- super.new(name, parent);
- $display ($sformatf("comp1::%s is created", name));
- endfunction
-
- virtual function void hello (string name);//virtual是关键
- $display ( $sformatf("comp1:: %s is said hello!", name);
- endfunction
- endclass
-
- class comp2 extends comp1;//要覆盖的类一定要继承于被覆盖的类
- `uvm_component_utils(comp2)
-
- function new (string name="comp2", uvm_component parent= null);
- super.new(name, parent);
- $display ($sformatf("comp2::%s is created", name));
- endfunction
-
- function void hello (string name);
- $display ( $sformatf("comp2:: %s is said hello!", name);
- endfunction
- endclass
-
- comp1 c1, c2;//两个句柄都是comp1的类型
- initial begin
- comp1::type_id::set_type_override (comp2::get_type());//调用覆盖函数,如上段例码
- c1= new("c1");//例化c1(comp1),没有通过工厂。打印comp1::c1 is created,
- c2= comp2::type_id::creare("c2",null);//工厂创建的对象,create返回一个comp2句柄给c2
- //但是c2是comp1的句柄,却指向了comp2类型的对象。这里就是子类句柄覆盖父类句柄。所以必须是继承关系
- //用工厂注册,就一定要用工厂来创建,达到便利的目的
- //打印comp1::c2 is created,comp2::c2 is created
- c1.hello("c1");//调用comp1的hello,打印 comp1::c1 is said hello
- c2.hello("c2");//调用comp2的hello,打印 comp2::c2 is said hello
- end
-
- endmodule
今后会参与到的对象拷贝、克隆、打印等操作的成员变量
注册的时候顺便声明,就可以直接使用uvm_object预定义的一些方法
- class box extends uvm_object;
- int volume=120;
- color_t color = white;
- string name= "box";
- `uvm_object_utils_begin(box)//注册box的同时
- `uvm_filed_int(volume, UVM_ALL_ON)//声明了会参与到object数据操作的成员变量
- `uvm_filed_enum(color_t, color, UVM_ALL_ON)
- `uvm_filed_string(name, UVM_ALL_ON)//默认采取UVM_ALL_ON和UVM_DEFAULT,所有操作方法都打开
- `uvm_object_utils_end
- ......
- endclass
-
- box b1, b2;
- initial begin//声明过的成员变量将在数据操作时自动参与进来
- b1 = new("box1");
- b1.volume = 80;
- b1.color = black;
- b2 = new();
- b2.copy(b1);//否则不会自动参与数据的操作,要自己定义数据操作方法
- b2.name = "box2";
- end
域的类型及其对应的宏声明非常多,还有数据操作列表,这里有两个图,就省略了
见类库地图,几乎是所有核心基类的最顶层
copy,clone,compare,pare,pack和unpack
关于复制的例码,句柄赋值给另一个句柄b2,此时两个句柄指向同一个对象box,在b2句柄中修改name,box中也被修改,打印出来的是同一个name
- typedef enum {RED, WHITE, BLACK} color_t;
- class box extends uvm_object;
- int volume=120;
- color_t color=WHITE;
- string name="box";
- `uvm_objext_utils(box)
- function new(string name="name");
- super.new(name);
- this.name=name;
- endfunction
- endclass
-
- initial begin
- b1=new("box1");
- b2=b1;
- b2.name="box2";
- $display("b1 name is %s", b1.name);
- $display("b2 name is %s", b2.name);
- end
-
- //结果如下
- //b1 name is box2
- //b2 name is box2
function bit compare(uvm_object rhs, uvm_compare compare=null); 不做额外配置的话,第二个参数可以忽略,采用默认的比较配置
uvm_package::uvm_default_comparer 最大输出错误比较信息(show_max)是1,当错误发生后不再进行后续比较
如果不用默认,可以创建一个uvm_comparer对象,如下;也可以修改uvm_comparer对象
- box b1, b2;
- uvm_comparer cmpr;
- initial begin
- ...
- cmpr=new();
- cmpr.show_max=10;
- if(!b2.compare(b1)) begin
- ... end
调用uvm_object::print()函数时自动打印出来
全局对象:uvm_default_printer,d和p中间可以加上tree、line、table,打印的方式
字符串返回信息uvm_object::sprint(),自定义回调函数do_print()
对于验证环境层次化,保证例化先后关系的机制

只有build是自顶向下的执行
只有uvm_component及其子类才会按照图中的顺序执行,component!!!
只有run_phase是task,可以耗时,可以完成一些等待、激励、采样的任务
runphase通常需要组织的序列:上电;复位;reg配置;发送主要测试内容;等待dut完成测试
run_phase还有12个分支phase(reset,config,main,shutdown及其前后),并行执行。不要用
为了验证环境的复用性,配置更细致的环境调节中的变量,在仿真时通过变量设置来修改环境。在不破坏原有结构的前提去改变验证环境。
- uvm_config_db#(T)::set(uvm_component cntxt, string inst_name, string field_name, T value);
- // 传递一个实例句柄进来 实例名称 实例中的变量名 值
- //第一个参数表示当前层次,如果是最高层可以是null,也可以uvm_root::get()
- uvm_config_db#(T)::get(uvm_component cntxt, string inst_name, string field_name, inout T value);
位置:在run_test()之前
类型:interface和virtual interface
例码如下:先声明接口,
- interface intf1;
- logic enable=0;
- endinterface
-
- class comp1 extends uvm_component;
- `uvm_componnet_utils(comp1)
- virtual intf1 vif;//拿到intf1的指针
- ......
- function void build_phase (uvm_phase phase);
- if(!uvm_config_db#(virtual intf1)::get(this, "", "vif", vif)) begin
- //this表示当前的comp1(uvm_top.root.test.c1.vif),没有实例,变量是vif字符串要加“”,
- `uvm_error("GETVIF", "no virtual interface is assigned")
- end
- `uvm_info("SETVAL", $sformatf("vif.enable is %b befor set", vif.enable), UVM_LOW)
- vif.enable=1;
- `uvm_info("SETVAL", $sformatf("vif.enable is %b after set", vif.enable), UVM_LOW )
- endfunction
- endclass
-
- class test1 extends uvm_test;
- `uvm_component_utils(test1)
- comp1 c1;
- ...
- endclass
-
- intf1 intf();
- initial begin
- uvm_config_db#(virtual intf1)::set(uvm_root::get(), "uvm_test_top.c1", "vif", intf);
- //先set进intf1中,等下就get出来
- run_test("test1");//root->test->c1->vif,分别对应set中的4个参数
- end
位置:build_phase
- class comp1 extends uvm_component;
- `uvm_component_utils(comp1)
- int val1 = 1;
- string str1 = "null";
- ......
- function void build_phase (uvm_phase phase);
- `uvm_info("SETVAL", $sformatf("val1 is %d before get", val1), UVM_LOW)
- `uvm_info("SETVAL", $sformatf("str1 is %s before get", str1), UVM_LOW)
- uvm_config_db#(int)::get(this, "", "val1", val1);//把配置好的get进来
- uvm_config_db#(string)::get(this, "", "str1", str1);
- `uvm_info("SETVAL", $sformatf("val1 is %d after get", val1), UVM_LOW)
- `uvm_info("SETVAL", $sformatf("str1 is %s after get", str1), UVM_LOW)
- endfunction
-
- endclass
-
- class test1 extends uvm_test;
- `uvm_component_utils(test1)
- comp1 c1;
- ......
- function void build_phase (uvm_phase phase);
- uvm_config_db#(int)::set(this, "c1", "val1", 100);//先set再例化
- uvm_config_db#(string)::set(this, "c1", "str1", "comp1");
- c1=comp1::type_id::create("c1", this);
- endfunction
- endclass
目的:将需要配置的参数变量放到一个uvm_object中,一次配置完毕
位置:build_phase
- class config1 extends uvm_object;
- int val1=1;
- int str1="null";
- `uvm_object_utils(config1)
- ......
- endclass
-
- class comp1 extends uvm_component;
- `uvm_component_utils(comp1)
- config1 cfg;
- ......
- function void build_phase(uvm_phase phase)
- uvm_object tmp;
- uvm_config_db#(uvm_object)::get(this, "", "cfg", tmp);//得到的tmp是父类句柄
- void'($cast(cfg, tmp));//传递的类型要保持一致!!
- `uvm_info("SETVAL", $sformatf("cfg.val1 is %d after get", cfg.val1), UVM_LOW)
- `uvm_info("SETVAL", $sformatf("cfg.str1 is %s after get", cfg.str1), UVM_LOW)
- endfunction
- endclass
-
- class test1 extends uvm_test;
- `uvm_component_utils(test1)
- comp1 c1,c2;
- config cfg1, cfg2;
- ......
- function void build_phase(uvm_phase phase);
- cfg1= config1::type_id::create("cfg1");
- cfg2= config2::type_id::create("cfg2");
- cfg1.val1=30;
- cfg1.str1="c1";
- cfg2.val1=50;
- cfg2.str1="c2";
- uvm_config_db#(uvm_object)::set(this, "c1", "cfg", cfg1);//类型从int换成object
- uvm_config_db#(uvm_object)::set(this, "c2", "cfg", cfg2);
- c1=comp1::type_id::create("c1", this);
- c2=comp2::type_id::create("c2", this);
- endfunction
- endclass
-
之前的SV实验使用的是$sformatf()系统函数
- initial begin
- t1 = new();
- t2 = new();
- tests["mcdf_data_consistence_basic_test"] = t1;
- tests["mcdf_full_random_test"] = t2;
- if($value$plusargs("TESTNAME=%s", name)) begin
- if(tests.exists(name)) begin
- tests[name].set_interface(chnl0_if, chnl1_if, chnl2_if, reg_if, arb_if, fmt_if, mcdf_if);
- tests[name].run();
- end
- else begin
- $fatal($sformatf("[ERRTEST], test name %s is invalid, please specify a valid name!", name));
- end
- end
- else begin
- $display("NO runtime optiont +TESTNAME=xxx is configured, and run default test mcdf_data_consistence_basic_test");
- tests["mcdf_data_consistence_basic_test"].set_interface(chnl0_if, chnl1_if, chnl2_if, reg_if, arb_if, fmt_if, mcdf_if);
- tests["mcdf_data_consistence_basic_test"].run();
- end
- end
方式1:通过uvm_pkg提供的全局函数run_test()来指定运行某一个uvm_test,都继承于uvm_test
方式2:就是上面例码的+UVM_TESTNAME=
- class trans extends uvm_object;
- bit[31:0] data;
- `uvm_object_utils(trans)
- function new(string name = "trans");
- super.new(name);
- `uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
- endfunction
- endclass
-
- class object_create extends top;
- trans t1, t2, t3, t4;
- `uvm_component_utils(object_create)
- function new(string name = "object_create", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- uvm_factory f = uvm_factory::get(); // get singleton factory
- super.build_phase(phase);
- t1 = new("t1"); // direct construction
- t2 = trans::type_id::create("t2", this); // common method
- void'($cast(t3,f.create_object_by_type(trans::get_type(), get_full_name(), "t3")));
- // factory method用工厂提供的方法create_object_by_type()来创建对象
- void'($cast(t4,create_object("trans", "t4"))); // 用component预定义的方法来创建对象
- endfunction
- endclass
- class unit extends uvm_component;
- `uvm_component_utils(unit)
- function new(string name = "unit", uvm_component parent = null);
- super.new(name, parent);
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- endclass
-
- class component_create extends top;
- unit u1, u2, u3, u4;
- `uvm_component_utils(component_create)
- function new(string name = "component_create", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- uvm_factory f = uvm_factory::get(); // get singleton factory
- super.build_phase(phase);
- u1 = new("u1"); // direct construction
- u2 = unit::type_id::create("u2", this); // common method
- void'($cast(u3,f.create_component_by_type(unit::get_type(), get_full_name(), "u3", this))); // factory method
- void'($cast(u4,create_component("unit", "u4"))); // pre-defined method inside component
- endfunction
- endclass
和上面的方法set_type_override ( uvm_object_wrapper override_type);有一点区别的是这里是用set_type_override_by_type ( uvm_object_wrapper override_type, new_type::get_type());
想要表示type类型都要调用原来类型中的::get_type()
- class bad_trans extends trans;
- bit is_bad = 1;
- `uvm_object_utils(bad_trans)
- function new(string name = "trans");
- super.new(name);
- `uvm_info("CREATE", $sformatf("bad_trans type [%s] created", name), UVM_LOW)
- endfunction
- endclass
-
- class object_override extends object_create;
- `uvm_component_utils(object_override)
- function new(string name = "object_override", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- set_type_override_by_type(trans::get_type(), bad_trans::get_type());
- super.build_phase(phase);
- endfunction
- endclass
- class big_unit extends unit;
- bit is_big = 1;
- `uvm_component_utils(big_unit)
- function new(string name = "bit_unit", uvm_component parent = null);
- super.new(name, parent);
- `uvm_info("CREATE", $sformatf("big_unit type [%s] created", name), UVM_LOW)
- endfunction
- endclass
-
- class component_override extends component_create;
- `uvm_component_utils(component_override)
- function new(string name = "component_override", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- set_type_override("unit", "big_unit");//!!!!!!!!!!!!!!!!!!!!!!
- super.build_phase(phase);
- endfunction
- endclass
-
- class trans extends uvm_object;
- bit[31:0] addr;
- bit[31:0] data;
- op_t op;
- string name;
- `uvm_object_utils_begin(trans)
- `uvm_field_int(addr, UVM_ALL_ON)
- `uvm_field_int(data, UVM_ALL_ON)
- `uvm_field_enum(op_t, op, UVM_ALL_ON)
- `uvm_field_string(name, UVM_ALL_ON)
- `uvm_object_utils_end
function bit compare (uvm_object rhs, uvm_comparer comparer=null)
直接调用对应对象.compare(待比较对象句柄)
- class object_methods_test extends uvm_test;
- `uvm_component_utils(object_methods_test)
- function new(string name = "object_methods_test", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- endfunction
- task run_phase(uvm_phase phase);
- trans t1, t2;
- bit is_equal;
- phase.raise_objection(this);
- t1 = trans::type_id::create("t1");
- t1.data = 'h1FF;
- t1.addr = 'hF100;
- t1.op = WRITE;
- t1.name = "t1";
- t2 = trans::type_id::create("t2");
- t2.data = 'h2FF;
- t2.addr = 'hF200;
- t2.op = WRITE;
- t2.name = "t2";
- is_equal = t1.compare(t2);//调用比较函数
- uvm_default_comparer.show_max = 10;//通过全局控制对象设置最大比较次数
- is_equal = t1.compare(t2);
-
- if(!is_equal)
- `uvm_warning("CMPERR", "t1 is not equal to t2")
- else
- `uvm_info("CMPERR", "t1 is equal to t2", UVM_LOW)
-
- `uvm_info("COPY", "Before uvm_object copy() taken", UVM_LOW)
- t1.print();
- t2.print();
- `uvm_info("COPY", "After uvm_object t2 is copied to t1", UVM_LOW)
- t1.copy(t2);//也是直接调用即可
- t1.print();
- t2.print();
- `uvm_info("CMP", "Compare t1 and t2", UVM_LOW)
- is_equal = t1.compare(t2);
- if(!is_equal)
- `uvm_warning("CMPERR", "t1 is not equal to t2")
- else
- `uvm_info("CMPERR", "t1 is equal to t2", UVM_LOW)
-
- #1us;
- phase.drop_objection(this);
- endtask
- endclass
- typedef enum {WRITE, READ, IDLE} op_t;
-
- class trans extends uvm_object;
- bit[31:0] addr;
- bit[31:0] data;
- op_t op;
- string name;
- `uvm_object_utils_begin(trans)
- `uvm_field_int(addr, UVM_ALL_ON)
- `uvm_field_int(data, UVM_ALL_ON)
- `uvm_field_enum(op_t, op, UVM_ALL_ON)
- `uvm_field_string(name, UVM_ALL_ON)
- `uvm_object_utils_end
- function new(string name = "trans");
- super.new(name);
- `uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
- endfunction
- //自定义回调函数,在上面的代码中执行完compare立即会执行以下的do_compare
- function bit do_compare(uvm_object rhs, uvm_comparer comparer);
- trans t;
- do_compare = 1;
- void'($cast(t, rhs));
- if(addr != t.addr) begin
- do_compare = 0;
- `uvm_warning("CMPERR", $sformatf("addr %8x != %8x", addr, t.addr))
- end
- if(data != t.data) begin
- do_compare = 0;
- `uvm_warning("CMPERR", $sformatf("data %8x != %8x", data, t.data))
- end
- if(op != t.op) begin
- do_compare = 0;
- `uvm_warning("CMPERR", $sformatf("op %s != %8x", op, t.op))
- end
- if(addr != t.addr) begin
- do_compare = 0;
- `uvm_warning("CMPERR", $sformatf("name %8x != %8x", name, t.name))
- end
- endfunction
- endclass
build_phase中例化对象
- class comp2 extends uvm_component;
- `uvm_component_utils(comp2)
- function new(string name = "comp2", uvm_component parent = null);
- super.new(name, parent);
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "comp2 build phase entered", UVM_LOW)
- `uvm_info("BUILD", "comp2 build phase exited", UVM_LOW)
- endfunction
- function void connect_phase(uvm_phase phase);
- super.connect_phase(phase);
- `uvm_info("CONNECT", "comp2 connect phase entered", UVM_LOW)
- `uvm_info("CONNECT", "comp2 connect phase exited", UVM_LOW)
- endfunction
- task run_phase(uvm_phase phase);
- super.run_phase(phase);
- `uvm_info("RUN", "comp2 run phase entered", UVM_LOW)
- `uvm_info("RUN", "comp2 run phase entered", UVM_LOW)
- endtask
- function void report_phase(uvm_phase phase);
- super.report_phase(phase);
- `uvm_info("REPORT", "comp2 report phase entered", UVM_LOW)
- `uvm_info("REPORT", "comp2 report phase exited", UVM_LOW)
- endfunction
- endclass
-
- class comp3 extends uvm_component;
- `uvm_component_utils(comp3)
- function new(string name = "comp3", uvm_component parent = null);
- super.new(name, parent);
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "comp3 build phase entered", UVM_LOW)
- `uvm_info("BUILD", "comp3 build phase exited", UVM_LOW)
- endfunction
- function void connect_phase(uvm_phase phase);
- super.connect_phase(phase);
- `uvm_info("CONNECT", "comp3 connect phase entered", UVM_LOW)
- `uvm_info("CONNECT", "comp3 connect phase exited", UVM_LOW)
- endfunction
- task run_phase(uvm_phase phase);
- super.run_phase(phase);
- `uvm_info("RUN", "comp3 run phase entered", UVM_LOW)
- `uvm_info("RUN", "comp3 run phase entered", UVM_LOW)
- endtask
- function void report_phase(uvm_phase phase);
- super.report_phase(phase);
- `uvm_info("REPORT", "comp3 report phase entered", UVM_LOW)
- `uvm_info("REPORT", "comp3 report phase exited", UVM_LOW)
- endfunction
- endclass
-
- class comp1 extends uvm_component;
- comp2 c2;
- comp3 c3;
- `uvm_component_utils(comp1)
- function new(string name = "comp1", uvm_component parent = null);
- super.new(name, parent);
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "comp1 build phase entered", UVM_LOW)
- c2 = comp2::type_id::create("c2", this);
- c3 = comp3::type_id::create("c3", this);
- `uvm_info("BUILD", "comp1 build phase exited", UVM_LOW)
- endfunction
- function void connect_phase(uvm_phase phase);
- super.connect_phase(phase);
- `uvm_info("CONNECT", "comp1 connect phase entered", UVM_LOW)
- `uvm_info("CONNECT", "comp1 connect phase exited", UVM_LOW)
- endfunction
- task run_phase(uvm_phase phase);
- super.run_phase(phase);
- `uvm_info("RUN", "comp1 run phase entered", UVM_LOW)
- `uvm_info("RUN", "comp1 run phase entered", UVM_LOW)
- endtask
- function void report_phase(uvm_phase phase);
- super.report_phase(phase);
- `uvm_info("REPORT", "comp1 report phase entered", UVM_LOW)
- `uvm_info("REPORT", "comp1 report phase exited", UVM_LOW)
- endfunction
- endclass
在顶层test中set
- class uvm_config_test extends uvm_test;
- comp1 c1;
- config_obj cfg;
- `uvm_component_utils(uvm_config_test)
- function new(string name = "uvm_config_test", uvm_component parent = null);
- super.new(name, parent);
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "uvm_config_test build phase entered", UVM_LOW)
- cfg = config_obj::type_id::create("cfg");
- cfg.comp1_var = 100;
- cfg.comp2_var = 200;
- //在这里配置
- uvm_config_db#(config_obj)::set(this, "*", "cfg", cfg);
- uvm_config_db#(int)::set(this, "c1", "var1", 10);
- uvm_config_db#(int)::set(this, "c1.c2", "var2", 20);
-
- c1 = comp1::type_id::create("c1", this);
- `uvm_info("BUILD", "uvm_config_test build phase exited", UVM_LOW)
- endfunction
-
- task run_phase(uvm_phase phase);
- super.run_phase(phase);
- `uvm_info("RUN", "uvm_config_test run phase entered", UVM_LOW)
- phase.raise_objection(this);
- #1us;
- phase.drop_objection(this);
- `uvm_info("RUN", "uvm_config_test run phase exited", UVM_LOW)
- endtask
- endclass
在对应的class中get
- class config_obj extends uvm_object;
- int comp1_var;
- int comp2_var;
- `uvm_object_utils(config_obj)
- function new(string name = "config_obj");
- super.new(name);
- `uvm_info("CREATE", $sformatf("config_obj type [%s] created", name), UVM_LOW)
- endfunction
- endclass
-
- class comp2 extends uvm_component;
- int var2;
- virtual uvm_config_if vif;
- config_obj cfg;
- `uvm_component_utils(comp2)
- function new(string name = "comp2", uvm_component parent = null);
- super.new(name, parent);
- var2 = 200;
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "comp2 build phase entered", UVM_LOW)
- //配置接口
- if(!uvm_config_db#(virtual uvm_config_if)::get(this, "", "vif", vif))
- `uvm_error("GETVIF", "no virtual interface is assigned")
-
- `uvm_info("GETINT", $sformatf("before config get, var2 = %0d", var2), UVM_LOW)
- //配置变量
- uvm_config_db#(int)::get(this, "", "var2", var2);
- `uvm_info("GETINT", $sformatf("after config get, var2 = %0d", var2), UVM_LOW)
-
- uvm_config_db#(config_obj)::get(this, "", "cfg", cfg);
- `uvm_info("GETOBJ", $sformatf("after config get, cfg.comp2_var = %0d", cfg.comp2_var), UVM_LOW)
-
- `uvm_info("BUILD", "comp2 build phase exited", UVM_LOW)
- endfunction
- endclass
-
- class comp1 extends uvm_component;
- int var1;
- comp2 c2;
- config_obj cfg;
- virtual uvm_config_if vif;
- `uvm_component_utils(comp1)
- function new(string name = "comp1", uvm_component parent = null);
- super.new(name, parent);
- var1 = 100;
- `uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
- endfunction
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- `uvm_info("BUILD", "comp1 build phase entered", UVM_LOW)
- if(!uvm_config_db#(virtual uvm_config_if)::get(this, "", "vif", vif))
- `uvm_error("GETVIF", "no virtual interface is assigned")
-
- `uvm_info("GETINT", $sformatf("before config get, var1 = %0d", var1), UVM_LOW)
- uvm_config_db#(int)::get(this, "", "var1", var1);
- `uvm_info("GETINT", $sformatf("after config get, var1 = %0d", var1), UVM_LOW)
-
- uvm_config_db#(config_obj)::get(this, "", "cfg", cfg);
- `uvm_info("GETOBJ", $sformatf("after config get, cfg.comp1_var = %0d", cfg.comp1_var), UVM_LOW)
-
- c2 = comp2::type_id::create("c2", this);
- `uvm_info("BUILD", "comp1 build phase exited", UVM_LOW)
- endfunction
- endclass