UVM实验1

1. 工厂的注册,创建和覆盖机制

1.1 注册

只有两种用来注册的宏

`uvm_object_utils(T) // T指类型
`uvm_component_utils(T)

//注册的三个步骤:
class trans extends uvm_object;//1.trans声明
	  bit[31:0] data;
	  `uvm_object_utils(trans) //2.trans注册
	  function new(string name = "trans"); //3.function new(),注册的三个步骤,下面同理
	  	super.new(name);
	  	`uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
	  endfunction
	 endclass

1.2 创建

推荐使用t2

	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
			//uvm_factory里的创建方法,需要通过uvm_factory::get()来获得uvm_factory的句柄,从而调用create_object_by_type(uvm_object_wrapper requested_type, string parent_inst_path="", string name="");
			void`($cast(t4, create_object("trans", "t4")));//pre_defined method inside component
			//uvm_object自己提供的创建方法,create_object(string requested_type_name, string name="");
		endfunction
	endclass

uvm_component 的创建方法同理

1.3 覆盖

覆盖方法有:

comp1::type_id::set_type_override(comp2::get_type()) //推荐,comp2覆盖comp1
set_type_override_by_type(trans::get_type(), bad_trans::get_type()); //bad_trans覆盖trans,uvm_component自己的覆盖函数
set_type_override(“unit”, “big_unit”) //big_unit覆盖unit

注意两点:
1.先覆盖,再创建
2.覆盖类型一定要继承于原类型

	class object_override extends object_creat;
		`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());
			//使用的是uvm_component自己的函数set_type_override_by_type(uvm_object_wrapper original_type, uvm_object_wrapper override_type, bit replace=1)
			super.build_phase(phase);
			//有一个细节,先覆盖,再创建,即先执行上上行代码set_type,再执行super.build_phase
		endfunction
	endclass

2. 域的自动化和uvm_object的常用方法

2.1 compare方法

修改默认比较次数

uvm_default_comparer.show_max = 10;

使用回调函数do_compare
do_compare函数是compare函数的回调函数,执行完conpare以后会自动的执行do_compare,compare没有执行的话do_compare也不会执行

	class trans extends uvm_object;//1.声明
		bit[31:0] addr;
		bit[31:0] data;
		op_t op;
		string name;
		`uvm_object_utils_begin(trans)//2.注册以及域的自动化的声明
			`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");//3.functon new()
			super.new(name);
			`uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
			endfunction
		function bit do_compare(uvm_object rhs, uvm_comparer compare);//在trans类型里声明回调函数do_compare
		//那么在trans类里的变量使用comepare函数后会自动调用do_compare函数
			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))
			if(data != t.data) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("data %8x != %8x", data, t.data))
			if(op != t.op) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("op %s != %s", op, t.op))
			if(name != t.name) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("name %s != %s", name, t.name))
			end
		endfunction
	endclass

2.2 print()

2.3 copy()

3. phase机制

phase机制使得验证环境从组建(build),到连接(connect),再到执行得以分阶段执行,按照层次结构和phase顺序严格执行,继而避免一些依赖关系,也使得UVM用户可以正确的将不同的代码放置到不同的phase块中

3.1 run_phase执行顺序(仿真结果图)

1.phase_order_test创建了c1,c1又创建的c2和c3
2.观察是否是统一的某一个phase执行完,再执行下一个phase
3.是否是所有组件的build_phase执行完,再执行connect_phase,再执行run_phase
4.按照层次关系,build_phase是否是自顶向下的,connect_phase是否是自底向上的
c2未在c1的build_phase里创建时:
在这里插入图片描述

3.2 run_phase和12个子phase的执行顺序(仿真结果图)

1.在uvm_test里,run_phase和与它平行的reset_phase和main_phase,它们之间是不是并行运行的关系
2.最终仿真运行了多长时间,1us还是2us,为什么运行这么长的时间?
在这里插入图片描述

4. config机制

仿真结果图
1.接口传递与run_test()之间是否存在顺序?
2.在uvm_config_test::build_phase()中,如果将c1的例化提前到刚进入build_phase()中时,而将后续config_db传递的操作放置于其后,是否可行?为什么?
通过上述两个问题,你认为config_db在使用时,需要注意什么地方

4.1 接口传递置于run_test之前:

	initial begin
		uvm_config_db#(virtual uvm_config_if)::set(uvm_root::get(), "uvm_test_top.*", "vif", if0);
		run_test("")
	end

4.2配置放在对象创建之前

为了将所需配置的变量事先放于uvm_config_db中进行存储,而在后续子一级组件例化并且进入build_phase从uvm_config_db获得配置变量时,可以确保所配置的变量都已事先于子一级组件创建前进行过配置,避免出现配置变量无法获取的情况。
在build_phase中,对当前层次及以下组件的变量配置,都应该先于该子一级组件创建前完成。尽管实际子一级组件先创建后配置的做法往往也可以成功,但为了避免可能出现的麻烦,我们仍然建议将配置放在对象创建之前。

对于cfg(object类型),先创建,再赋值
对于c1(component类型),先配置,再创建

	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;//对于cfg(object类型),先创建,再赋值
			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);//对于c1(component类型),先配置,再赋值
			`uvm_info("BUILD", "uvm_config_test build phase exited", UVM_LOW)
		endfunction

