UVM学习小结

UVM学习小结

1、UVM是一种用于验证数字设计标准化的简单方法,其优势是:
1)第一种自动化方法和第二种自动化类库的集合;
2)贯穿于验证平台的可重用性;
3)通用的验证平台开发;
4)供应商和模拟器独立;
5)高智能的验证平台(即从预先设计的覆盖计划中产生合法的激励);
6)即插即用的验证IP;
7)支持CDV(覆盖率驱动)验证;
8)支持CRV(受限随机)验证;
9)支持寄存器模型;
10)UVM在Accelerate System Initialive 下标准化。

2、对UVM的理解?
1)模块化和可重用性:该验证方法被分为模块化组件(驱动程序,序列发生器,代理,env等),可以将组件级别之间的组件重用于多单元或芯片级别验证以及跨项目。
2)将测试用例与验证平台分开:测试用例与实际的测试平台层次结构分开,因此可以在不同的单元或跨项目中重用激励。
3)独立于仿真器:所有仿真器都支持基类库和方法,因此不依赖于任何特定的仿真器。
4)更好地控制激励产生:sequence方法可以很好地控制激励的产生。有一些方法可以开发序列,包括随机化,layer sequence,virtual sequence等,它们提供了良好的控制和扩展激励生成的能力。
5)轻松配置:configure机制简化了具有深层次结构的对象的配置。configure机制有助于根据验证环境轻松配置不同的测试平台组件,而无需担心任何组件在测试平台层次结构中的深度。
6)factory机制:factory机制简化了组件的修改。使用工厂创建每个组件使它们可以在不同的测试或环境中被覆盖,而无需更改底层代码库。

3、哪个方法可以激活UVM验证平台,如何调用它?
run_test()方法(静态方法)用来激活UVM验证平台。通常在顶层的“initial begin…end”块中调用,并且它使用一个参数指定要运行的test case。run_test()方法在build_phase()中执行test class的构造函数,并进一步构造层次化的env/agent/driver/sequencer。

4、在UVM方法学中仿真如何结束?
UVM具有分阶段(phase)执行,该执行由一组构建阶段,运行阶段和检查阶段组成。
在运行阶段执行实际的仿真,并且在此阶段中每一个组件都可以在开始时raise objection 并保留该objection直到完成其仿真行为为止。一旦所有组件都drops objection则运行阶段完成,然后所有组件的check()阶段执行,最后测试结束。
这是正常仿真结束的方式,但是如果某些组件由于设计或测试平台中的错误而挂起,仿真超时(timeouts)也可以控制仿真结束。

5、如何在UVM中实现仿真超时机制(simulation timeout mechanism)?
如果由于某些错误导致超出最大仿真时间,仿真超时机制可以帮助停止仿真。在UVM中有一个很方便的函数set_global_timeout(timeout)用于将uvm_top.phase_timeout变量设置为超时值。如果run()phase在超时值之前没有结束,则仿真将停止并报告错误。

6、uvm_component与uvm_object之间有什么区别?
uvm_component:
准静态实体(在构建阶段之后,它在整个模拟过程中可用)
始终连接到给定硬件(DUT接口)或TLM端口
具有用于控制仿真行为的phase机制
配置组件拓扑结构
uvm_object:
动态实体(在需要时创建,从一个组件转移到另一个组件然后取消引用)
不连接到给定的硬件或任何TLM端口
没有phase机制

7、宏uvm_component_utils() 和 宏uvm_object_utils()的优势和区别是什么?
utils宏定义了保证对象/组件进行正确factory操作所需的基础结构。
有两个宏的原因是factory设计模式固定了构造函数可以用于的参数数量。从uvm_object派生的类具有带一个参数的构造函数,即字符串名称。从uvm_component派生的类有两个参数,一个名称和一个uvm_component父类。
两个uvm__ * __utils宏插入代码,提供了factory模式create( )方法,该方法将调用委托给uvm_object或uvm_component的构造函数。需要使用相应的宏,以便传递正确的构造函数参数,这意味着在拓展这些类时,为了能够使用UVM factory模式,无法添加额外的构造函数参数。

