【IC验证】UVM实验lab01

news2024/11/16 11:48:54

1. 工厂的注册、创建和覆盖

1.1 注册

object组件使用宏'uvm_obeject_ultis(string name)来创建,component组件使用'uvm_object_ultis(string name, parent)来创建

	class trans extends uvm_object;/*定义*/
		bit[31:0] data;
		'uvm_object_ultis(trans)/*注册*/
		function new(string name = "trans");/*构建*/
			super.new(name);
			'uvm_info("CREATE", $sformatf("trans type [%s] created", name),UVM_LOW)
			/*使用宏来进行消息管理。'uvm_info(ID, message,verbosity)*/
		endfunction
	endclass

1.2 创建

	class object_create extends top;
		trans t1, t2, t3, t4;
		'uvm_component_ultis(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();/*创建uvm_factory实例*/
			super.build_phase(phase);
			/*对象的创建*/
			/*方法1,使用new函数来做*/
			t1 = new("t1");
			/*方法2,使用create*/
			/*string name = comp_type::type_id::create("string name", uvm_component parent = null)*/
			t2 = trans::type_id::create("t2", this);//trans是uvm_object类型的,为什么用component的来创建?
			/*方法3,使用uvm_factory的函数来做*/
			/*get_full_name()用于返回当前对象的完整层次名称 
			create_object_by_name (string requested_type_name,string parent_inst_path = "",string name = "")*/
			void'($cast(t3, f.create_object_by_type(trans::get_type(), get_full_name(), "t3")));
			/*方法4,使用create_object方法*/
			void'($cast(t4, create_object("trans", "t4")));//为什么要使用cast来实现类型转换
			/*因为 create_object_by_type 返回的是通用类型 uvm_object,为了使用对象的特定方法和属性,
			需要将其转换为具体的类型。这是通过 $cast 语句完成的*/
		endfunction		
	endclass

1.3 覆盖

	class object_override extends object_create;
		'uvm_component_ultis(object_override)
		function new(string name = "object_override", uvm_component parent = null);
			super.new(name, parent);
		endfunction	

		function void build_phase(uvm_pahse phase);
			set_type_override_by_type(trans, bad_trans, bit replace = 1);
			trans::type_id::set_type_override(bad_trans::get_type());//这种创建方法是不是也可以
			super.build_phase(phase);
		endfunction
	endclass

1.4 问题

为何对t1,t2,t3,t4报告名称不对

仿真器的原因,VCS可以。Questa Sim对于component组件可以传递进去name,但是object不行

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

2.1 域的自动化

		'uvm_object_utils_begin(trans)
			'uvm_field_int(addr, UVM_ALL_ON)
			'uvm_field_int(data, UVM_DEFAULT)
			'uvm_field_enum(op_t, op, UVM_ALL_ON)
			/*`uvm_field_enum(T, ARG,FLAG=UVM_DEFAULT),
			T is an enumerated type, ARG is an instance of that type*/
			'uvm_field_string(name, UVM_DEFAULT)
		'uvm_objectr_utils_end

2.2 compare()

do_compare是compare的回调函数,在调用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_warnning("CREATE", $sformatf(addr %8x != %8x, addr, t.addr))
			end
			if(data != t.data)begin
				do_compare = 0;
				'uvm_warnning("CREATE", $sformatf(addr %8x != %8x, data, t.data))
			end	
			if(op != t.op)begin
				do_compare = 0;
				'uvm_warnning("CREATE", $sformatf(addr %8x != %8x, op, t.op))
			end				
			if(name != t.name)begin
				do_compare = 0;
				'uvm_warnning("CREATE", $sformatf(addr %8x != %8x, name, t.name))
			end					
		endfunction
			is_equal = t1.compare(t2);
			uvm_default_compare.show_max = 10;
			/*uvm_default_compare 是一个默认的比较对象,用于控制比较时的显示行为。
			show_max 是它的一个属性,表示在比较时最多显示多少个不匹配项*/
			if(!is_equal)
				'uvm_warning("COMPARE", "t1 is not equal to t2")
			else
				'uvm_info("COMPARE", "t1 is equal to t2")

