如何使用virtual sequence和virtual sequencer?

本文转自:http://www.eetop.cn/blog/html/28/1561828-3571706.html

对于初入行的验证工程师,理解和搭建UVM验证环境是很重要的,而其中,virtual sequence的机制又是很有用很重要的一部分。本文希望通过了一些问题的回答,以及一个相对完整的结构帮助经验尚浅的工程师理清思路。

 什么时候使用virtual sequencer 呢?

下图给我们一个基本介绍:

  • 如果只有一个驱动端agent,显然是不需要使用virtual sequencer的。
  • 如果有多的驱动端agent,但是多个激励之间并无协调关系,virtual sequencer 也并无必要。
  • 如果有多的驱动端agent,而且多个激励之间存在协调关系,那么virtual sequencer就很有必要了。这个时候环境中需要包含一个甚至多个virtual sequencer了。

virtual sequence 和virtual sequencer的“virtual”有何含义呢?

Virtual sequencer 有三个属性:

  • Virtual sequencer 控制其他的sequencer
  • Virtual sequencer并不和任何driver相连
  • Virtual sequencer本身并不处理item

并不像正常的sequencer那样,将sequence item 通过sequencer port传递给driver。Virtual sequencer 通过一个指向subsequencer目标的句柄来指定sequence。这里的subsequencer就是和driver相连接的真实sequencer。所谓的virtual 就是指真正的sequence并不是在Virtual sequencer里产生和传递的。一个virtual sequencer 可以通过它的subsequencer产生许多种不同类型的tranction。

而virtual sequence 的作用就是在协调不同的subsequencer中sequence的执行秩序了。

如何实现一个virtual sequencer呢?

例1是virtual sequencer的典型结构,设定的名字是vsequencer。Virtual sequencer派生自UVM_sequencer,而不是uvm_virtual_sequencer(当然,并没有这个类)。virtual sequencer 与其他普通的sequencer最显著的区别就在于,virtual sequencer 并没有指定具体的tranction类型,因为virtual sequencer会执行多种类型的tranction。这里派生时未指定参数,意味着virtual sequencer会使用uvm_sequence_item的默认参数值。

上图,virtual sequencer声明了两个自sequencer句柄,分别是ahb_seq 和eth_sqr。这两个subsequencer将会在end_of_elaboration_phase()这一阶段被赋值。上述代码并没有采取UVM testbench中的大多数组件间常有的连接方式——TLM connect(),这里在环境中使用了配置数据的方式对其进行指定,这样virtual sequencer会在配置数据库中抽取相应的sequencer并赋给virtual sequencer 中声明好的句柄。真实的subsequencer会在build phase中创建。因此,这些subsequencer 句柄只能在connect_phase中被放入配置数据库。这样,virtual sequencer就不得不在下一个阶段重新检索他们,即 end_of_elaboration_phase()阶段。

从这里可以看出来,vsequencer只是一个容器,存放指向subsequencer的句柄以及一些其他配置参数。Virtual sequence假定virtual sequencer在virtual sequence在run phase阶段之前就已被合理的配置过了。他们可以在virtual sequencer中通过p_sequencer句柄访问配置参数。

什么是M-sequencer句柄呢?

所有的sequence都要在sequencer中启动:如tr_seq.start(env.vsqr)。当sequence启动的时候,m_sequencer 句柄就指向了env.vsqr。 m_sequencer 就是这样一个指向执行当前sequence的sequencer句柄。

什么是P-sequencer句柄呢?

UVM新手常有两个问题:

P_sequencer是什么呢?P-sequencer 与M-sequencer有什么区别?

所有的sequence 都有一个m_sequencer 句柄,但是m_squencer变量是个内部实现变量,而且由于参数类型的原型,通过这一句柄通常不能直接调用sequencer里的变量。任何以m_开的变量和方法也都是如此。

