0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UVM设计中的sequence启动方式有哪几种呢?

rfdqdzdg 来源:IC Verification Club 2023-08-17 10:07 次阅读

本篇介绍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英文文档中没有对应关键词,仅是根据实际使用总结出来的词汇 * )

继承关系:

wKgaomTdgZCAGq9kAAAnwfSCLs4862.jpg

三种sequence的启动方式:

1. start()函数显示调用

使用形式:

wKgZomTdgZCALtvNAAC1v_RKRA8496.jpg

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

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

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

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

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

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的成员函数和成员变量了。

wKgaomTdgZCAb_9EAATG8ufD8Zc397.jpg

2. `uvm_do()宏

**使用形式: **

wKgaomTdgZCATC10AABPfsyZa64535.jpg

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

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

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

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

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

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

wKgaomTdgZCABkKGAAPMSNnEIDE492.jpg

3. default_sequence方式

使用形式:

第一种:

wKgZomTdgZCAXT0BAABL9pUPoLc970.jpg

第二种:

wKgZomTdgZCASW25AABVVl9CIog497.jpg

使用default_sequence的方式也是通过工厂模式创建sequence,再隐式的调用seq.start(this) 函数

【拓展】

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

命令模式

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

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

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

wKgZomTdgZCAIhpOAAZNAwweQSg612.jpg

start_item finish_item

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

wKgaomTdgZCAK2krAAFhjzpkuJ4296.jpg

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

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

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

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

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

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

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

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都是唯一的。

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

wKgZomTdgZCANzbiAAS_fVSQ-Vo438.jpg

wKgZomTdgZCAW3kBAAA2FD9IgxQ510.jpg

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

wKgaomTdgZCAGlH2AAHYqg3Xs38561.jpg

结合命令模式,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:定义一个单独的(中介)对象,来封装一组对象之间的交互。将这组对象之间的交互委派给与中介对象操作,来避免对象之间的直接交互,使耦合松散。

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

wKgaomTdgZCAN45XAABq1QwviUo122.jpg

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






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 转换器
    +关注

    关注

    27

    文章

    8607

    浏览量

    146787
  • 寄存器
    +关注

    关注

    31

    文章

    5305

    浏览量

    119919
  • 耦合器
    +关注

    关注

    8

    文章

    717

    浏览量

    59609
  • UVM
    UVM
    +关注

    关注

    0

    文章

    181

    浏览量

    19126
  • sequence
    +关注

    关注

    0

    文章

    23

    浏览量

    2829

原文标题:UVM设计模式 (七)命令模式、三种sequence启动方式、start_item/finish_item、中介模式

文章出处:【微信号:数字芯片设计工程师,微信公众号:数字芯片设计工程师】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32F407可以哪几种方式进行启动

    STM32F407的启动模式是什么?STM32F407可以哪几种方式进行启动
    发表于 10-21 08:02

    STM32哪几种启动模式

    STM32哪几种启动模式?STM32烧录程序的方式是什么?
    发表于 10-25 06:40

    SYSCLK的BOOT引脚哪几种不同的启动模式

    SYSCLK的BOOT引脚哪几种不同的启动模式
    发表于 10-29 07:20

    实现手机快充哪几种方式

    充电器实现快充的原理是什么?实现手机快充哪几种方式
    发表于 11-03 07:06

    SPI协议的工作方式哪几种

    SPI是什么?SPI协议的工作方式哪几种
    发表于 11-04 08:01

    I.MX6U启动方式哪几种?如何去选择

    I.MX6U启动方式哪几种?如何去选择?如何利用汇编语言来初始化一下C语言环境
    发表于 11-30 07:11

    TokenServer哪几种开发方式

    TokenServer哪几种开发方式?TokenClient和TokenServer端开发的流程哪些
    发表于 12-27 06:12

    System复位哪几种方式

    System复位哪几种方式?系统时钟的结构是怎样构成的?求解答
    发表于 01-14 06:13

    芯片的启动方式哪几种

    芯片的启动方式哪几种?如何去实现?
    发表于 01-18 06:16

    HTTP协议哪几种加密方式

    HTTP协议哪几种加密方式?其加密方式何优缺点
    发表于 01-20 06:13

    什么是流控?流控的方式哪几种

    什么是流控?流控的方式哪几种?流控的串口是怎样去定义的?
    发表于 01-26 08:16

    SDK配网的方式哪几种

    SDK配网的方式哪几种?微信配网与app配网的原理是什么
    发表于 02-22 08:25

    UVM sequence分层哪几种方式

    验证环境需要对数据进行分层。例如,将32比特的寄存器读写封装成数据读写和状态读写等实际业务操作等或者对底层sequence进行一些随机控制等。实现这种分层可以两种方式:1、Sequence
    发表于 04-11 16:37

    轴承跑内圆哪几种修复方式

    轴承跑内圆哪几种修复方式
    发表于 01-23 11:07 7次下载

    电容器的补偿方式哪几种

    电容器在电子领域中使用十分普遍,而在它的使用过程,为了保证电路可靠性和性能稳定,电容器的补偿就变得尤为重要。那么,电容器的补偿方式哪几种
    的头像 发表于 11-16 15:12 3740次阅读