ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UVM1-基础知识篇

2022-01-02 15:34:04  阅读:216  来源: 互联网

标签:component 基础知识 UVM UVM1 phase new super uvm


//------------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


标签:component,基础知识,UVM,UVM1,phase,new,super,uvm
来源: https://blog.csdn.net/helloworld573/article/details/122276818

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有