在变量的配置上:
对于cfg句柄来说,将当前声明的句柄set即可
对于var1,当前类里声明并创建了c1
对于var2,c2在c1里创建,c1在当前类里创建

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)

在这里插入图片描述

5. 消息管理

set_report_verbosity_level_hier(UVM_NONE) //屏蔽所有层次的消息
set_report_id_verbosity_level_hier(“BUILD”, UVM_NONE) // 屏蔽BUILD的消息
uvm_root::get().set_report_id_verbosity_level_hier(“BUILD”, UVM_NONE) //uvm_message_test的顶层

6. 源代码

package factory_pkg;
	import uvm_pkg::*;
	`include "uvm_macros.svh"
	
	class trans extends uvm_object;//1.trans声明
	  bit[31:0] data;
	  `uvm_object_utils(trans) //2.trans注册
	  function new(string name = "trans"); //3.function new(),注册的三个步骤,下面同理
	  	super.new(name);
	  	`uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
	  endfunction
	 endclass

	class bad_trans extends trans; //只有继承于父类,才能覆盖父类
		bit is_bad = 1;
		`uvm_object_utils(trans)
		function new(string name = "bad_trans");
			super.new(name);
			`uvm_info("CREATE", $sformatf("bad_trans type [%s] created", name), UVM_LOW)  	
	  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 big_unit extends unit;
		bit is_big = 1;
		`uvm_component_utils(big_unit)
		function new(string name = "big_unit", uvm_component parent = null);
			super.new(name, parent);
			`uvm_info("CREATE", $sformatf("big_unit type [%s] created", name), UVM_LOW)
		endfunction
	endclass

	class top extends uvm_test;
		`uvm_component_utils(top)
		function new(string name = "top", uvm_componet 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);
			phase.raise_objection(this);
			#1us;
			phase.drop_objection(this);
		endtask
	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
			//uvm_factory里的创建方法,需要通过uvm_factory::get()来获得uvm_factory的句柄,从而调用create_object_by_type(uvm_object_wrapper requested_type, string parent_inst_path="", string name="");
			void`($cast(t4, create_object("trans", "t4")));//pre_defined method inside component
			//uvm_object自己提供的创建方法,create_object(string requested_type_name, string name="");
		endfunction
	endclass

	class object_override extends object_creat;
		`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());
			//使用的是uvm_component自己的函数set_type_override_by_type(uvm_object_wrapper original_type, uvm_object_wrapper override_type, bit replace=1)
			super.build_phase(phase);
			//有一个细节,先覆盖,再创建,即先执行上上行代码set_type,在执行super.build_phase
		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(phase);
			uvm_factory f = uvm_factory::get();//get singleton factory
			u1 = new("u1");//direct construction
			u2 = unit::type_id::create("u2", this);
			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

	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

endpackage

module factory_mechanism_ref;
	
	import uvm_pkg::*;
	`include "uvm_macros.svh"
	import factory_pkg::*;

	initial begin
		run_test("")//empty test name
	end

endmodule
	
package object_methods_pkg;
	import uvm_pkg::*;
	`include "uvm_macros.svh"
	
	typedef enum {WRITE, READ, IDLE} op_t;

	class trans extends uvm_object;//1.声明
		bit[31:0] addr;
		bit[31:0] data;
		op_t op;
		string name;
		`uvm_object_utils_begin(trans)//2.注册以及域的自动化的声明
			`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");//3.functon new()
			super.new(name);
			`uvm_info("CREATE", $sformatf("trans type [%s] created", name), UVM_LOW)
			endfunction
		function bit do_compare(uvm_object rhs, uvm_comparer compare);//在trans类型里声明回调函数do_compare
		//那么在trans类里的变量使用comepare函数时会自动调用do_compare函数
			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))
			if(data != t.data) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("data %8x != %8x", data, t.data))
			if(op != t.op) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("op %s != %s", op, t.op))
			if(name != t.name) begin
				do_compare = 0;
				`uvm_warning("CMPERR", $sformatf("name %s != %s", name, t.name))
			end
		endfunction
	endclass

	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;

			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 copy() taken", 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("COMPERR", "t1 is not equal to t2")
			else
				`uvm_info("CMPERR", "t1 is equal to t2",UVM_LOW)
			#1us;
			phase.drop_objection(this);
		endtask
	endclass

endpackage

module uvm_object_methods_ref;

	import uvm_pkg::*;
	`include "uvm_macros.svh"
	import object_methods_pkg::*;

	initial begin
		run_test("");//empty test name
	end

