【UVM】sequence 的启动方式
该篇文章描述不清楚的地方建议参考: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 的启动方式相关推荐
- UVM设计模式 (七)命令模式、三种sequence启动方式、start_item/finish_item、中介模式、virtual sequence
本篇介绍UVM中的sequence,这是UVM中最基础的部分.对于前面介绍的uvm_callback, uvm_visitor等,很少被使用到或者也只有搭建平台的人会使用.不能认为平台的搭建更富有&q ...
- (16)UVM sequence和item
UVM sequence和item 文章目录 UVM sequence和item 一.概述 二.sequence item介绍 三.item使用时的特点 四.item与sequence的关系 五.fl ...
- SOC验证环境的启动方式
SOC验证环境一千家公司有一千家公司的做法.那么一个优秀的SOC验证环境应该具备哪些功能呢? 首先是SOC验证环境支持C和SV两种下激励的方式. 通过C code启动SOC环境是怎么启动的呢?这里涉及 ...
- thinkpad重装系统不引导_重装系统时,如何判断Windows的启动方式是Legacy还是UEFI?...
众所周知,BIOS启动模式有UEFI+GPT和Legacy+MBR两种,如今大多数新机型电脑都采用了UEFI的启动模式来引导系统,即便如此,仍有部分电脑采用Legacy启动模式.这两种启动模式究竟有什 ...
- Flask开发服务器启动方式
开发服务器启动方式 在1.0版本之后,Flask调整了开发服务器的启动方式,由代码编写app.run()语句调整为命令flask run启动. from flask import Flaskapp = ...
- Redis的多种启动方式比较!
有感: Redis玩了许久时间,真心感觉启动方式还是自己定义的方便! 1)直接启动和关闭:(配置文件默认) 开启:redis-server &(&后台运行) #daemonize ye ...
- 12.QT线程的两种启动方式
一.QT中的线程 QT中的线程主要是通过QThread进行管理,一个QThread对象管理程序中的一个线程. QThreads管理的线程在run()中开始执行. 默认情况下,run()通过调用exec ...
- prometheus 插件node_exporter 启动方式
在linux下./node_exporter&这种启动方式,关闭终端后,就挂掉了,使用以下启动方式 nohup ./node_exporter --web.listen-address=&q ...
- mysql服务器的启动方式有哪几种_Mysql启动的方式(四种)
废话不多说了,直奔主题了. mysql的四种启动方式: 1.mysqld 启动mysql服务器:./mysqld --defaults-file=/etc/my.cnf --user=root 客户端 ...
最新文章
- 开源Web应用中最常见漏洞是XSS和SQLI漏洞
- [TCP/IP] SSL的通讯原理
- 一个程序设计试题:读取2维字符数组,判断出表示的数字
- 你们觉得这个时代好还是父母那个时代好?
- 怎么搜索php文件内容,linux怎么搜索文件
- 微投抖的1080_1080P不到三千元 微投价格战竟如此激烈
- C++ - 虚基类、虚函数与纯虚函数
- 安捷伦频谱仪的使用方法图解_频谱分析仪的基本使用方法(转载)
- ADC0808ad转换实验程序c语言,模数转换器ADC0808的应用
- HTML5期末大作业:个人网站设计——简单响应式个人博客HTML模板(8页面) HTML+CSS+JavaScript...
- Canonical 在 Linux 上提供 Flutter 桌面应用支持
- 文化馆建筑方案设计原理及方案
- 积跬步而至千里,积小流而成江海
- php imap函数详解,Imap是什么意思,php imap 函数详解
- 浏览器内置对象 Web API 规则部分
- 系统迁移性能问题解决
- Python:用【Win32】模块,结合Word通配符替换,将Word文档表格的部分内容替换为加粗
- Fluke DTX-CHA001/DTX-CHA001A/DTX-CHA002的区别
- python爬虫入门—selenuim自动登录qq邮箱
- kubernetes test-infra