这时候为了方便,就使用了P_seuencer。但是任意sequence 并不会自动凭空就有p_sequencer。P_seuencer没有被自动声明,但是可以使用`uvm_declare_p_sequencer宏声明。当调用这一宏时,在virtual sequence 开启时,P_seuencer就会被自动声明、赋值,并正确的指向正在执行这一virtual sequence的virtual sequencer。

`uvm_declare_p_sequencer宏实际上完成了这两步。

  1. 声明了一个sequencer类型的句柄p_sequencer
  2. 这个宏将m_sequencer句柄转化为p_sequencer 类型的句柄。

具体对于`uvm_declare_p_sequencer宏源代码的解析,可参见原文。

所有的virtual sequence 都需要能访问定义于virtual sequencer中的subsequencer的句柄。于是virtual sequence需要使用`uvm_declare_p_sequencer 宏,由于每一个virtual sequence都需要执行这些步骤,所以我们推荐将这部分代码放入一个virtual sequence base class(vseq_base)中,然后基于此base class(vseq_base)派生出所有的virtual sequence。

在展示代码前,这里融合上文所讲例1,给出一个使用virtual sequencer机制的testbench框架图。

vseq_base  示例

为了更方便的管理sequence的公共方法,我们可以定义一个vseq_base。对应于example 1 的sequencer示例, vseq_base 具体代码如下。

本例中, vseq_base类利用p_sequencer 把virtual sequencer (p_sequencer)中的两个subsequencer的句柄拷贝到本地并赋给ahb_sqr 和eth_sqr.

创建virtual sequence

一旦virtual sequence 基类创建完成。我们就可以直接基于此基类派生创建virtual sequence了。如下例3和例4的两个virtual sequence示例。

例3的virtual sequence 使用了`uvm_do macros方法产生sequence,这里先产生了一个AHB packet sequence, 然后产生了两个Ethernet packet sequence, 最后产生了一个AHB packet。

Virtual sequence 就是以这样一种方法,调控sequence的序列顺序的。

例4的virtual sequence 使用了start方法产生sequence,并在此前进行了随机化。

virtual sequence 调用的sequence

Virtual sequence的另一个很重要的特点是,对于已经存在的sequence,它可以无需更改,就直接执行。比如用户创建了一个sequence库,就可以直接在不同模间块进行使用。

下图例5的AHB packet,这是一个"pseudo-AHB packet"。

如下所示,是一个AHB sequence 代码。这个简单的AHB sequence会随机的产生2-5个AHB packet。如上例3和例4的的virtual sequence将会根据这里的sequence定义随机发送AHB packet。

开启virtual sequence

一般来讲,virtual sequence会使用start方法启动。`uvm_do_on 宏是不能在test组建中直接调用的,`uvm_do_on 宏只能在派生的sequence 中调用,`uvm_do_on所需的方法 create_item(), start_item() 和finish_item()都不能在uvm_test  以及其他UVM component 中调用。

常见的好方法是,创建一个test_base 类,在其中声明一些公用的方法。然后在其派生的test类启动sequence

在派生的类中定义了run_phase,在run_phase 中创建一个virtual sequencer,并调用raise_objection() 和drop_objection()方法,在其中使用start()方法开启virtual sequence。

The environment sets the handles in the virtual sequencer

在environment 传递句柄给virtual sequencer

下图代码示例了一个典型的environment结构。这里实例化了一个virtual sequencer  v_sqr, 并将两个sequencer(AHB agent 和 ETH agent 的sequencer)set到配置database。在我们一开始的时候,我们讲“如何实现virtual sequencer”的时候讲,virtual sequencer句柄在connect phase 中被存放到virtual sequencer中,并在end_of_elaboration() phase中重新检索就是这个意思。

本文叙述了一个简单的使用virtual sequencer机制的验证环境的搭建,对于UVM新手弄懂他们如何工作是很有参考意义的,对于源代码及原文更详细的描述,请参阅<<Using UVM Virtual Sequencers & Virtual Sequences>>

猜你喜欢

转载自blog.csdn.net/qq_41394155/article/details/82144676
今日推荐