该篇文章描述不清楚的地方建议参考:UVM设计模式 (七)命令模式、三种sequence启动方式、start_item/finish_item、中介模式、virtual sequence_Holden_Liu的博客-CSDN博客_uvm的body函数

第一种:直接在tc中例化sequence,通过调用star函数指定sequencer启动。

my_sequence my_seq;
my_seq = my_sequence::type_id::create("my_seq");
my_seq.start(sequencer); ## 括号中是sequencer的例化路径,也可以使用m_sequencer(m_sequencer为sequence的启动sequencer). 如果sequence例化在sequencer中,可以用this.

第二种:采用default_sequence

未直接例化sequence:

uvm_config_db#(uvm_object_wrapper)::set(this,"env.i_agt.sqr.main_phase","default_sequence",my_sequence::type_id::get());

未例化时,如何在seqr中启动seq?可以通过在test_base中uvm_config_db将seq set到sequencer中。

在使用 `uvm_do宏时,会默认选择seq启动的seqr上,seq中创建的tr会发送给seqr, seqr负责tr的调度,发送给driver.

`uvm_do_on可以显示将seq中的tr发送给哪个seqr。

uvm_do系列宏不仅仅适用于tr, 也适合seq。如果要在vseq中调用seq,`uvm_do(seq)可以自动调用seq的start函数,同时seq中的tr自动发送给vseq启动的seqr上。使用`uvm_do_on(seq, p_sequencer.p_sqr1)则将seq中的tr发送给vseqr中的p_sqr1这个seqr上。

class my_sequence extends uvm_sequence;my_config cfg;`uvm_declare_p_sequencer(my_sequencer) virtual task body();cfg = p_sequencer.cfg;endtaskendclass

直接例化sequence:

my_sequence my_seq;
my_seq = my_sequence::type_id::create("my_seq",this);
uvm_config_db#(uvm_sequence_base)::set(this,"env.i_agt.sqr.main_phase","default_sequence",my_seq);

通过例化的方法,uvm_object_wrapper要改成uvm_sequence_base;sequence也可以放在env中例化;如果要在tc中向sequence传入handle,就不需要p_sequencer了,因为sequence已例化,可以直接将句柄相连:

seq.tr_h = this.tr_h; #seq例化在tc中
env.seq.tr_h = this.tr_h;#seq例化在env中

seq,seqr,还是 vseq,vseqr,最关键的是搞明seq的启动方式(1. default_sequence启动 2. start启动 3. vseq中调用uvm_do宏启动seq),seq在哪个seqr上启动,挂载。启动的意思就是调用seq的body函数,因为seq不是component,不属于验证组件,没有phase机制,所以必须挂载到一个seqr上启动。第二个需要搞明白seq中的tr发送给哪个seqr调度(1. uvm_do宏(封装了start_item) 2. start_item形式),seq启动后创建的tr需要发送给seqr,seqr调度tr通过TLM发送给对应的dvier。一种是默认的使用启动时的seqr, 一种是显示指明seqr,这种一般是指定vseqr中的seqr。

seq挂载到seqr上时,成员变量m_sequencer就指向了该seqr。

所以uvm_do宏即适用seq,也适用tr。 尽量少用宏

每个sequence中都有一个m_sequencer的句柄,指向seq启动的seqr,如果要引用seqr中的参数,可以声明p_sequencer(其实就是m_sequencer cast转化过来的)

关键是seq在哪个seqr上启动。

在sequence中控制仿真时间:

default_sequence启动方式其实隐式调用start函数:

task my_sequencer::main_phase(phase);seq.starting_phase = phase;seq.start(this);endtask
  • 采用default_sequence启动方式,要在sequence中控制仿真时间,通过starting_phase的raise和drop。
task my_sequence::body();if(starting_phase != null)starting_phase.raise_objection(this);tr = new();start_item(tr);finish_item(tr);if(starting_phase != null)starting_phase.drop_objection(this);endtask
  • 不采用default_sequence启动方式,但是也通过starting_phase的raise和drop。
class sequence1 extends uvm_sequence #(my_transaction);virtual task body();if(starting_phase != null) starting_phase.raise_objection(this);repeat (5) begin`uvm_do_with(m_trans, {m_trans.pload.size < 500;})`uvm_info("sequence1", "send one transaction", UVM_MEDIUM)end#100;if(starting_phase != null) starting_phase.drop_objection(this);endtask

没有set  default_sequence, 所以starting_phase 为 null。 但是可以像下面那样seq0.starting_phase = phase 赋值为非空,间接通过sequence中的starting_phase 控制 objection。

task my_case0::main_phase(uvm_phase phase);sequence0 seq0;sequence1 seq1;seq0 = new("seq0");seq0.starting_phase = phase;seq1 = new("seq1");seq1.starting_phase = phase;forkseq0.start(env.i_agt.sqr);seq1.start(env.i_agt.sqr);join
endtask
  • 不采用default_sequence, 通过testcase中的phase的raise和drop。
task my_case0::main_phase(uvm_phase phase);sequence0 seq0;sequence1 seq1;phase.raise_objection(this);seq0 = new("seq0");seq1 = new("seq1");forkseq0.start(env.i_agt.sqr);seq1.start(env.i_agt.sqr);joinphase.drop_objection(this);
endtask

此时sequence中的starting_phase = null ;

starting phase的赋值发生的机制是1.run_test()->excute_phases()->traverse->excute()->sqr.start_phase_sequence();
2.start_phase_sequence()中会通过uvm_config_db::get 得到default_sequence的名字,如果get 到了default sequence的名字就会create default_sequence,并且将当前phase(uvm_main_phase或者uvm_run_phase)的句柄赋值给starting phase,如果没有get 到就会直接return退出当前函数;
3.由于uvm_config_db::set default sequence只针对的是virtual sequencer,当执行你调用的子sequencer的时候由于没有uvm_config_db::get到default sequence的名字,所以会直接退出return;4.所以如果使用了default_sequence机制,并且default sequence中有子sequence,这个时候要在子sequence使用starting_phase.raise_object要非常小心;4.这个跟pre body,post body貌似没有多大关系;
4.具体代码请见uvm1.1 中文件 uvm_sequencer_base.svh

================================================================================================================================================================================================================================================================================================

`uvm_do_on(tr, this.m_sequencer)
第一个是transaction指针,第二个是sequencer指针。m_sequencer默认为启动(显式或者隐式)sequence的sequencer.