8、UVM验证平台为什么要phase机制/phase机制弥补了SV验证平台的什么不足?
SV的验证环境构建中,传统的硬件设计模型在仿真开始前,已经完成例化和连接了,而SV的软件部分对象例化则需要在仿真开始后执行。虽然对象例化通过调用构建函数new()来实现,但是单单通过new()函数无法解决在验证环境实现层次化时,无法保证例化的先后关系,以及各个组件在例化后的连接。如果需要实现高级功能,例如在顶层到底层的配置时,SV也无法在底层组件例化之前完成对底层的配置逻辑。
因此,UVM在验证环境构建时,引入了phase机制,通过该机制可以将UVM仿真阶段层次化,不单单是各个phase的先后执行顺序,而且处于同一phase中的层次化组件之间的phase也有先后关系。

9、UVM方法学中phase的概念是什么?
不同于基于module的验证测试平台(所有module静态地存在于层次结构中)基于class的验证测试平台需要管理不同对象的创建和其方法的执行。
Phase使得验证平台具有一致的执行流程,测试的执行可以分为以下任务-配置(configuration)创建验证平台组件(creation),运行激励(stimulus)和测试检查结束(end of test checks)。

10、UVM phase如何启动?
通过在顶层模块中调用run_test(test1)来启动UVM phase。当调用run_test()方法时,它首先创建一个test_top的对象然后调用所有phase。

11、为什么建议配置放在对象创建之前?
这是为了将所需配置的变量事先嵌入uvm_config_db进行存储,而在后续子一级组件例化并进入build_phase()从uvm_config_db获得配置时,可以确保所配置的变量都已先于子一级组件进行配置,避免出现配置变量无法获取的现象。

12、为什么build_phase是自顶而下而connect_phase是自底而上?
connect_phase旨在用于在组件之间建立TLM类型的连接,这就是它在构建阶段之后发生的原因。它自底而上工作,以便在设计层次结构中获得正确的实现,如果从上而下工作,这是不可能的。

13、用户是否可以自定义UVM中的phase?
除了UVM中可用的预定义uvm_phase之外,用户还可以选择将自己的phase添加到组件中,这通常通过拓展uvm_phase类和使用构造函数调用super.new来完成,new有三个参数:①阶段任务或功能的名称②自上而下或自下而上的阶段③任务或功能。

14、什么是objection机制?
UVM中objection机制是允许组件之间的分层状态通信,这有助于决定验证结束的时间。
每个内置phase都有一个内置的objection机制,它为组件和对象提供了一种同步其测试活动的方法,并指示何时可以安全地结束phase,最终确定验证进程的结束。
组件或sequence将在活动开始时raise objection(提起异议),该活动必须在phase结束之前完成,因此将在该活动结束时drop objection(撤销异议)。一旦所有被raise的objection都被drop,phase就会终止。

15、什么是UVM drian time?
drain time是指设置的所有objection结束之后、仿真结束之前的时间。

16、测试用例如何从仿真的命令行启动?
在top模块中写run test( ),即不要变量中提供任何内容。然后在命令行中添加:+UVM_TESTNAME = test1,启动测试用例名为test1的测试用例。

17、new( )和create之间的区别是什么?
我们都知道用于对象实例分配内存的new()方法,在UVM(OVM)中,create方法可以从factory创建对象实例,这允许使用factory重载时将所需对象替换为不同类型的对象,而无需重新编码。

18、模块和基于class的tb的区别有哪些?
模块是仿真期间始终存在的静态对象。
class是一个动态对象,因此它们可以在仿真的生命周期中来去。
特别指出:interface是静态对象,因此只能用于top、模块等静态对象中,driver为动态的对象类,因此driver等类中使用的为virtual interface,通过虚的指针指向实际的interface。

19、如何在component或者sequence中访问DUT中的信号?
接口信号:可以通过指向具体interface的virtual interface访问;
DUT内部信号可以通过信号路径访问。

20、driver类方法哪个是阻塞调用,哪个是非阻塞调用?
阻塞调用:get()、get_next_item()、peek();
非阻塞调用:try_next_item()、item_done()、put()。

21、driver中带和不带有参数的item_done()调用有什么区别?
item_done()方法是driver中的一种非阻塞方法,用于在get_next_item()或try_next_item()成功之后与sequencer完成握手。如果不需要发回响应,则调用不带参数的item_done()。如果需要发回响应,则将指向sequence_item的指针作为item_done()参数。

22、UVM driver类中的get_next_item()和get()方法之间有什么区别?
get_next_name():是一个阻塞调用,用于从sequencer FIFO获取sequence_item。driver驱动完sequence_item后需要先使用item_done()完成握手,然后再使用get_next_item()请求新的sequence_item。
get():也是一个阻塞调用,同样适用于从sequencer FIFO获取sequence_item。但是再使用get()时,由于get()方法隐式完成了握手,因此无法显示调用item_done()。

