UVM设计模式 (七)命令模式、三种sequence启动方式、start_item/finish_item、中介模式、virtual sequence

本篇介绍UVM中的sequence,这是UVM中最基础的部分。对于前面介绍的uvm_callback, uvm_visitor等,很少被使用到或者也只有搭建平台的人会使用。不能认为平台的搭建更富有“技术含量”,用例的构建有时候更重要。UVM提供了多种方式,常常让使用者混淆,本篇将会 “捋” 一下sequence_item,sequence,sequencer,driver的协作关系,结合设计模式中的命令模式,中介模式,桥接模式进行介绍。

启动与挂载

基本理解:UVM中各个组件的相互“交流”是基于实际业务提取出的transaction(uvm_sequence_item);uvm_sequence中的body()函数负责产生发送这些transaction,生命周期是body()函数的执行期;uvm_sequencer负责调度从uvm_sequence中拿到的transaction,然后发送给driver;uvm_sequcence和transaction一样,也是继承于uvm_sequence_item,uvm_sequcne是transaction的有机结合,代表一种具体的业务行为,描述一种scenario 这样更有利于在创建用例时的复用。同时在transaction,uvm_sequence中加入SV特有的语法特点,constrain约束,方便扩展使用到不同的场景。

启动:这里的启动就是通过哪种方式调用uvm_sequence中的body()函数的意思。( body()函数被sequence的 start()函数调用,也可以理解成 start()函数的执行

sequence的挂载:uvm_sequence不属于component,没有phase概念,需要挂载在一个sequencer上,在这个sequencer的phase中被调用(default_sequence的情形),同时uvm_sequence可以操作所挂载的sequencer的成员变量(比如在sequence中使用sequencer中的寄存器模型句柄;在virtual sequence中调用 virtual sequcner中的其他 sequcner 句柄 )。

transaction的挂载:对于transaction,挂载的意思就是将transaction发送给所挂载的sequencer,sequencer再发送给连接的driver。(无论sequence还是transaction,挂载的本质就是给uvm_sequence_item中的成员变量 m_sequencer赋值,sequence/transaction都继承于uvm_sequence_item

启动,挂载在UVM英文文档中没有对应关键词,仅是根据实际使用总结出来的词汇 

继承关系:

三种sequence的启动方式:

1.  start()函数显示调用

使用形式:

1. 在sequence中显示调用strat()函数,第一个参数是需要挂载的sequencer;第二个是parent_sequence,一般传入this或者不传入;第三个是优先级;第四个call_pre_post默认为1,则自动执行pre_body/ post_body()函数

2. 执行pre_start,body等函数。此时就完成了sequence的启动过程。

3. 在start()函数中,首先调用了函数set_item_context()函数,这个函数位于sequence的父类uvm_sequence_item中,负责给成员变量m_sequencer, m_parent_sequence赋值。

4. 如果没有指定挂载的sequencer,则挂载到parent_sequence的sequencer上。

5. 此处seq0显示传入了需要挂载的p_sqr0,则调用set_sequencer()函数完成挂载,给m_sequencer赋值。

6. set_sequencer()函数会调用m_set_p_sequencer(),这个函数是一个空的虚函数。如果在sequence中调用了宏 uvm_declare_p_sequencer则会重写这个函数,将成员变量p_sequencer指向sequence所挂载的sequencer上。所以使用者要保证start()函数传入的sequencer应该和宏 uvm_declare_p_sequencer声明的类型一致。否则$cast转换的时候会报错。使用uvm_declare_p_sequencer后,就可以在sequence中调用挂载sequencer的成员函数和成员变量了。

2. `uvm_do()宏

使用形式: 

UVM中提供了多个宏,`uvm_do,`uvm_do_with,`uvm_do_on_with等,但最终都是调用了uvm_do_on_pri_with宏。uvm_do_on_pri_with宏第一个参数可以传入sequence,也可以传入transaction。

1. uvm_do_on宏第一参数是sequence。uvm_do_on_pri_with宏中调用宏uvm_create_on。

2. create_item通过工厂模式创建sequence实例

3. 调用set_item_context()函数,给成员变量m_sequencer, m_parent_sequence赋值,参考上节分析。此处parent_sequence默认是this。

4. 调用sequence的start函数,流程和上节一样,最后调用body()函数。

通过宏的形式相比于直接调用start函数,节省了sequence的实例化和随机化的步骤,但是对于不熟悉宏的人来说,宏封装的内容可能与其使用意图偏差。

3. default_sequence方式

使用形式:

第一种:

第二种:

使用default_sequence的方式也是通过工厂模式创建sequence,再隐式的调用seq.start(this) 函数,可以参考:🔗 UVM设计模式 ( 四 ) 模板模式、策略模式、default_sequence、uvm_callback

 【拓展】对于sequence中的资源访问,可以参考 UVM设计模式 (三) 静态类、资源管理、uvm_event、uvm_*_pool、uvm_config_db、UVM_REGEX_NO_DPI 中的"sequence中的资源访问"小节,总结了6种使用方式。

命令模式

Comand Pattern:将一个请求(命令)封装成一个对象,从而可以用不同的请求对接收者进行参数化,实现请求的发送者和接收者解耦;还可以对请求排队,或者记录请求日志,以及支持撤销操作。

命令模式和前面提到的策略模式很相似,也是通过“组合 + 多态”实现的。设计模式更关注于设计意图,也就是应用场景,单纯地从代码实现上看,有些模式确实很相似,比如命令模式和策略模式。但策略模式是不同策略具有相同的目的,不同的实现,相互之间可以替换,在命令模式中,是不同的命令具有不同的目的,对应不同的逻辑处理,相互之间不可替换。

一个简单的示例:captain是命令的发起者,soldier是命令的接收者。

start_item finish_item

上节提到使用uvm_do宏启动sequence,如果宏传入的第一个参数不是uvm_sequence_base类型,就是我们的transaction, 则调用start_item, finish_item函数。

1. start_item()三个参数,第一个是传入的transaction, 第二个是优先级,第三个是指定该transaction发送给哪一个sequencer, transaction挂载在哪一个sequencer上。

2. 如果之前没有给transaction的m_sequencer赋值,此处sequcner仍未null

3. 调用get_sequencer()函数,将transaction挂载到sequence启动的sequencer上。

4. transaction必须指定挂载的sequencer, 否者transaction无法通过sequencer发送给driver。而sequence却不一定需要挂载到sequencer上,因为sequence的主要目的是执行body函数,直接在tc中调用seq.start()不指定sequencer,也可以。但是default_sequence的形式必须挂载到sequencer上。

5. set_item_context()函数上节已提到。wait_for_grant()等待sequencer仲裁。pre_do() hook函数。

6.  在finish_item中,调用transaction挂载sequencer的函数send_request(), 这个函数定义在uvm_sequencer_param_base中。将transaction放入m_req_fifo容器中。

7.  当driver中调用seq_item_port.get_next_item(req)时,实际调用的是uvm_sequencer中的get_next_item函数。从m_req_fifo容器中拿到之前sequence放入的transaction。

8.  driver中的seq_item_port.item_done(),实际调用的是uvm_sequencer中的item_done函数。sequence通过wait_for_item_done和sequencer的item_done握手,通过成员变量m_wait_for_item_sequence/transaction_id判断。每个sequence, sequence中的每个transaction其ID都是唯一的。

9. 如果item_done()传入rsp,调用put_response函数,与sequence中的get_response配合使用。

🔍+ :

start_item/finish_item封装函数以及sequence,sequencer,driver的握手关系如下图:

结合命令模式,sequence作为命令的发起者,sequencer作为接收者。sequence负责发送各种transaction, 至于是哪一个sequencer接收,由transaction中的成员变量m_sequencer决定。实现发送者与接收者的解耦。设计模式侧重应用场景,transaction仅仅是事务,不具备命令的实现行为,所以UVM的实现并不完全符合命令模式。UVM中的sequencer更像一个仲裁者,一边是driver不断请求transaction,一边根据priority给sequcence授权,接收sequence发送的transaction,支持lock,grab操作。同时driver,sequence之间也有联系,driver可以response transaction给sequence。

在实际使用中,建议不要使用宏,而是通过start()函数显示启动sequence, 通过start_item finish_item发送transaction。

中介者模式

Mediator Pattern: 定义一个单独的(中介)对象,来封装一组对象之间的交互。将这组对象之间的交互委派给与中介对象操作,来避免对象之间的直接交互,使耦合松散。

如果不使用中介者模式,各个系统模块,或者说各个类之间,互相依赖,就会形成一个复杂的网装结构;使用了中介者模式,系统就变成了结构清晰的星形结构。

 UVM中virtual sequence就是一个典型的中介者模式的使用案列。在virtual sequence中可以统一调度各个sequence,负责每个sequence的同步,成员变量赋值,随机约束等。中介者模式实现简单,具体示例不在演示。

  • 43
    点赞
  • 325
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
UVM(Universal Verification Methodology,通用验证方法学)是一种常用的硬件验证方法学,其提供了一套完整的验证框架和工具,方便进行复杂的设计验证工作。 在UVM中,Sequence Item(序列项)是用于描述被验证设计中的信号、寄存器或其他需要验证的对象的数据结构。它可以看作是将待验证设计中的信息抽象出来的一个模型。 设计一个UVM Sequence Item主要是为了对待验证对象进行建模,并且在验证环境中进行重复使用。它包含了待验证对象的属性、状态和行为等信息。根据设计规范,Sequence Item一般需要继承自uvm_sequence_item类,并且需要实现必要的函数和任务。 使用UVM Sequence Item设计模式有以下几个好处: 1. 抽象层次高: Sequence Item将待验证设计抽象为一个独立的对象,使得验证人员只需关注待验证对象的功能和行为,而无需过多关注其内部实现细节,从而提高了验证的复用性和可维护性。 2. 灵活性和可扩展性: 通过继承和重载函数,可以对Sequence Item进行扩展和定制化,以适应不同的需求。可以在Sequence Item中添加必要的约束和约定,以确保验证的正确性和完整性。 3. 与其他验证组件的连接性: Sequence Item是验证环境中不同组件之间交互的桥梁。通过使用Sequence Item,可以方便地将验证组件(如生成器、驱动器、监控器等)与待验证对象进行连接和通信,实现验证环境的协同工作。 总结来说,UVM Sequence Item设计模式提供了一种有效的方法来抽象和建模待验证对象,使得验证工作更加高效、灵活和可维护。它是UVM验证框架中不可或缺的一部分,对于复杂的设计验证工程具有重要的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

劲仔小鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值