【IC验证】UVM实验lab01

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);/*从顶层做配置*/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工业无线wifi系统搭配高速路由,解决联网及数据传输

​面对日益复杂的工业应用场景,企业对无线网络的高速、可靠和安全提出了更高要求。星创易联SR600系列多网口4G路由器应运而生,为工业无线WiFi系统提供了一个性能卓越的高速路由方案。(key-iot.com/iotlist/sr600-5.html) SR600路由器集4G LTE、虚拟专用…

机器学习算法 —— 基于鸢尾花数据集的逻辑回归分类

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 实践演示基于鸢尾花(iris)数据集的逻辑回归分类库函数导入数据读取/载入数据信息简单查看可视化展示利用逻辑回归模…

香橙派 Orange AIpro 测评记录视频硬件解码

香橙派 Orange AIpro 测评记录视频硬件解码 香橙派官网:http://www.orangepi.cn/ 收到了一块Orange Pi AIpro开发板,记录一下我的测评~测评简介如下:1.连接网络2.安装流媒体进行硬件解码测试3.安装IO测试 简介 Orange Pi AI Pro 是香橙派联合…

Python爬虫协程批量下载图片

import aiofiles import aiohttp import asyncio import requests from lxml import etree from aiohttp import TCPConnectorclass Spider:def __init__(self, value):# 起始urlself.start_url value# 下载单个图片staticmethodasync def download_one(url):name url[0].spl…

【前端 - Vue】Vuex基础入门,创建仓库的详细步骤

🚀 个人简介:6年开发经验,现任职某国企前端负责人,分享前端相关技术与工作常见问题~ 💟 作 者:前端菜鸟的自我修养❣️ 📝 专 栏:vue从基础到起飞 🌈 若有帮助&…

云手机定位切换,带来的不只是便利

当我们利用云手机的定位切换时,首先感受到的确实是极大的便利。 我们就像是拥有了瞬间移动的超能力,可以自由地在不同城市、甚至不同国家的虚拟场景中穿梭。无论是为了更精准地获取当地的信息,比如实时的交通状况、特色店铺等,还…

Redis位图

简介 在我们平时开发过程中,会有一些bool型数据需要存取,比如用户一年的签到记录,签了是1,没签是0,要记录365天。如果使用普通的key/value,每个用户要记录365个,当用户上亿的时候,需…

Git存储库的推送保护

Git存储库的推送保护 昨天有一个提交一直提示:Push rejected Push rejected Push master to origin/master was rejected by remote起初在网络上找各种解决办法,先列举以下找到的各类方法 提交用户的用户名和邮箱与Git不一致,这个只需要通…

MATLAB设计ATF教程

打开Control System Designer 在MATLAB命令行窗口输入sisotool 出现如下Control System Designer窗口 基础Compensator 打开工具后,Compensator初始为1,需要按照需求进行设计。本示例的传递函数为: 基于上述传递函数的Bode图进行后续的设计…

SecureFX[po破] for Mac FTP/SSH传输工具[解] 安装教程

Mac分享吧 文章目录 效果一、准备工作二、开始安装注意: SecureFX 和 SecureCRT 不能同时都放在应用程序中安装,一定要一个在应用程序中,另一个在桌面上使用!否则会导致一个操作不成功!将SecureFX软件拖到桌面&#x…

Docker桥接网络分析

前言 《虚拟局域网(VLAN)》一文中描述了虚拟网卡、虚拟网桥的作用,以及通过iptables实现了vlan联网,其实学习到这里自然就会联想到目前主流的容器技术:Docker,因此接下来打算研究一下Docker的桥接网络与此有何异同。 猜测 众所周知…

将Java程序打包为为.exe文件

将Java程序打包为为.exe文件 将Java程序打包为为.exe文件分为俩个步骤: 1、将Java程序打包成Jar包(此时就可复制桌面便于使用) 2、打包为.exe文件(需要借助工具) 一、打包为.exe文件 1. file -> Project Structure…

linux网络基础 DHCP和ftp 02

一、DHCP DHCP:动态主机配置协议。 1、DHCP原理 服务端和客户端 服务端:提供某种特定的服务客户端:使用这种特定的服务c/s client/servre 客户端 服务端 应用程序之间通过端口进行通信,实现c/sb/s browser/server 浏览器 服务…

深度学习——卷积神经网络(CNN)

深度学习 深度学习就是通过多层神经网络上运用各种机器学习算法学习样本数据的内在规律和表示层次,从而实现各种任务的算法集合。各种任务都是啥,有:数据挖掘,计算机视觉,语音识别,自然语言处理等。‘ 深…

生成式AI时代已来,你是否做好了准备?

面对正在来临的生成式AI时代,从个人到企业,都应该为之做好充足的准备。 生成式AI时代的黎明已经来临 “生成式AI时代的黎明已经来临,它将会改变我们每个人的生活和工作方式、改变每一个行业。”在近日召开的2024亚马逊云科技中国峰会上&#…

甲方的苛刻,是成就优质作品的必要条件,辩证看待。

取其上、得其中,取其中,得其下,取其下、则无所的。在进行B端界面的设计的时候,设计师除了自我加压外,还少不了客户的严格要求,贝格前端工场为大家辩证分析一下。 一、严格产出高品质作品 甲方提出苛刻的要…

vue改造四级树状可输入table

vue改造四级树状可输入table <template><div class"dimension_wary"><div class"itemHeader"><div class"target"></div><div class"sort">X2</div><div class"weight">…

使用Ollama+OpenWebUI本地部署Gemma谷歌AI开放大模型完整指南

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;AI大模型部署与应用专栏&#xff1a;点击&#xff01; &#x1f916;Ollama部署LLM专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月4日10点50分 &#x1f004;️文章质量&#xff1…

2024年工业设计与智能城市国际会议(ICIDSC 2024)

2024 International Conference on Industrial Design and Smart Cities 【1】大会信息 大会时间&#xff1a;2024-07-26 大会地点&#xff1a;中国三亚 截稿时间&#xff1a;2024-07-12(以官网为准&#xff09; 审稿通知&#xff1a;投稿后2-3日内通知 会议官网&#xff1a;…

从实战案例来学习结构化提示词(一)

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识,包括但不限于AI科普,AI工具测评,AI效率提升,AI行业洞察。关注我,AI之…