endmodule

package phase_order_pkg;
	import uvm_pkg::*;
	`include "uvm_macro.svh"

	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)		
		endfuction
		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 exited", 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)		
		endfuction
		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 exited", 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里,组件的创建或者对象的创建都发生在build_phase里,sv发生在new()里,注意区别
			`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)		
		endfuction
		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 exited", 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

	class phase_order_test extends uvm_test;//构建环境顶层,任何一个层次结构都离不开uvm_test
		comp1 c1;
		`uvm_component_utils(phase_order_test)
		function new(string name = "phase_order_test", uvm_component parent = null);
			super.new(name, parent);
		endfunction
		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			`uvm_info("BUILD", "phase_order_test build phase entered", UVM_LOW)
			c1 = comp1::type_id::create("c1", this);
			`uvm_info("BUILD", "phase_order_test build phase existed", UVM_LOW)
		endfunction
		function void connect_phase(uvm_phase phase);
			super.connect_phase(phase);
			`uvm_info("CONNECT", "phase_order_test connect phase entered", UVM_LOW)
			`uvm_info("CONNECT", "phase_order_test connect phase existed", UVM_LOW)
		endfunction
		task run_phase(uvm_phase phase);
			super.run_phase(phase);
			`uvm_info("RUN", "phase_order_test run phase entered", UVM_LOW)
			phase.raise_objection(this);
			#1us;
			phase.drop_objection(this);
			`uvm_info("RUN", "phase_order_test run phase existed", UVM_LOW)
		endtask
		function void report_phase(uvm_phase phase);
			super.report_phase(phase);
			`uvm_info("REPORT", "phase_order_test report phase entered", UVM_LOW)
			`uvm_info("REPORT", "phase_order_test report phase existed", UVM_LOW)
		endfunction

		task reset_phase(uvm_phase phase);
			`uvm_info("RESET", "phase_order_test reset phase entered", UVM_LOW)
			phase.raise_objection(this);
			#1us;
			phase.drop_objection(this);
			`uvm_info("RESET", "phase_order_test reset phase existed", UVM_LOW)
		endtask

		task main_phase(uvm_phase phase);
			`uvm_info("MAIN", "phase_order_test main phase entered", UVM_LOW)
			phase.raise_objection(this);
			#1us;
			phase.drop_objection(this);
			`uvm_info("MAIN", "phase_order_test main phase existed", UVM_LOW)
		endtask
	endclass
endpackage

module phase_order_ref;

	import uvm_pkg::*;
	`include "uvm_macros.svh"
	import phase_order_pkg::*;

	initial begin
		run_test("");//empty test name
	end

endmodule

interface uvm_config_if;
	logic[31:0] addr;
	logic[31:0] data;
	logic[ 1:0] op;
endfunction

package uvm_config_pkg;
	import uvm_pkg::*;
	`include "uvm_macros.svh"

	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")
			else
				`uvm_info("GETVIF", $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("GETINT", $sformatf("after config get,cfg.comp2_var = %0d", cfg.comp2_var), UVM_LOW)

			`uvm_info("BUILD", "comp2 build phase existed", UVM_LOW)
		endfunction
	endclass
	
	class comp1 extends uvm_component;
		int var1;
		comp2 c2;
		virtual uvm_config_if vif;
		config_obj cfg;
		`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")
			else
				`uvm_info("GETVIF", $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("GETINT", $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 existed", UVM_LOW)
		endfunction
	endclass
	
	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 existed", UVM_LOW)
		endtask
	endclass
endpackage

module uvm_config_ref;

	import uvm_pkg::*;
	`include "uvm_macros.svh"
	import uvm_config_pkg::*;

	uvm_config_if if0();

	initial begin
		uvm_config_db#(virtual uvm_config_if)::set(uvm_root::get(), "uvm_test_top.*", "vif", if0);
		run_test("")
	end

endmodule


package uvm_message_pkg;
	import uvm_pkg::*;
	`include "uvm_macros.svh"

	class config_obj extends uvm_object;
		`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;
		`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
		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 exited", UVM_LOW)
		endtask
	endclass
		
	class comp1 extends uvm_component;
		comp2 c2;
		`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
		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 exited", UVM_LOW)
		endtask
	endclass




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值