23、get_next_item()和try_next_item()有什么区别?
get_next_item():是一个阻塞调用,直到存在可供驱动的sequence_item为止,并返回指向sequence_item的指针。
try_next_item():是非阻塞调用,如果没有可供驱动的sequence_item,则返回空指针。

24、解释sequence和driver之间的握手协议?
UVM将sequence_item从sequence传输到driver并收集来自driver的响应。
在sequence端:
1)start_item(< item >):请求sequence访问driver。
2)finish_item(< item >):使driver接收sequence_item,这是阻塞调用,在driver调用item_done()方法后才返回。
在driver端
1)get_next_item(reg):这是driver中的一个阻塞方法,直接接收到sequence_item,driver可以将其转换为引脚级协议信号。
2)item_done(reg):向sequencer发出信号,表明它可以接收新的sequence请求,是的sequence解除对finish_item()方法的阻塞。

25、流水线和非流水线sequence-driver模式有什么区别?
根据设计接口如何激励模式,分为两种sequence-driver模式。
1)非流水线模式:如果driver一次仅驱动一个事务,则称为非流水线模型。在这种情况下,sequence可以将一个事务发送给driver,并且driver可能需要几个周期(基于接口协议)才能完成驱动该事务。只有在该事务完成驱动后,driver才会接受sequencer的新事务。
2)流水线模式:如果driver一次驱动多个事务,则称为流水线模式。在这种情况下,sequence可以继续向driver持续发送新事务,而无需等待driver中都会有一个单独的进程来驱动该事务,而不用等到它完成上一次事务的驱动之后在接受新事务。如果我们不需要等待设计的响应,则此模式很有用。

26、我们如何确保在driver驱动多个sequences时,则driver的响应会发送给正确的sequences?
如果从driver返回了几个sequences之一的响应,则sequencer利用sequence中的sequence ID字段将响应返回给正确的sequence。driver中的响应处理代码应调用set_id_info(),以确保任何响应都具有与其原始请求相同的sequence ID。

27、什么是m_sequencer句柄?
启动sequence时,它始终与启动sequencer相关联。m_sequencer句柄包含该sequencer的引用,使用此句柄,sequence可以访问UVM组件层次结构信息。

28、什么是p_sequencer句柄?与m_sequencer相比有什么不同?
与sequencer,driver或monitor等UVM组件在整个仿真周期内存在不同,UVM sequence是生命周期有限的对象。因此,如果在sequence从测试平台层次结构(组件层次结构)访问任何成员或句柄,则需要运行该sequence的sequencer的句柄。
m_sequencer是uvm_sequencer_base类型的句柄,默认情况下在uvm_sequence中可用。但是要访问在真实的sequencer,我们需要对m_sequencer进行转换(typecast),通常称为p_sequencer。下面是一个简单的示例,其中sequence要访问clock monitor组件的句柄。

29、运行sequence需要什么步骤?
启动sequence需要三个步骤:
1)创建一个序列,使用工厂创建方法创建一个序列

my_sequence_c seq;
	seq = my_sequence_c ::type_id ::create("my_seq")

2)配置或随机化序列

seq.randomize()

3)开始一个sequence。使用sequence.start()方法启动序列。start方法需要输入一个指向sequencer的参数。关于sequence的启动,UVM进一步做了封装。

30、在sequencer上启动sequence时,如何指定sequence的优先级?
通过将优先级相对值参数传给sequence的start()方法来指定优先级,第三个参数指定优先级。

seq_1.start(m_sequence,this,500);	//highest priority
seq_2.start(m_sequence,this,300);	//next highest priority
seq_3.start(m_sequence,this,100);	//lowest priority among threesequences

31、如何停止在sequencer上运行的所有sequences?
sequencer具有stop_sequences()方法,可用于停止所有sequences。但是此方法不检查driver当前是否正在驱动任何sequence_items,如果driver调用item_done()或put(),则可能会出现fatal error,因此sequences指针可能无效。

32、生成sequence时,early randomization和late randomization有什么区别?
在early randomization中,先调用randomize()方法对sequence对象进行随机化,然后再使用start_item()来请求对sequencer的访问。
在late randomization中,先调用start_item(),直到从sequencer授予仲裁,然后在将事务发送到sequencer/driver之前调用randomize。