p_sequencer:

 class case0_sequence extends uvm_sequence #(my_transaction);my_transaction m_trans;`uvm_object_utils(case0_sequence)`uvm_declare_p_sequencer(my_sequencer)
endclass

此时sequence的默认启动m_sequencer指向p_sequencer,可以引用p_sequencer中的变量和方法。

在sequence中获得sequencer的object ( config class ,interface, TLM port etc.)

第一种方式:在base sequence中的pre_start中,当执行start函数时,会自动调用pre_start函数。

class sys_base_seq extends uvm_sequence;
......`uvm_declare_p_sequencer(sys_vseqr)sys_cfg m_cfg_h;xxxx port;virtual sys_if sys_vif;task pre_start();this.m_cfg_h      = p_sequencer.m_cfg_h;this.sys_vif      = p_sequencer.sys_vif;this.port         = p_sequencer.port;endtask

第二种方式: 在base sequence中的pre_body中,当执行body函数时,会自动调用pre_body函数。 (建议放在pre_start中)

class sys_base_seq extends uvm_sequence;
......`uvm_declare_p_sequencer(sys_vseqr)sys_cfg m_cfg_h;xxxx port;virtual sys_if sys_vif;task pre_body();this.m_cfg_h      = p_sequencer.m_cfg_h;this.sys_vif      = p_sequencer.sys_vif;this.port         = p_sequencer.port;endtask

除了直接句柄的赋值,也可以采用config_db的形式:

uvm_config_db#(virtual sys_if)::get(m_sequencer,"","vif",sys_vif);

