UVM m_sequencer 和 p_sequencer
m_sequencer:
class uvm_sequence extends uvm_sequence_item; // uvm_sequence 继承于 uvm_sequence_item
// case属于sequence类型,case本质是个sequence
// case0_sequence 在 my_sequencer上启动:case0_sequence.start(my_sequencer)class case0_sequence extends uvm_sequence #(my_transaction);my_trasaction m_trans;`uvm_object_utils(case0_squence)...virtual task body();...repeat(10) begin... //如何得到dmac和smac?end...
endclass
- m_sequencer 是继承于 uvm_transaction 的 uvm_sequence_item 中,定义为 uvm_sequencer_base 类型的变量,即是个定义在 sequence 里的 sequencer。
- uvm_sequence_item 中的变量,默认情况下在每个sequence中都可用
- uvm_sequence 继承于 uvm_sequence_item
- uvm_sequence 和 uvm_sequence_item都继承于 uvm_object
p_sequencer:
方法一
// 创建继承于 uvm_sequencer 的 my_sequencer
`uvm_do_with 宏,这个宏完成了三个步骤:
• sequence 或 item 的创建;
• sequence 或 item 的随机化;
• sequence 或 item 的传送uvm_do_with(sequencer, {sequencer.seq_item = values}
class case0_sequence extends uvm_sequence #(my_transaction);my_trasaction m_trans;`uvm_object_utils(case0_squence)...virtual task body();my_sequencer x_sequencer; // class my_sequencer extends uvm_sequencer #(my_transaction); 声明uvm_sequencer类型变量x_sequencer...$cast(x_sequencer, m_sequencer); // 将m_sequencer转换为x_sequencer...endtask: bodyrepeat(10) begin`uvm_do_with(m_trans,{m_trans.dmac==x_sequencer.dmac;m_trans.smac==x_sequencer.smac;}) // `uvm_do_with宏创建item,并调用item.randomize()对item进行约束,(item.randomize with {m_trans.dmac==x_sequencer.dmac; m_trans.smac==x_sequencer.smac;})end...
endclass
- sequencer 是继承于 uvm_sequencer,uvm_sequencer 是 uvm_component 类型;uvm_component 可以通过树形组织结构管理,可以很方便的通过 uvm_config_db 实现对其类成员的参数设置
- sequence 属于 uvm_object,不属于UVM结构中,sequence 属于 uvm_component,在UVM结构中。sequence 必须挂到 sequencer,才能获得顶层的配置和更多信息
- case 属于 sequence 类型,uvm_sequence 是 uvm_sequence_item 类型,sequence(子弹) 从 sequencer(弹夹) 发送,如何得到 sequencer(弹夹) 的 dmac 和 smac?
- sequence 中变量 m_sequencer 类型是 uvm_sequencer_base(uvm_sequencer的基类),而不是 my_sequencer 类型,sequence 如何通过自己的成员变量 m_sequencer,拿到 sequencer 的 dmac 和 smac?
方法一:在 case0_sequence 的 body 中创建 my_sequencer 类型变量 x_sequencer,再 $cast(x_sequencer, m_sequencer),m_sequencer 通过 cast 转换成 x_sequencer,相当于 my_sequencer m_sequencer? sequence 通过自己的成员变量挂载在 sequencer上?
- m_sequencer 可作为媒介,用于从 sequence 中访问组件层次结构中的配置信息和其他资源。可以通过调用m_sequencer.get_full_name() 来获取 sequencer 的完整层次名称
方法二 UVM内建宏 `uvm_declare_p_sequencer(SEQUENCER)
// 使用宏定义 声明一个 my_sequencer 类型的成员变量 p_sequencer class case0_sequence extends uvm_sequence #(my_transaction);my_trasaction m_trans;`uvm_object_utils(case0_squence)`uvm_declare_p_sequencer(my_sequencer) // UVM内建宏`uvm_declare_p_sequencer(SEQUENCER),UVM会自动将m_sequencer通过$cast() 转换成 my_sequencer 类型的 p_sequencer,在pre_body() 之前完成...virtual task body();...repeat(10) begin`uvm_do_with(m_trans,{m_trans.dmac==p_sequencer.dmac;m_trans.smac==p_sequencer.smac;})end...
endclass
`uvm_declare_p_sequencer(my_sequencer)宏的作用:
- 声明了一个my_sequencer类型的句柄p_sequencer
- 将 m_sequencer 句柄通过 $cast(p_sequencer,m_sequencer) 转化为 p_sequencer 类型的句柄。
- uvm_sequencer_base -> uvm_sequencer_param_base #(REQ,RSP) -> uvm_sequencer -> my_sequencer
- uvm_sequencer_base m_sequencer
- uvm_sequencer p_sequencer
- m_sequencer 是 p_sequencer 的父类
- $cast(p_sequencer, m_sequencer) ,向下类型转换?
- case0_sequence.start(my_sequencer),则 start() 任务将分配 case0_sequence.m_sequencer 作为my_sequencer,case0_sequence 可以使用 m_sequencer 访问组件层次结构。例如通过调用m_sequencer.get_full_name() 来获取 sequencer 的完整层次名称。请注意,m_sequencer的类型是uvm_sequencer_base
equence/item一旦“挂载”到某一个sequencer上,该sequencer的句柄即被赋值于m_sequencer(uvm_sequencer_base类);而p_sequencer通常需要通过在定义sequence类使,通过宏`uvm_declare_p_sequencer(SEQUENCER)声明,间接定义p_sequencer成员变量。m_sequencer与p_sequencer均指向同一个挂载的sequencer句柄,只是前者使父类句柄,后者往往是所挂载sequencer句柄(子类句柄)
cast
对于两个具有继承关系的class,若对应父类的instance为father_tr,而子类的instance为child_tr,那么如果只是让子类的指针指向父类,有以下几种操作方法:
1、简单赋值:fathrer_tr = child_tr;
2、使用copy函数:father_tr = child_tr.copy();
3、使用cast函 数:cast(father_tr, child_tr);
以上3种方法均可实现数据的传递,但有本质区别:(1)通过简单赋值操作,使两个handle father_tr和child_tr指向了同一块memory,因此,father_tr的类型也会变成子类的类型。(2)使用copy函数,是将数值进行简单的copy,即将child_tr对应的memory中的数据放入father_tr对应的memory中,这种数据的copy方式,不会带来类型的变化,因此,father_tr仍然是父类的类型,但使用copy函数要求father_tr得先new一块memory, 如果没有memory,则需要使用clone函数。(3)此处的$cast操作与(1)中的简单赋值很类似,father_tr的类型也会变为子类的类型。
上面子类向父类进行数据传递时,显示不出cast操作向下类型转换的优势,但父类向子类传递数据时,无法使用child_tr = father_tr,则必须要使用$cast操作。
直接使用cast(child_tr, father_tr)是非法的,此时则要求基类的handle必须指向派生类的对象,即father_tr必须指向child_tr类型的对象,因此一般会有如下几步操作:
1、定义一个派生类类型的对象:child1_tr = new;
2、father_tr = child1_tr;
3、$cast(child_tr, father_tr);
以上第(3)步,$cast会做类型检查,若类型兼容返回1,否则返回0。
m_sequencer是uvm_sequencer_base类型的句柄,默认情况下在每个sequence中都可用。要访问正在运行sequence 的真实sequencer ,我们需要将m_sequencer类型转化为真实sequencer ,通常称为p_sequencer。
// 下面是一个简单的示例,sequence 希望访问sequencer的 clock monitor组件class test_sequencer_c extends uvm_sequencer; clock_monitor_c clk_monitor;
endclassclass test_sequence_c extends uvm_sequence;test_sequencer_c p_sequencer; // sequencer/monitor在sequence中声明clock_monitor_c my_clock_monitor;task pre_body() //Typecast the m_sequencer base type to p_sequencerif(!$cast(p_sequencer, m_sequencer)) begin // m_sequencer转p_sequencer,sequence挂载sequencer`uvm_fatal("Sequencer Type Mismatch:", " Worng Sequencer");end//get access to clock monitormy_clock_monitor = p_sequencer.clk_monitor; // sequence中声明的monitor连接sequencer的monitorendtask
endclass
UVM m_sequencer 和 p_sequencer相关推荐
- m_sequencer和p_sequencer
每次重读白皮书,总能看到之前忽视掉的很多,总会有些许收获. 1.m_sequencer和p_sequencer 1.类型 m_sequencer 是每个sequence中都有的默认成员变量,它的类型 ...
- UVM—virtual sequencer and virtual sequence详解
目录 1.前言 2.virtual sequencer使用环境 3. virtual sequencer 和virtual sequence的作用 4.m_sequencer与p_sequencer ...
- 理解UVM中的virtual sequencer和virtual sequence
这周看了Cliff的文章<Using UVM Virtual Sequencers & Virtual Sequences>,本文相当于是一个阅读记录. 一.什么时候需要virtu ...
- 【UVM】sequence 的启动方式
该篇文章描述不清楚的地方建议参考:UVM设计模式 (七)命令模式.三种sequence启动方式.start_item/finish_item.中介模式.virtual sequence_Holden_ ...
- 【面经】【经验分享】研究生导师是路桑,找工作是一种什么样的体验?
点击蓝字 关注我们 编者说 一直想让竹兄给大家写一个经验分享,今天终于约到了稿子,作为路桑的学生,有一些独特的经历和经验分享给大家,本文分为两大部分,第一部分为经验分享,问答,第二部分为竹秋一的秋招面 ...
- sequence机制
New 与 ::Type_id::create的区别(详见工厂机制) UVM推荐使用内置方法 :: type_id :: create() ,而不是直接调用构造函数new()创建组件或事务对象.cre ...
- Testbench Hierarchy
目录 UVM Testbench Top UVM Test [uvm_test] UVM Environment [uvm_env] UVM Driver [uvm_driver] Sequencer ...
- UVM中p_sequencer和m_sequencer的用法及其区别
在sequencer中存在如下成员变量: 文件:my_sequencer.sv 4 class my_sequencer extends uvm_sequencer #(my_transaction) ...
- uvm 形式验证_uvm面试题
1.uvm_component与uvm_object之间的区别和联系? uvm_component类:是用于构成UVM仿真平台的组件,可组成树形结构,在bulid_phase中创建,之后整个仿真周期内 ...
最新文章
- mysql 审核引擎 goInception 的基本使用
- java null布局_Java Swing 绝对布局管理方法,null布局
- Sencha Touch 笔记
- numpy 创建加一行_Python数据分析快速入门--NumPy amp; Pandas
- DevExpress WinForms v18.2新版亮点(一)
- shell实现矩阵转置
- MySQL-8.0.12-winx64
- 前端学习(2432):上午总结
- 五分钟实现SpringBoot快速入门
- 信息学奥赛一本通(2028:【例4.14】百钱买百鸡)
- java中的 ok_java okhttp包的类特点
- 扎克伯格夏威夷州大肆买地引发当地不满 被批搞“新殖民主义”
- 索引sql server_SQL Server索引结构和概念
- Balder 3D开发系列之--给自定义基本体进行贴图操作
- transform2D转换
- openbsd下实现双网卡负载均衡
- [Unity3D]ml-agent入门案例
- 【Unity3D】初学加密技巧(反破解)
- python读取grd数据_Matlab读取grd格式的文件
- 给大家推荐几个程序员必备网站