33、什么是subsequence?
从sequence的body()任务中,如果调用了另一个sequence的start(),则通常将其称为subsequence。

34、sequence通常包含什么?
一个sequence通常包含一个body()任务,在其中生成施加到DUT的激励。

35、为什么不建议在sequence中使用pre_body()和post_body()?
只有通过uvm_sequence::start()方法调用时,才会间接调用pre_body()和post_body();而经常使用的序列宏发送宏序列例如`uvm_do则不会调用pre_body()和post_body()。

36、sequence中pre_body()和post_body()函数是什么?它们总是被调用post_body()方法。
uvm_sequence::start()有一个可选参数,如果将其设置为0,将不调用这些方法。以下是sequence中的start()方法参数:

virtual task start(
	uvm_sequence_base sequence,		//pointer to sequence
	uvm_sequence_base parent_sequence = null,	//parent sequence
	integer this_priority = 100,	//priority on the sequencer
	bit call_pre_post = 1);			//pre_body and post_body called

37、宏uvm_do和宏uvm_rand_send之间的区别是什么?
宏uvm_do自动地创建。随机化和发送新的对象。
宏uvm_send用于发送已经完成创建和随机化之后的对象。
宏uvm_do执行以下步骤:
①create②start item③randomize④finish item⑤get response(optional)
宏uvm_rand_send执行除create之外的所有上述步骤。用户需要创建sequence或sequence item。

38、start()和宏uvm_do_on有什么区别?
start()是uvm_sequence的方法,而宏uvm_do/宏uvm_do_on等一系列的宏只能在uvm_sequence中使用,在uvm_test中如果要将顶层virtual sequence挂载到virtual sequencer上,应该使用uvm_sequence::start()方法,而不是宏uvm_do的宏,原因就是在uvm_test中无法使用该类宏。

39、sequence和sequence_item有什么区别?
sequence是driver驱动的sequence_item序列模式,由其body()方法实现。例如:连续读取10次事务。
sequence_item是一个对象,其建模了两个验证组件之间传输的信息(有时也可以称为事务(transaction))。例如:读操作和写操作中的地址和数据信息。

40、调用sequence_print()方法时,调用sequence中的哪个方法?
convert2string():建议实现此函数,该函数返回对象的字符串形式(其数据成员的值),这对于将调试信息打印到仿真器界面或日志文件很有用。

41、什么是virtual sequence,在哪里使用?有什么好处?什么是virtual sequencer?
virtual sequence是控制多个sequencers中激励生成的sequence。由于sequences、sequencers和drivers都只针对单个接口,几乎所有测试平台都需要virtual sequence来协调不同接口之间的激励。
virtual sequences在子系统或系统级测试平台上也很用,可以是模块级的sequence协调地运行。
virtual sequencer是包含其他sequencer的容器以使得virtual sequence中的每个字sequence都能在相应的sequencer上获得执行。

42、uvm_transaction和uvm_seq_item之间的区别?
uvm_sequence_item类仅从uvm_transaction类扩展,uvm_sequence_item类具有更多支持sequence和sequencer特征的功能。uvm_sequence_item为sequencer和sequence提供了钩子,所以可以使用sequence和sequencer生成事务,而uvm_transaction只提供do print和do record等基本方法。

43、sequence如何才能独占访问sequencer?
当在sequencer上运行多个sequence时,sequencer对sequence中的每个sequence_item的访问权限进行仲裁。有时一个sequence可能希望独占访问sequencer,直到将其所有的sequence_item都发送完毕为止(例如:你希望施加一个定向的激励,在此过程中不被打断)。
有两种机制允许sequence获得对sequencer的独占访问权。
lock()和unlock():sequence可以调用sequencer的lock方法,通过sequencer的仲裁机制获得对driver的独占访问权限。如果还有其他标记为更高优先级的sequences,则此sequences需要等待。授予lock权限后,其他sequences在sequencer上调用unlock()方法。lock()方法是阻塞调用,直到获得lock权限才返回。
grab()和ungrab():grab()方法类似于lock方法,用于申请独占访问。grab()和lock()之间的区别在于,调用grab()时将立即生效,不考虑其他sequences优先级,除非已经存在sequences调用lock()或grab()。

44、sequencer有哪些不同的仲裁机制可用?
多个sequences可以同时连接到单个接口的driver上。sequencer支持仲裁机制,可以确保在任何时间点只有一个sequences可以访问driver。哪个sequence_item可以发送取决于用户选择的sequencer仲裁算法。
在UVM中实现了五种内置的sequencer仲裁机制,也可以实现用户自定义的仲裁算法。sequencer有一个set_arbitration()的方法,调用该方法可以选择使用哪种算法进行仲裁。可以选择的六种算法如下:
1)SEQ_ARB_FIFO(Default if none specified)
2)SEQ_ARB_WEIGHTED
3)SEQ_ARB_RANDOM
4)SEQ_ARB_STRICT_FIFO
5)SEQ_ARB_STRICT_RANDOM
6)SEQ_ARB_USER

45、什么是uvm_config_db?uvm_config_db和uvm_resource_db之间的区别?
uvm_config_db是一个参数化的类,用于将不同类型的参数配置到uvm数据库中,如此它可以被任何较低级别层次结构中的组件使用。uvm_config_db是一个构建在uvm_resource_db之上的便利层,但这种便利非常重要,特别是,uvm_resource_db使用“最后写入获胜”方法。另一方面,uvm_config_db通过end_of_elaboration查看层次内容,因此“父获胜”。一旦启动star_of_simulation,config_db就会变成“最后写入获胜”。
uvm_config_db#( T )中的所有函数都是静态的,因此必须使用::运算符调用它们。uvm_config_db#( T )中的所有函数都是静态的,因此必须使用::运算符调用它们。uvm_config_db#( T )是从uvm_resource_db#( T )拓展而来的,所以它是uvm_resource_db#( T )的子类。

46、如何使用uvm_config_db的get()和set()方法?
get()和set()是用于使用uvm_config_db配置或检索信息的主要方法。任何验证组件都可以使用set()方法为config_db配置一些信息,还可以控制其他组件对该信息的可见性,可以将其设置为全局可见性,或者仅对一个或多个特定测试平台组件可见。
get()函数从数据库中匹配配置参数。get()和set()方法的语法如下:
context指定调用get/set的当前类或组件。
inst_name是调用get/set的组件实例的名称。
field_name是在config_db中get/set的参数的名称。
< type >标识get/set的

47、什么是事务级建模(Transaction Level Modelling)?
事务级建模(TLM)是一种在较高抽象级别上对系统设计或模块设计进行建模的方法,抽象出所有底层实现细节。
这是验证方法学中用于提高模块化和重用性的关键概念之一。即使DUT的实际接口有信号级别表示,但大多数验证任务(如生产激励,功能检查,收集覆盖率数据等)都可以在事务级别上更好地完成,这有助于验证组件在项目内部和项目之间重用和维护。

48、copy()、clone()和create()方法之间的区别?
create()方法用于构造一个对象。
copy()方法用于将一个对象复制到另一个对象。
clone()方法复制一个对象同时完成对象的创建。

49、get_name()和get_full_name()有什么区别?
get_name()函数返回对象的名称,该对象的名称由new构造函数提供或set_name()方法提供。
get_full_name()返回对象的完整层次结构名称。对于uvm_components,这在打印语句中使用时很有用,因为它显示了组件的完整层次结构。对于没有层次结构的sequence或配置对象,与get_name()打印相同的值。

50、ACTIVE agent与PASSIVE agent有何不同?
ACTIVE agent是可以在其操作的接口上生成激励,其包含driver和sequencer。
PASSIVE agent不生成激励,只能监视接口,这意味着在PASSIVE agent中将不会创建driver和sequencer。

51、Agent如何配置ACTIVE和PASSIVE?
UVM agent具有类型为uvm_active_passive_enum的变量,该变量定义agent是否active(UVM_ACTIVE)(构建了sequencer和driver)或者passive(UVM_PASSIVE)(不构建sequencer和driver)。
此参数默认情况下设置为UVM_ACTIVE,在environment类中创建agent时,可以使用set_config_int()进行更改。然后,agent的build phase阶段应具有以下代码以选择性的构建driver和sequencer。

function viod build_phase(uvm_phase phase);
	if(m_cfg.active == UVM_ACTIVE) begin 	//create driver,sequencer
	end
endfunction

52、什么是factory automation?
factory是一种在验证环境中实例化组件或生成激励时提供更大灵活性的机制,factory机制允许在不修改原始源代码的条件下覆盖现有验证代码创建的对象类型。

53、我们为什么在factory中注册类?
factory是UVM使用的特殊查找表,用于创建component或者transaction类型的对象。使用factory创建对象的好处是,测试平台可以在运行仿真时决定创建哪种类型的对象。
一个类可以用另一个类替换,而无需更改任何代码,为确保此功能,建议所有类都在factory中注册,如果不向factory注册类,则将无法使用factory方法::type_id::create()构造对象。

54、什么是TLM ports和exports?
在事务级别建模中,不同的组件或模块使用事务对象进行通信。TLM port 定义了用于连接的一组方法(API),而这些方法的具体实现称为TLM exports。
TLM port和export之间的连接建立了两个组件之间的通信机制。producer可以创建事务并将其put到TLM端口,而put方法实现(也称为TLM export)将在consumer中读取producer创建的事务,从而建立通信渠道。

55、什么是analysis_port?
analysis_port(uvm_tlm_analysis_port)一特定类型的事务级端口,可以连接到零个,一个或多个analysis export,组件可以通过该端口调用在另一个组件中实现的方法。

56、什么是TLM FIFO?
TLM FIFO是两个UVM组件之间的FIFO,最好是在monitor和scoreboard之间,monitor继续发送data,他将存储在TLM FIFO中,scoreboard可以在需要时从TLM FIFO获取数据。

57、analysis ports/FIFOs和TLM ports/FIFO有什么区别?
analysis ports/FIFOs是一种事务通信通道,用于组件将事务广播到多个组件。TLM ports/FIFO用于两个组件之间的事务级别通信,这两个组件具有使用put/get方法建立的通信通道。
analysis ports/FIFOs用于monitor将接受的事务广播到scoreboard或reference model;TLM port/FIFO用于driver和sequencer之间的连接。

58、TLM上的get()和peek()操作之间有什么区别?
get()操作将从TLM FIFO返回一个事务(如果存在的话),并且还会从FIFO中删除该事务。如果FIFO中没有可用的事务,它将阻塞并等待,直到FIFO至少有一个事务。
peek()操作将从TLM FIFO返回事务(如果存在的话),而无需从FIFO中删除该事务。这也是一个阻塞调用,如果FIFO没有可用事务,它将等待。

59、TLM FIFO上的get()和try_get()操作之间的区别?
get()是从TLM FIFO获取事务的阻塞调用。因此如果FIFO中没有可用的事务,则任务get()将等待。
try_get()是一个非阻塞调用,即使FIFO中没有可用的事务,也会立即返回。try_get()的返回值指示是否返回有效事务项。

60、如何连接monitor和scoreboard、driver、sequencer?
使用analysis_port 在connect phase连接monitor和scoreboard。driver具有一个seq_item_port,可以在agent的connect phase中连接到sequencer的seq_item_export。

61、什么是UVM寄存器模型?为什么需要它?
在验证上下文中,寄存器模型是一类组,用于模拟DUT中寄存器和存储器的存储器映射的行为,以便于激励生成和功能检查(以及可选的功能覆盖的某些方面)。UVM提供了一组基类,可以拓展它们以实现全面的寄存器建模功能。

62、寄存器模块验证中常见的测试点有哪些?
1)检查寄存器的复位值
2)需要检查寄存器的域常见读写属性
3)检查每个寄存器的地址映射关系是否正确
4)检查寄存器的反馈是否及时准确,这一点需要检查硬件状态信号是否连接到寄存器端,如果是更新方式是主动更新,那么可以通过后门访问进行快速检查(不占总线),如果更新方式是被动更新,那么只能通过前门访问状态值更新。
5)对于一些特殊寄存器(wc/rc/wo)需要特定属性,进行单独访问,并通过后门访问或者检测内部信号检查其功能。

63、RAL frontdoor和backdoor访问有什么区别?
frontdoor访问:通过数据总线协议访问,消耗仿真时间。
backdoor访问:通过RAL信号路径访问,不消耗仿真时间。

64、什么是UVM call back?
uvm_callback类是用于实现回调(callbacks)的基类,这些回调用于在不更改组件类代码的情况下修改组件的行为。
一种常见用法是在driver将激励发送到DUT之间前将错误注入到生成的数据包中。
实现call back 的步骤:
1)定义数据包packet类;
2)定义从sequence中接收此数据包并将其发送到DUT的driver类;
3)定义一个从uvm_callback基类派生的driver callback类,并添加一个虚拟方法,该方法可用于注入错误或翻转数据包中的某个位。
4)使用宏uvm_register_cb()注册callback类;
5)在driver类的run()方法中接收数据包并将其发送到DUT。

  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值