2.3 print() 与copy()

			'uvm_info("COPY", "Before uvm_object copy() taken", UVM_LOW)
			t1.print();
			uvm_default_printer = uvm_default_line_printer;/*修改打印的默认格式*/
			t2.print(();
			'uvm_info("COPY", "After uvm_object copy() taken", UVM_LOW)
			t1.copy(t2);/*将t2拷贝给t1*/
			uvm_default_printer = uvm_default_tree_printer;			
			t1.print();
			uvm_default_printer = uvm_default_line_printer;/*修改打印的默认格式*/
			t2.print(();	

3. phase机制

9个phase之间顺序执行,只有run_phase耗时因此采用task。run_phase必须有挂起和落下机制,否则该phase不被执行。run_phase与之对应的有12个并列的子Phase,12个子phase是顺序执行,但是和run_phase是并行执行。一般不建议在有run_phase的情况下采用其子phase   

  3.1 代码

	class comp2 extends uvm_component
		'uvm_component ultis(comp2)
		function new(string name = "comp2", uvm_component parent = null);
			super.new(name, parent);
			'uvm_info("CREATE", $sformatf("unit type [%s] create", name), UVM_LOW)
		endfunction
		
		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			'uvm_info("BUILD", "comp2 build_phase completed", UVM_LOW)
		endfunction
		
		function void connect_phase(uvm_phase phase);
			super.connect_phase(phase);
			'uvm_info("CONNECT", "comp2 connect_phase completed", UVM_LOW)
		endfunction

		task run_phase(uvm_phase phase);
			super.run_phase(phase);
			'uvm_info("RUN", "comp2 run_phase completed", UVM_LOW)
		endtask				

		function void report_phase(uvm_phase phase);
			super.report_phase(phase);
			'uvm_info("REPORT", "comp2 report_phase completed", UVM_LOW)
		endfunction		
	endclass
	
	class comp3 extends uvm_component
		'uvm_component ultis(comp3)
		function new(string name = "comp3", uvm_component parent = null);
			super.new(name, parent);
			'uvm_info("CREATE", $sformatf("unit type [%s] create", name), UVM_LOW)
		endfunction	
		
		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			'uvm_info("BUILD", "comp1 build_phase completed", UVM_LOW)
		endfunction
		
		function void connect_phase(uvm_phase phase);
			super.connect_phase(phase);
			'uvm_info("CONNECT", "comp1 connect_phase completed", UVM_LOW)
		endfunction

		task run_phase(uvm_phase phase);
			super.run_phase(phase);
			'uvm_info("RUN", "comp1 run_phase completed", UVM_LOW)
		endtask				

		function void report_phase(uvm_phase phase);
			super.report_phase(phase);
			'uvm_info("REPORT", "comp1 report_phase completed", UVM_LOW)
		endfunction		
	endclass	
	
	class comp1 extends uvm_component
		comp2 c2;
		comp3 c3;
		'uvm_component ultis(comp1)
		function new(string name = "comp1", uvm_component parent = null);
			super.new(name, parent);
			'uvm_info("CREATE", $sformatf("unit type [%s] create", name), UVM_LOW)
		endfunction	
		
		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			'uvm_info("BUILD", "comp1 build phase begin", UVM_LOW)
				c2 = comp2::type_id::create("c2", this);
				c3 = comp3::type_id::create("c3", this);				
			'uvm_info("BUILD", "comp1 build phase end", UVM_LOW)
		endfunction
		
		function void connect_phase(uvm_phase phase);
			super.connect_phase(phase);
			'uvm_info("CONNECT", "comp1 connect_phase completed", UVM_LOW)
		endfunction

		task run_phase(uvm_phase phase);
			super.run_phase(phase);
			'uvm_info("RUN", "comp1 run_phase completed", UVM_LOW)
		endtask				

		function void report_phase(uvm_phase phase);
			super.report_phase(phase);
			'uvm_info("REPORT", "comp1 report_phase completed", UVM_LOW)
		endfunction		
	endclass	
	
	class phase_order_test extends uvm_test
		comp1 c1;
		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 begin", UVM_LOW)
				c1 = comp2::type_id::create("c2", this);				
			'uvm_info("BUILD", "phase_order_test build phase end", UVM_LOW)
		endfunction
		
		function void connect_phase(uvm_phase phase);
			super.connect_phase(phase);
			'uvm_info("CONNECT", "phase_order_test connect_phase completed", UVM_LOW)
		endfunction

		task run_phase(uvm_phase phase);
			super.run_phase(phase);
			'uvm_info("BUILD", "phase_order_test task begin", UVM_LOW)
				phase.raise_objection(this);
					#1us;
				phase.drop_objection(this);
			'uvm_info("BUILD", "phase_order_test task end", UVM_LOW)
		endtask	

		task reset_phase(uvm_phase phase);
			'uvm_info("RESET", "reset_phase  begin", UVM_LOW)
				phase.raise_objection(this);
					#1us;
				phase.drop_objection(this);
			'uvm_info("RESET", "reset_phase  end", UVM_LOW)
		endtask				

		task main_phase(uvm_phase phase);
			'uvm_info("MAIN", "main_phase  begin", UVM_LOW)
				phase.main_objection(this);
					#1us;
				phase.main_objection(this);
			'uvm_info("MAIN", "main_phase  end", UVM_LOW)
		endtask	
	endclass

   3.2 仿真结果

从仿真结果可以看出来,run_phase和main_phase, reset_phase都是在1us的时候仿真结束。

3.3 问题

为什么是在c1关于run_phase所有的信息被打印完了以后才去打印c2和c3的run_phase相关信息呢?

因为一旦进入c1的run_phase,就必须得要等到执行完毕退出以后才能去执行其他的,而c1的run_phase是有时延的。在每个 run_phase 和子phase方法中,如果包含了延迟或等待语句(如 #1us),那么仿真时间会在该方法中停留,直到延迟结束后才会继续执行下一个组件的 run_phase。但是各个组件的其他phase可以并行执行

4. config机制

4.1 代码

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] has been created", name), UVM_LOW)
		endfunction
	endclass
	
	class comp2 extends uvm_component;
		int var2;
		virtual uvm_config_if vif;
		config_obj cfg;
		'uvm_object_utils(comp2)
		function new(string name = "comp2", uvm_component parent = null);
			super.new(name, parent);
			var2 = 200;
			'uvm_info("CREATE", $sformatf("unit type [%s] has been 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("GET VIF", "no virtual interface is assigned")
		
			'uvm_info("GET INT", $sformatf("before config get, var2 = %0d", var2), UVM_LOW)
			uvm_config_db#(int)::get(this, "", "var2", var2);
			'uvm_info("GET INT", $sformatf("after config get, var2 = %0d", var2), UVM_LOW)	

			uvm_config_db#(config_obj)::get(this, "", "cfg", cfg);
			'uvm_info("GET OBJ", $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 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] has been created", name), UVM_LOW)
		endfunction
	endclass
	
	class comp1 extends uvm_component;
		int var1;
		virtual uvm_config_if vif;
		config_obj cfg;
		comp2 c2;
		'uvm_object_utils(comp1)
		function new(string name = "comp2", uvm_component parent = null);
			super.new(name, parent);
			var1 = 100;
			'uvm_info("CREATE", $sformatf("unit type [%s] has been 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("GET VIF", "no virtual interface is assigned")
		
			'uvm_info("GET INT", $sformatf("before config get, var1 = %0d", var1), UVM_LOW)
			uvm_config_db#(int)::get(this, "", "var1", var1);
			'uvm_info("GET INT", $sformatf("after config get, var1 = %0d", var1), UVM_LOW)	

			uvm_config_db#(config_obj)::get(this, "", "cfg", cfg);
			'uvm_info("GET OBJ", $sformatf("after config get, cfg.comp1_var = %0d", cfg.comp1_var), UVM_LOW)				
		
			'uvm_info("BUILD", "comp1 build phase exited", 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 exited", UVM_LOW)			
		endtask
	endclass
endpackage

4.2 仿真结果

5. 消息管理

set_report_verbosity_level_hier(UVM_NONE);/*冗余度高于UVM_NONE的都不会被打印出来*/
set_report_id_verbosity_hier("BUILD", UVM_NONE);/*只对BUILD ID做限制*/
uvm_root::get().set_report_id_verbosity_hier("BUILD", UVM_NONE);/*从顶层做配置*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1788787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML如何让文字底部线条不紧贴在文字下面(既在内容下方又超出内容区域)

hello,大家好,星途星途今天给大家带来的内容是如何让文字底部线条不紧贴在文字下面。 话不多说,先上效果图 简单来说就是padding和margin的区别。 在网页设计中,有时我们想要给某个元素添加一个装饰性的线条,比如底部…

【面试题-004】ArrayList 和 LinkList区别

文章目录 List和setArrayList扩容机制HashMap扩容机制HashMap初始容量(Initial Capacity)和负载因子(Load Factor)HashMap与HashTable区别 ?HashMap底层数据结构?ConcurrentHashMap底层数据结构&#xff1f…

HTML静态网页成品作业(HTML+CSS)—— 美食湘菜介绍网页(5个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有5个页面。 二、作品演示 三、代…

AI 正在攻克难题——赋予计算机嗅觉

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

NLP(1)-TF-IDF算法介绍

一、TF-IDF算法介绍 TF-IDF(term frequency–inverse document frequency,词频-逆向文件频率)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术。 TF-IDF是一…

Java:流程控制语句

文章目录 一、顺序结构二、分支结构2.1 if2.2 switch 三、循环结构3.1 for3.2 while3.3 do...while 四、流程控制4.1 break4.2 continue 五、结语 一、顺序结构 顺序结构语句是Java程序默认的执行流程,按照代码的先后顺序,从上到下依次执行。 二、分支结…

理解NSCopying协议

NSCopying 协议用于让对象能够被复制。实现这个协议的类需要定义如何创建该对象的副本。这个副本是独立的,不会与原对象共享内存地址。 为什么需要 NSCopying 协议? 当你需要复制对象时,例如将对象存储到一个集合(如数组、字典&…

锐捷校园网自助服务-字符过滤存在缺陷

锐捷校园网自助服务-字符过滤存在缺陷 漏洞介绍 令人感到十分遗憾的是,锐捷网络安全应急响应中心对漏洞上报似乎缺少了一些奖励,令人对官方上报漏洞失去了些许兴趣​。 该缺陷仅仅打破了安全检查防护,并没有造成实质性危害,至于…

ChatGPT成知名度最高生成式AI产品,使用频率却不高

5月29日,牛津大学、路透社新闻研究所联合发布了一份生成式AI(AIGC)调查报告。 在今年3月28日—4月30日对美国、英国、法国、日本、丹麦和阿根廷的大约12,217人进行了调查,深度调研他们对生成式AI产品的应用情况。 结果显示&…

Ubuntu22.04下源码编译安装pythonocc-7.8

Ubuntu22.04下源码编译安装pythonocc-7.8 本文介绍Ubuntu下手动编译安装pythonocc,及安装过程遇到的各种坑 基本依赖安装 sudo apt-get update sudo apt-get install -y wget libglu1-mesa-dev libgl1-mesa-dev libxmu-dev libxi-dev build-essential cmake libf…

Angular17(1):使用Angular CLI创建空项目

要创建一个空的 Angular 项目,可以使用 Angular CLI(命令行界面)。以下是使用 Angular CLI 创建一个新项目的步骤: 1、安装 Angular CLI: 打开你的命令行界面(在 Windows 上是 CMD、PowerShell 或 Git Bas…

浮点数精度问题(详细)

文章目录 1.什么是浮点数2. 二进制与十进制的转换2.1 二进制与十进制的相互转换(方法介绍,思维理解)2.2 在线转换工具 3.浮点数的 IEEE754 表示4.C# 浮点型float、double 、decimal 比较5.解决运算精度问题5.1 浮点数预算精度问题5.2 解决方案5.2.1 放大倍数计算5.2…

基于PHP+MySQL开发的一套游泳馆预约报名小程序开发源码模板

最近新开发了一套游泳馆线上预约报名小程序,其主要功能有预约功能,报名功能,支付功能,个人中心,订单管理,商品管理等等。 游泳馆预约报名小程序系统-运行环境 开发语言:PHP 数据库:M…

升级SVN服务器web管理工具EasyPHP17.1

1、卸载EasyPHP12.1,删除C盘安装路径下C:\Program Files (x86)\EasyPHP12**文件 2、安装EasyPHP-Devserver-17.0-setup,链接见下方官网地址 PHP DEVSERVER | LOCAL PHP DEVELOPMENT ENVIRONMENTA complete and ready-to-use PHP development environmen…

MySQL 自定义函数(实验报告)

一、实验名称: 自定义函数 二、实验日期: 2024年 6 月 1 日 三、实验目的: 掌握MySQL自定义函数的创建及调用; 四、实验用的仪器和材料: 硬件:PC电脑一台; 配置:内存&#…

LabVIEW实现汽车逆变器功能测试系统

​介绍了如何利用LabVIEW开发汽车逆变器(包括功率板和控制板)的自动测试设备(ATE),实现对额定800V电压、300A电流的逆变器进行功能测试。系统通过CAN2.0通讯协议,实现电机控制、温度传感器监测、电压校验和…

docker一键部署EFK系统(elasticsearch filebeat kibana metricbeat es-head)

EFK日志系统搭建 EFK日志系统介绍功能需求搭建elasticsearch集群规划前提部署核对证书及权限 EFK日志系统介绍 Elasticsearch 是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于…

7、css3实现边框不停地跑动效果

效果例图&#xff1a; 1、上html代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><meta …

百分之九十的人都忽视了JMeter响应断言中的这个实用功能—— Jmeter Variable Name to use

JMeter的响应断言 相信对于使用过JMeter的同学来学&#xff0c;一定都使用过响应断言&#xff0c;在这里我就不相信介绍了&#xff0c;我们可以简单的理解为&#xff1a; JMeter的响应断言是一种用于检查测试中得到的响应数据是否符合预期的工具&#xff0c;旨在保证性能测试…

挑战你的数据结构技能:复习题来袭【6】

1. (单选题)设无向图的顶点个数为n,则该图最多有&#xff08;&#xff09;条边 A. n-1 B. n(n-1)/2 C. n(n1)/2 D. 0 答案&#xff1a;B 分析&#xff1a; 2. (单选题)含有n个顶点的连通无向图,其边的个数至少为()。 A. n-1 B. n C. n1 D. nlog2n 答案&#xff1a;A…