【UVM】sequence 的启动方式相关推荐

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

    本篇介绍UVM中的sequence,这是UVM中最基础的部分.对于前面介绍的uvm_callback, uvm_visitor等,很少被使用到或者也只有搭建平台的人会使用.不能认为平台的搭建更富有&q ...

  2. (16)UVM sequence和item

    UVM sequence和item 文章目录 UVM sequence和item 一.概述 二.sequence item介绍 三.item使用时的特点 四.item与sequence的关系 五.fl ...

  3. SOC验证环境的启动方式

    SOC验证环境一千家公司有一千家公司的做法.那么一个优秀的SOC验证环境应该具备哪些功能呢? 首先是SOC验证环境支持C和SV两种下激励的方式. 通过C code启动SOC环境是怎么启动的呢?这里涉及 ...

  4. thinkpad重装系统不引导_重装系统时,如何判断Windows的启动方式是Legacy还是UEFI?...

    众所周知,BIOS启动模式有UEFI+GPT和Legacy+MBR两种,如今大多数新机型电脑都采用了UEFI的启动模式来引导系统,即便如此,仍有部分电脑采用Legacy启动模式.这两种启动模式究竟有什 ...

  5. Flask开发服务器启动方式

    开发服务器启动方式 在1.0版本之后,Flask调整了开发服务器的启动方式,由代码编写app.run()语句调整为命令flask run启动. from flask import Flaskapp = ...

  6. Redis的多种启动方式比较!

    有感: Redis玩了许久时间,真心感觉启动方式还是自己定义的方便! 1)直接启动和关闭:(配置文件默认) 开启:redis-server &(&后台运行) #daemonize ye ...

  7. 12.QT线程的两种启动方式

    一.QT中的线程 QT中的线程主要是通过QThread进行管理,一个QThread对象管理程序中的一个线程. QThreads管理的线程在run()中开始执行. 默认情况下,run()通过调用exec ...

  8. prometheus 插件node_exporter 启动方式

    在linux下./node_exporter&这种启动方式,关闭终端后,就挂掉了,使用以下启动方式 nohup ./node_exporter  --web.listen-address=&q ...

  9. mysql服务器的启动方式有哪几种_Mysql启动的方式(四种)

    废话不多说了,直奔主题了. mysql的四种启动方式: 1.mysqld 启动mysql服务器:./mysqld --defaults-file=/etc/my.cnf --user=root 客户端 ...

最新文章

  1. 开源Web应用中最常见漏洞是XSS和SQLI漏洞
  2. [TCP/IP] SSL的通讯原理
  3. 一个程序设计试题:读取2维字符数组,判断出表示的数字
  4. 你们觉得这个时代好还是父母那个时代好?
  5. 怎么搜索php文件内容,linux怎么搜索文件
  6. 微投抖的1080_1080P不到三千元 微投价格战竟如此激烈
  7. C++ - 虚基类、虚函数与纯虚函数
  8. 安捷伦频谱仪的使用方法图解_频谱分析仪的基本使用方法(转载)
  9. ADC0808ad转换实验程序c语言,模数转换器ADC0808的应用
  10. HTML5期末大作业:个人网站设计——简单响应式个人博客HTML模板(8页面) HTML+CSS+JavaScript...
  11. Canonical 在 Linux 上提供 Flutter 桌面应用支持
  12. 文化馆建筑方案设计原理及方案
  13. 积跬步而至千里,积小流而成江海
  14. php imap函数详解,Imap是什么意思,php imap 函数详解
  15. 浏览器内置对象 Web API 规则部分
  16. 系统迁移性能问题解决
  17. Python:用【Win32】模块,结合Word通配符替换,将Word文档表格的部分内容替换为加粗
  18. Fluke DTX-CHA001/DTX-CHA001A/DTX-CHA002的区别
  19. python爬虫入门—selenuim自动登录qq邮箱
  20. kubernetes test-infra

热门文章

  1. 1、matlab页面和基本操作
  2. 浅析资产配置的种方法
  3. NumPy处理图像:色彩取反、图片变灰、图像手绘
  4. 怎么知道电脑和打印机是否连接正常
  5. 数字测图成果处理——计算开挖量绘制剖面图
  6. feed流和瀑布流_内容时代已来,别说你还不懂feed流
  7. 计算机组成原理(谭志虎)第7章课后题部分答案及解析+第7到9章重要知识点解析
  8. FlowLayout流式布局实现搜索清空历史记录
  9. 教你怎样将RS422转成RS485接口
  10. 公告:永久停用我的MSN邮箱!