UVM1-基础知识篇

//------------UVM基础知识篇------------


package pack1; //pack1头
	import uvm_pkg::*; //+UVM
  	`include "uvm_macros.svh"//+工厂


	//目标类与组件类,目标类可以游离的存在,组件类必须挂在某个位置,或许是
	//root或许是其他组件
	//目标类
	class obj1 extends uvm_object;
		//顺序1:属性
		bit [7:0] data0 = 'haa;
		bit [7:0] data1 = 'hbb;
		//顺序2:工厂
		`uvm_object_utils(obj1)
		//顺序3:方法
		function new();//构造函数
			super.new();//调用父类构造函数	   
			`uvm_info("class:obj1",$sformatf("data0:%x!",data0),UVM_LOW)
			`uvm_info("class:obj1",$sformatf("data1:%x!",data1),UVM_LOW)
			//UVM信息:组别,打印信息,优先级(UVM_LOW优先级很高)
		endfunction

		//也可以定义类的外部方法,来解决一个类中方法过长的现象
		extern task xxx(); 
	endclass

	task obj1::xxx();
		`uvm_info("class:obj1",$sformatf("this is xxx task"),UVM_LOW)
	endtask



	//目标类
	class obj2 extends obj1;
		bit [7:0] data1 = 'hcc;//这个data1并不会覆盖掉父类的data1
		//而是会分化成this.data1 和 super.data1
		//直接使用data1默认为this.data1
		`uvm_object_utils(obj2)
		function new();//构造函数
			//super.new(); 
			//如果你使用了extends,即使你不super.new,实际上系统还
			//是会帮你调用你父类的构造函数new  
			`uvm_info("class:obj2",$sformatf("data1:%x!",data1),UVM_LOW)
			`uvm_info("class:obj2",$sformatf("super.data1:%x!",super.data1),UVM_LOW)
			`uvm_info("class:obj2",$sformatf("this.data1:%x!",this.data1),UVM_LOW)
		endfunction
	endclass


	//组件类
	class comp1 extends uvm_component;
		`uvm_component_utils(comp1)
		function new(string name = "comp1",uvm_component parent = null);
			//组件类的构造函数,必须要有名字和指明挂载父类
			//parent = null 代表该组件被例化后默认挂载在uvm_root下
			super.new(name,parent);
			`uvm_info("class:comp1",$sformatf("handle is %s",name), UVM_LOW)
		endfunction
	endclass	

	//组件类
	class comp2 extends comp1;
		`uvm_component_utils(comp2)
		function new(string name = "comp2", uvm_component parent = null);
			super.new(name, parent);
			`uvm_info("class:comp2",$sformatf("handle is %s",name), UVM_LOW)
		endfunction
	endclass


	//UVM_TEST
	//可由run_test函数直接例化,并执行phase机制
	class test1 extends uvm_test;
		comp2 a,b,c;
		`uvm_component_utils(test1)
		function new(string name = "test1", uvm_component parent = null);
			super.new(name, parent);
		endfunction

		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			`uvm_info("test1",$sformatf("build"), UVM_LOW)
			a = new("a",null);//这个会被挂在root下
			b = new("b",this);//这个会被挂在test1下
			c = comp2::type_id::create("c",null);//使用工厂的实例化方法
		endfunction

		task run_phase(uvm_phase phase);
			phase.raise_objection(this);//进入run_phase需要先举手
			`uvm_info("test1",$sformatf("run0"), UVM_LOW)
			#1us;
			`uvm_info("test1",$sformatf("run1"), UVM_LOW)
			phase.drop_objection(this);//退出run_phase需要先落手
		endtask
	endclass



	//----------------------------类覆盖------------------------------
	//有类xy,且y是x子类
	//在类x中,声明了类a的句柄
	//在类y中,想把类a覆盖为类b,可以使用类覆盖
	//但类b也必须是类a的子类,经过测试a需要是组件类,而目标类跑不通。
	class a extends uvm_component;
		bit [3:0] va ='ha;
		`uvm_component_utils(a)
		function new(string name = "a", uvm_component parent = null);
			super.new(name, parent);
		endfunction
	endclass

	class b extends a;
		`uvm_component_utils(b)
		function new(string name = "b", uvm_component parent = null);
			super.new(name, parent);
			super.va = 'hb; //改变类a的属性
		endfunction
	endclass

	class x extends uvm_test;
		a handle0,handle1;

		`uvm_component_utils(x)
		
		function new(string name = "x", uvm_component parent = null);
			super.new(name, parent);
		endfunction
    		
		function void build_phase(uvm_phase phase);
      			super.build_phase(phase);
			handle0 = a::type_id::create("handle0",this);//使用工厂的实例化方法
			handle1 = a::type_id::create("handle1",this);//使用工厂的实例化方法
   			`uvm_info("x build phase",$sformatf("handle0.va=%x",handle0.va), UVM_LOW)
   			`uvm_info("x build phase",$sformatf("handle1.va=%x",handle1.va), UVM_LOW)
    		endfunction
	endclass

	 class y extends x;
    		`uvm_component_utils(y)
    		function new(string name = "y", uvm_component parent = null);
      			super.new(name, parent);
   		endfunction
    		function void build_phase(uvm_phase phase);
      			  set_type_override("a", "b");//类覆盖
			//另一个实现类覆盖的方法
      			//set_type_override_by_type(a::get_type(),b::get_type());
			super.build_phase(phase);
			//这个super是要放在后面的,因为要先替换后例化
    		endfunction
  	endclass

endpackage   //pack1尾

//--------------------------------------module1---------------------------------
module hardware1;
	import pack1::*;
	import uvm_pkg::*; //+UVM
	
	initial begin
		obj2 handle0;
		obj1 handle1;

		handle0 = new();

		handle1 = new();
		handle1.xxx();

		run_test("y");//直接例化test,并执行phase机制 
	end
		
endmodule
//----------------------------------------------------------------------------

//
//
//
//
//
//
//


interface interf1;
  logic [31:0] addr;
  logic [31:0] data;
endinterface

package pack2; //pack2头
	import uvm_pkg::*; //+UVM
  	`include "uvm_macros.svh"//+工厂
	
	//----------------------------config机制------------------------------
	//UVMconfig机制,在相对上层的位置,为相对下层的位置来配置信息,这个信息
	//大致有三种:虚接口、单一变量、对象	
	//上层把要传递的信息贴上标号,然后甩到某个UVM层级下,在questasim中sim栏
	//的instance中可以看到这个UVM层级关系。
	//下层要按照标号,去指定的层级搜索,由上层传递下来的配置信息
	
	//"虚接口"传递	
  	class comp2 extends uvm_component;
    		virtual interf1 vif;  
    		`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);
			//*
			if(!uvm_config_db#(virtual interf1)::get(this, "", "label0", vif))begin
				                             //到当前层级下找
						     	     //标号为label0的
							     //interf1的实例
							     //放入vif中
        			`uvm_error("config_db", "can't find label0 in this hierarchy!")
			end
			else begin
      				`uvm_info("config_db","config_success!", UVM_LOW)
			end
    		endfunction
  	endclass

	//"单一变量"传递
  	class comp1 extends uvm_component;
    		int value;
		`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);
			//*
			if(!uvm_config_db#(int)::get(this, "", "val", value))begin
				                             //到当前层级下找
						     	     //标号为val的
							     //放入value中
        			`uvm_error("config_db", "can't find val in this hierarchy!")
			end
			else begin
      				`uvm_info("config_db","config_success!", UVM_LOW)
      				`uvm_info("config_db", $sformatf("Value is %h!", value), UVM_LOW)
			end
    		endfunction
  	endclass

	//"对象"传递
	class obj1 extends uvm_object;
		bit [7:0] data0 = 'haa;
		`uvm_object_utils(obj1)
		function new();
			super.new();
		endfunction
	endclass
  	class comp0 extends uvm_component;
		obj1 o1;
		`uvm_component_utils(comp0)
    		function new(string name = "comp0", 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);
			//*
			if(!uvm_config_db#(obj1)::get(this, "", "object", o1))begin
				                             //到当前层级下找
						     	     //标号为object的
							     //放入o1中
        			`uvm_error("config_db", "can't find object in this hierarchy!")
			end
			else begin
      				`uvm_info("config_db","config_success!", UVM_LOW)
      				`uvm_info("config_db", $sformatf("o1.data0 is %h!", o1.data0), UVM_LOW)
			end
    		endfunction
  	endclass

//test--------------------------------------------------------------------------------
 	class uvm_config_test extends uvm_test;
 	   	comp2 c2;
 	   	comp1 c1;
 	   	comp0 c0;
		obj1 o;
 	   	`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);
 	       		c2 = comp2::type_id::create("c2",this);

			//单一变量传递
    			uvm_config_db#(int)::set
				(uvm_root::get(), "uvm_test_top.*", "val", 'ha5a5_5a5a);
 	       		c1 = comp1::type_id::create("c1",this);

			//对象传递
 	       		o = obj1::type_id::create();
			o.data0 = 8'haa;
    			uvm_config_db#(obj1)::set
				(uvm_root::get(), "uvm_test_top.*", "object",o);
 	       		c0 = comp0::type_id::create("c0",this);

 	   	endfunction
 	       	task run_phase(uvm_phase phase);
 	     		super.run_phase(phase);
 	     		phase.raise_objection(this);
 	     		#1us;
 	     		phase.drop_objection(this);
 	   	endtask
 	 endclass





endpackage   //pack2尾
//----------------------------------------------------------------------------


//--------------------------------------module2---------------------------------
module hardware2;
	import pack2::*;
	import uvm_pkg::*; //+UVM

  	interf1 if0();
	
	initial begin
		//虚接口传递
    		uvm_config_db#(virtual interf1)::set
			(uvm_root::get(), "uvm_test_top.*", "label0", if0);
        	//一共有五个参数
		//=>第一个参数指明要配置信息的类型:这里是虚接口
	        //=>第二个和第三个参数联合起来组成目标路径,就是你所配置的这个
		//  信息放到哪个层级下面,这里是:uvm_root->uvm_test_top->*。
		//  第二个参数必须是component实例的指针,即为真实存在的组件,这里用的是uvm_root。
		//  uvm_root::get()也可以写成null
		//  第三个参数是相对此实例的路径。
		//=>第四个参数是一个标号,相同标号的set和get才可以共享资源
		//=>第五个参数是具体的值
	
	        //接口传递应发生在run_test()之前。
		//这保证了组件在进入build_phase要get之前,
		//virtual interface已经被放入到特定区域中
		run_test("uvm_config_test"); 	
	end
		
endmodule


上一篇:UVM的树形结构是怎么创建的?


下一篇:数据连接字符串