IC验证_综合知识

  • 接口与虚接口

接口的强大功能:一是简化模块之间的连接;二是实现类和模块之间的通信。可以说接口的功能固然强大,但是问题又来了:

首先,因为事务交易处理器中的方法采用了层次化应用的方式去访问对应端口的信号,所以我们只能为两个相同功能的接口分别编写两个几乎一样的事务交易处理器,为什么呢?因为采用的是层次化的应用,假如设计中的某个引脚名字需要修改,我们只能修改驱动这个端口的方法!这样还是有点繁琐,那么sv中有了虚接口的概念,事情就会变得更加简单了!

到底是如何操作的呢?

虚接口和对应的通用方法可以把设计和验证平台分隔开来,保证其不受设计改动的影响。当我们对一个设计的引脚名字进行改动的时候,我们无须改动驱动这个接口的方法,而是只需要在例化该事务交易处理器的时候,给虚接口绑定对应连接的实体接口即可。以此来实现事务交易处理器的更大重用性。

虚接口的定义:

virtual interface_type variable;

虚接口可以定义为类的一个成员,可以通过构造函数的参数或者过程进行初始化。

虚接口应用的具体步骤:

到此,我们就可以在事务交易处理器中,编写针对该接口的通用方法(如request和wait_for_bus),只要针对虚接口进行操作就可以,而该虚接口不针对特定的具体器件,只有在事务交易处理器的对象例化创建时,根据具体传递给他参数确定。

  1. 定义接口(Sbus),该接口可供所有具有相同接口的模块或者类使用
  2. 在事务交易处理器的类中(Sbus_transactor)添加一个对应接口类型(Sbus)的虚接口成员(bus)
  3. 在事务交易处理器的构造函数中,添加一个对应接口类型的虚接口的参数(s)
  4. 在事务交易处理器的构造函数体内将参数(s)赋值给虚接口成员(Sbus)
  5. 在被测设计同一个层次例化实体接口(s[1:4]())。
  6. 将被测设计(a1/b1/a2/b2)的例化端口和实体接口相连接
  7. 例化并创建事务处理器对象,并将实体接口作为参数传递给其例化。
  • event与uvm_event

在UVM中,同步的不再只局限于同一个对象中的各个线程,而是还有各个组件之间的同步问题。一旦发生同步的要求发生在各个组件之间,这就要求组件之间通过某种可以同步的方法来实现。而考虑到UVM各个组件的封闭性原则,我们并不推荐通过层次索引的形式在组件中来索引公共的event或者semaphore。UVM为了解决封闭性的问题,定义了如下的类来满足组件之间的同步:

uvm_event,uvm_event_pool,uvm_event_callback,uvm_barrier, uvm_barrier_pool

uvm_event类与event相比,它有下面的几个重要特性:

  1. event被->触发之后,会触发使用@等待该事件的对象;uvm_event通过trigger()来触发,会触发使用wait_trigger()等待的对象。如果要再次等待事件触发,event只需要再次用->来触发,而uvm_event需要先通过reset()方法重置初始状态,再使用trigger()来触发。
  2. event无法携带更多的信息,而uvm_event可以通过trigger(uvm_event data = null)的可选参数,将所要伴随触发的数据信息都写入到该触发事件中,而等待该事件的对象可以通过方法wait_trigger_data(output uvm_object data)来获取事件触发时写入的数据对象。
  3. event触发时无法直接触发回调函数,而uvm_event可以通过add_callback(uvm_event_callback cb, bit append = 1)函数来添加回调函数。
  4. event无法直接获取等待它的进程数目,而uvm_event不但可以通过get_num_waiters()来获取等待它的进程数目。

不同的组件可以共享同一个uvm_event,这不是通过跨层次传递uvm_event对象句柄来实现共享的,因为这并不符合组件环境封闭的原则。这种共享同一个uvm_event对象是通过uvm_event_pool这一全局资源池来实现的。这个资源池类是uvm_object_string_pool #(T)的子类,它可以生成和获取通过字符串来索引的uvm_event对象。通过全局资源池对象(唯一的),在环境中任何一个地方的组件都可以从资源池中获取共同的对象,这就避免了组件之间的互相依赖。

  • 解释下driver、sequencer、sequence的关系

  1. drv调用seq_item_port.get_next_item();
  2. seqr调用wait_for_grant();
  3. seqr调用begin_tr(req);
  4. seq调用start_item(req);
  5. seq调用randomize()函数;
  6. seq调用finish_item(req)函数;
  7. 在上一步的继续上,seqr相继调用send_request(req)函数;
  8. drv调用send()函数;
  9. drv调用seq_item_port.item_done();
  10. seqr调用wait_for_item_done()函数
  11. seqr调用end_tr()函数

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Learn_and_Think)