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相关推荐

  1. m_sequencer和p_sequencer

    每次重读白皮书,总能看到之前忽视掉的很多,总会有些许收获. 1.m_sequencer和p_sequencer 1.类型  m_sequencer 是每个sequence中都有的默认成员变量,它的类型 ...

  2. UVM—virtual sequencer and virtual sequence详解

    目录 1.前言 2.virtual sequencer使用环境 3. virtual sequencer 和virtual sequence的作用 4.m_sequencer与p_sequencer ...

  3. 理解UVM中的virtual sequencer和virtual sequence

    这周看了Cliff的文章<Using UVM Virtual Sequencers & Virtual Sequences>,本文相当于是一个阅读记录. 一.什么时候需要virtu ...

  4. 【UVM】sequence 的启动方式

    该篇文章描述不清楚的地方建议参考:UVM设计模式 (七)命令模式.三种sequence启动方式.start_item/finish_item.中介模式.virtual sequence_Holden_ ...

  5. 【面经】【经验分享】研究生导师是路桑,找工作是一种什么样的体验?

    点击蓝字 关注我们 编者说 一直想让竹兄给大家写一个经验分享,今天终于约到了稿子,作为路桑的学生,有一些独特的经历和经验分享给大家,本文分为两大部分,第一部分为经验分享,问答,第二部分为竹秋一的秋招面 ...

  6. sequence机制

    New 与 ::Type_id::create的区别(详见工厂机制) UVM推荐使用内置方法 :: type_id :: create() ,而不是直接调用构造函数new()创建组件或事务对象.cre ...

  7. Testbench Hierarchy

    目录 UVM Testbench Top UVM Test [uvm_test] UVM Environment [uvm_env] UVM Driver [uvm_driver] Sequencer ...

  8. UVM中p_sequencer和m_sequencer的用法及其区别

    在sequencer中存在如下成员变量: 文件:my_sequencer.sv 4 class my_sequencer extends uvm_sequencer #(my_transaction) ...

  9. uvm 形式验证_uvm面试题

    1.uvm_component与uvm_object之间的区别和联系? uvm_component类:是用于构成UVM仿真平台的组件,可组成树形结构,在bulid_phase中创建,之后整个仿真周期内 ...

最新文章

  1. mysql 审核引擎 goInception 的基本使用
  2. java null布局_Java Swing 绝对布局管理方法,null布局
  3. Sencha Touch 笔记
  4. numpy 创建加一行_Python数据分析快速入门--NumPy amp; Pandas
  5. DevExpress WinForms v18.2新版亮点(一)
  6. shell实现矩阵转置
  7. MySQL-8.0.12-winx64
  8. 前端学习(2432):上午总结
  9. 五分钟实现SpringBoot快速入门
  10. 信息学奥赛一本通(2028:【例4.14】百钱买百鸡)
  11. java中的 ok_java okhttp包的类特点
  12. 扎克伯格夏威夷州大肆买地引发当地不满 被批搞“新殖民主义”
  13. 索引sql server_SQL Server索引结构和概念
  14. Balder 3D开发系列之--给自定义基本体进行贴图操作
  15. transform2D转换
  16. openbsd下实现双网卡负载均衡
  17. [Unity3D]ml-agent入门案例
  18. 【Unity3D】初学加密技巧(反破解)
  19. python读取grd数据_Matlab读取grd格式的文件
  20. 给大家推荐几个程序员必备网站

热门文章

  1. Eclipse启动时闪退问题解决方案
  2. ASEMI场效应管7N60的极限和静态参数详解
  3. Axure实战——实现登录注册功能
  4. 计算机图像处理要学什么软件有哪些,电脑中常用的图像处理软件有哪些
  5. pytho中的json序列化与反序列化操作
  6. Verilog语言、语法
  7. c#加密:二、散列法 MD5、SHA256、SHA512
  8. vue + elementui table 列内容相同 自动合并单元格 完整代码
  9. python str怎么用_python的str函数怎么使用
  10. 丢番图方程c语言114,丢番图方程的实现