04、UVM核心基类

目录

一、uvm_object类

 二、域的自动化

三、拷贝copy

四、比较compare

五、打印print

六、打包和解包pack&unpack


一、uvm_object

  • UVM中的类最初都是从一个uvm_void根类(root class)继承而来的,而实际上这个类并没有成员变量和方法。
  • uvm_void只是一个虚类(virtual class),还在等待将来继承于它的子类去开垦。在继承于uvm_void的子类中,有两个类,一个为uvm_object类,另一个为uvm_port_base类。
  • 在UVM的类库地图中,除了事务接口(transaction interface)类继承于uvm_port_base,其他所有的类都是从uvm_object类一步步继承而来的。
  • uvm_object的核心方法主要提供与数据操作的相关服务,包括copy、clone、compare、print、pack/unpack。

 二、域的自动化  

         域:类的成员变量

  • UVM通过域的自动化,使得用户在注册UVM类的同时也可以声明今后会参与到对象拷贝、克隆、打印等操作的成员变量。
  • 域的自动化使得在使用uvm_object提供的一些预定义方法时,非常便捷,无需再实现自定义方法。
  • 熟悉域的自动化常用的宏之后,还需要考虑哪些成员变量在注册UVM类(`uvm_{component,object}_utils)的时候,也一并将它们归置到对应的域列表中,以便为稍后的域方法提供可以自动实现的基础。
class box extends uvm_object;
	int volume = 120;        //int类型
	color_t color = WHITE;   //枚举类型
	string name = "box";     //string类型

	`uvm_object_utils_begin(box)
		//*****域的自动化的声明*****
		`uvm_field_int(volume, UVM_ALL_ON)
		`uvm_field_enum(color_t, color, UVM_ALL_ON)
		`uvm_field_string(name, UVM_ALL_ON)
	`uvm_object_utils_end
	...
endclass

box b1, b2;

initial begin
	b1 = new("box1");
	b1.volume = 80;
	b1.color = BLACK;
	b2 = new();
	b2.copy(b1);		//copy会把b1的成员变量也拷贝给b2,copy方法是UVM自动实现的,前提是做域的自动化声明       SV中copy方法是自己实现的,而UVM中是自动实现的
	b1.name = "box2";
end

三、拷贝copy

在UVM的数据操作中,copy默认已经创建好了对象,只需要对数据进行拷贝,而clone则会自动创建对象并对source object进行数据拷贝,再返回target object句柄。无论是copy还是clone都需要对数据进行复制。在进行copy时,默认进行的是深拷贝,即会执行copy()和do_copy()。

扫描二维码关注公众号,回复: 16440959 查看本文章
class ball extends uvm_object;
	int diameter = 10;
	color_t color = RED;
	`uvm_object_utils_begin(ball)
		`uvm_field_int(diameter, UVM_DEFAULT)
		`uvm_field_enum(color_t, color, UVM_NOCOPY)
	`uvm_object_utils_end
	...
	function void do_copy(uvm_object rhs);
		ball b;
		$cast(b, rhs);
		$display("ball::do_copy entered...");
		if(b.diameter <= 20) begin
			diameter = 20;
		end
	endfunction
endclass

class box extends uvm_object;
	int volume = 120;
	color_t color = WHITE;
	string name = "box";
	ball b;
	`uvm_object_utils_begin(box)
		`uvm_field_int(volume, UVM_ALL_ON)
		`uvm_field_enum(color_t, color, UVM_ALL_ON)
		`uvm_field_string(name, UVM_ALL_ON)
		`uvm_field_object(b, UVM_ALL_ON)		//深拷贝
	`uvm_object_utils_end
	...
endclass

box b1, b2;

initial begin
	b1 = new("box1");
	b1.volume = 80;
	b1.color = BLACK;
	b2 = new();
	b2.copy(b1);
	b1.name = "box2";
	$display("%s", b1.sprint());
	$display("%s", b2.sprint());
end

四、比较compare

function bit compare(uvm_object rhs, uvm_comparer comparer=null);

默认情况下,如果不对比较的情况作出额外配置,可以在调用compare()方法时,省略第二项参数,即采用默认的比较配置。比较方法经常会在两个数据类中进行,例如从generator产生的一个transaction(数据类),和在设计输出上捕捉的transaction(数据类),如果它们为同一种类型,除了可以自定义数据比较之外,也可以直接使用uvm_object::compare()函数来实现数据比较和消息打印。
 

class box extends uvm_object;
	int volume = 120;
	color_t color = WHITE;
	string name = "box";
	ball b;
	`uvm_object_utils_begin(box)
		`uvm_field_int(volume, UVM_ALL_ON)
		`uvm_field_enum(color_t, color, UVM_ALL_ON)
		`uvm_field_string(name, UVM_ALL_ON)
	`uvm_object_utils_end
	...
endclass

box b1, b2;

initial begin
	b1 = new("box1");
	b1.volume = 80;
	b1.color = BLACK;
	b2 = new("box2");
	b2.volume = 90;
	if(!b2.compare(b1)) begin
		`uvm_info("COMPARE", "b2 compared with b1 failure", UVM_LOW)
	end
	else begin
		`uvm_info("COMPARE", "b2 compared with b1 success", UVM_LOW)
	end
end

在上面的两个对象比较中,会将每一个自动化的域进行比较,所以在执行compare()函数时,内置的比较方法也会将比较错误输出。默认的比较器,即uvm_package::UVM_default_comparer最大输出的错误比较信息是1,也就是说当比较错误发生时,不会再进行后续的比较。实际上,在uvm_object使用到的方法compare()、print()和pack(),如果没有指定数据操作配置对象作为参数时,会使用在uvm_pkg中例化的全局数据操作配置成员。
 

五、打印print

打印方法是核心基类提供的一种便于开发和调试的功能,通过field automation,使得声明之后的各个成员域会在调用uvm_object::print()函数时自动打印出来。相比于在仿真中设置断点,逐步调试,打印是另一种调试方式,好处在于可以让仿真继续进行,会在最终回顾执行过程中,从全局理解执行的轨迹和逻辑。
 

class box extends uvm_object;
	int volume = 120;
	color_t color = WHITE;
	string name = "box";
	ball b;
	`uvm_object_utils_begin(box)
		`uvm_field_int(volume, UVM_ALL_ON)
		`uvm_field_enum(color_t, color, UVM_ALL_ON)
		`uvm_field_string(name, UVM_ALL_ON)
	`uvm_object_utils_end
	...
endclass

box b1;
uvm_table_printer local_printer;
initial begin 
	b1 = new("box1");
	local_printer = new();
	$display("default table printer format");
	b1.print();
	$display("default line printer format");
	uvm_default_printer = uvm_default_line_printer;
	b1.print();
	$display("default tree printer format");
	uvm_default_printer = uvm_default_tree_printer;
	b1.print();
	$display("customized printer format");
	local_printer.knobs.full_name = 1;
	b1.print(local_printer);
end

六、打包和解包pack&unpack

function int pack(ref bit bitstream[], input uvm_packer packer=null);

function int unpack(ref bit bitstream[], input uvm_packer packer=null);

pack是为了将自动化声明后的域(标量)打包为比特流,即将各个散乱的数据,整理到bit数据串中,类似于struct packed的整理方式,但又能充分利用数据空间,也更容易与硬件之间进行数据传递和比对。
unpack则是将串行数据解包变为原有的各自域,该操作适用于从硬件一侧接受串行数据,进行校验之后,还原为软件一侧对象中各自对应的成员变量。
 

box b1, b2;
bit packed_bits[];
initial begin 
	b1 = new("box1");
	b2 = new("box2");
	b1.volume = 100;
	b1.height = 40;
	b1.color = RED;
	b1.print();
	b1.pack(packed_bits);
	$display("packed bits stream size is %d\n", packed_bits.size());
	b2.unpack(packed_bits);
	b2.print();
end

猜你喜欢

转载自blog.csdn.net/Arvin_ing/article/details/127567658