当sequence得知自己挂载的sequencer时,他就会调用sequencer自带的TLM端口与driver(的TLM端口)进行通信
而sequencer在这里就像一个傀儡

  • I sequence中拥有item
  • II sequence中拥有item和sequence
    • 使用start启动sequence
    • 使用start启动item
    • 发送item和sequence的小知识总结

I sequence中拥有item

package pack1; //pack1头import uvm_pkg::*; //+UVM`include "uvm_macros.svh"//+工厂class item extends uvm_sequence_item;rand int data_auto;rand int data_noauto;//声明两个data,一个加入自动化域,一个//不加入`uvm_object_utils_begin(item)`uvm_field_int(data_auto,UVM_ALL_ON)`uvm_object_utils_endfunction new(string name = "item");super.new(name);endfunctionendclassclass seq extends uvm_sequence;`uvm_object_utils(seq)function new(string name = "seq");super.new(name);endfunctiontask body();uvm_sequence_item temp;item req,rsp;temp = create_item(item::get_type(),m_sequencer,"req");//create_item:能够实例化一个继承于uvm_sequence_item类的类//返回值:uvm_sequence_item句柄//参数1:指明要例化的继承于uvm_sequence_item类的类//参数2:指明这个对象即将挂载到哪个sequencer上//       (m_sequencer是uvm_sequence类的一个属//       性,当m_sequencer被挂载到某个//       sequencer上时,m_sequencer会自动指向//       这个sequencer)//参数3:这个对象的名字void'($cast(req,temp));//在上一句话中由于使用create_item方法,导致//父类句柄指向子类对象//(uvm_sequence_item句柄) --> (item对象)//做个转化使子类对象重新被子类句柄指向start_item(req);void'(req.randomize with{data_auto == 50;data_noauto == 50;});`uvm_info("sequence","sequence request to send item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",req.data_auto), UVM_LOW)`uvm_info("data_noauto",$sformatf("%d",req.data_noauto), UVM_LOW)req.print();finish_item(req);////seq发起start告知seqr,我要向driver发送item//(start会立即返回,然后执行下面的语句)//seqr判断此时的driver是否已经get_next_item,//若否,则继续等待。若是,那么driver收到完item//后会执行item_done,收到item_done后,//finish_item的阻塞结束//get_response(temp);  //get_response返回的uvm_sequence_item是句柄,//需要做个中间转化void'($cast(rsp,temp));`uvm_info("sequence","sequence already recive item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",rsp.data_auto), UVM_LOW)`uvm_info("data_noauto",$sformatf("%d",rsp.data_noauto), UVM_LOW)req.print();endtaskendclassclass seqr extends uvm_sequencer;`uvm_component_utils(seqr)function new(string name = "seqr", uvm_component parent = null);super.new(name, parent);endfunctionendclassclass dri extends uvm_driver;`uvm_component_utils(dri)function new(string name = "dri", uvm_component parent = null);super.new(name, parent);endfunctiontask run_phase(uvm_phase phase);uvm_sequence_item temp ;uvm_object temp1;item req,rsp;phase.raise_objection(this);//进入run_phase需要先举手seq_item_port.get_next_item(temp);void'($cast(req,temp));`uvm_info("driver","driver already recive item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",req.data_auto), UVM_LOW)`uvm_info("data_noauto",$sformatf("%d",req.data_noauto), UVM_LOW)req.print();//driver使用自带的TLM端口,向seqr的TLM端口使用get_next_item//来获取一个对象,(get_next_item返回的是uvm_sequence_item//句柄需要类型转换)#1us;//---------------------------------------------//--此处省略driver解析item并向interface进行驱动//---------------------------------------------temp1 = req.clone();void'($cast(rsp,temp1));`uvm_info("clone:data_auto",$sformatf("%d",rsp.data_auto), UVM_LOW)`uvm_info("clone:data_noauto",$sformatf("%d",rsp.data_noauto), UVM_LOW)//克隆一个上一步接收到的对象//(clone返回的居然是uvm_object的句柄,需要类型转换)//!!clone只会克隆已经加入自动化域的属性的值,//data_noauto不在自动化域内,在克隆时候,类声明时候的//默认值0,而不是req的对象值50//同样‘req’的sequence_id也不会被克隆,克隆时候得到的也//是类中的声明初始值rsp.set_sequence_id(req.get_sequence_id());rsp.data_auto = rsp.data_auto + 100;rsp.data_noauto = rsp.data_noauto + 100;seq_item_port.item_done(rsp);//get_sequence_id用于获取‘req’这个item所在sequence的id好//然后使用set_sequence_id把id号交给‘rsp’这个item//这样item_done这个方法就知道要把‘rsp’这个item发送给谁//了//细节来说,item_done这个方法的作用有两个//1是:告知seq的finish_item,你别在那阻塞了,我都消化//     掉了//2是:向seqr的rspfifo中传递rsp这个对象//     这样sequence里的get_response才能得到对象//     要不然是得不到对象的`uvm_info("driver","driver already send item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",rsp.data_auto), UVM_LOW)`uvm_info("data_noauto",$sformatf("%d",rsp.data_noauto), UVM_LOW)phase.drop_objection(this);//退出run_phase需要先落手endtaskendclassclass env extends uvm_env;seqr seqr0;dri dri0;`uvm_component_utils(env)function new(string name="env" ,uvm_component parent = null);super.new(name,parent);endfunction//buildphase中例化sequencer 和 driverfunction void build_phase(uvm_phase phase);seqr0 = seqr::type_id::create("seqr0",this);     dri0 = dri::type_id::create("dri0",this);        endfunction//connect_phase中连接sequencer和driver自带的一组TLM端口function void connect_phase(uvm_phase phase);dri0.seq_item_port.connect(seqr0.seq_item_export);endfunctionendclassclass test1 extends uvm_test;env env0;`uvm_component_utils(test1)function new(string name = "test1", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env0 = env::type_id::create("env0",this);`uvm_info("test1",$sformatf("build"), UVM_LOW)endfunctiontask run_phase(uvm_phase phase);seq seq0;phase.raise_objection(this);//进入run_phase需要先举手`uvm_info("test1",$sformatf("run"), UVM_LOW)seq0 = new();seq0.start(env0.seqr0);//将seq0挂载到 env0的seqr0上//一旦seq被挂载到了seqr上,那么这个seq就知道了他的m_seqencer是谁//他的body任务也会自动执行phase.drop_objection(this);//退出run_phase需要先落手endtaskendclassendpackage//--------------------------------------module---------------------------------
module hardware1;import pack1::*;import uvm_pkg::*; //+UVMinitial beginrun_test("test1");    endendmodule

II sequence中拥有item和sequence

package pack1; //pack1头import uvm_pkg::*; //+UVM`include "uvm_macros.svh"//+工厂class item extends uvm_sequence_item;rand int data_auto;`uvm_object_utils_begin(item)`uvm_field_int(data_auto,UVM_ALL_ON)`uvm_object_utils_endfunction new(string name = "item");super.new(name);endfunctionendclass//底层sequenceclass child_seq extends uvm_sequence;`uvm_object_utils(child_seq)function new(string name = "child_seq");super.new(name);endfunctiontask body();uvm_sequence_item temp;item req;temp = create_item(item::get_type(),m_sequencer,"req");void'($cast(req,temp));start_item(req);void'(req.randomize with{data_auto == 99;});`uvm_info("child_seq","i want to send item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",req.data_auto), UVM_LOW)finish_item(req);//不get responseendtaskendclass//顶层sequenceclass top_seq extends uvm_sequence;`uvm_object_utils(top_seq)function new(string name = "top_seq");super.new(name);endfunctiontask body();uvm_sequence_item temp;item req;child_seq cseq;//创建一个sequcence和一个item对象cseq = child_seq::type_id::create("cseq");temp = create_item(item::get_type(),m_sequencer,"req");void'($cast(req,temp));//发送sequencecseq.start(m_sequencer,this);//start任务的入口参数有4个(这里使用两个)://参数1指定了挂载的是哪个sequencer,//(m_sequencer是什么请看第一节的代码)//参数2是如果你start这个sequence不是最顶层的sequence,那么请你为他指定上级//发送itemstart_item(req);void'(req.randomize with{data_auto == 66;});`uvm_info("top_seq","i want to send item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",req.data_auto), UVM_LOW)finish_item(req);//不get responceendtaskendclassclass seqr extends uvm_sequencer;`uvm_component_utils(seqr)function new(string name = "seqr", uvm_component parent = null);super.new(name, parent);endfunctionendclassclass dri extends uvm_driver;`uvm_component_utils(dri)function new(string name = "dri", uvm_component parent = null);super.new(name, parent);endfunctiontask run_phase(uvm_phase phase);uvm_sequence_item temp ;item req;forever beginseq_item_port.get_next_item(temp);void'($cast(req,temp));`uvm_info("driver","driver already recive item", UVM_LOW)`uvm_info("data_auto",$sformatf("%d",req.data_auto), UVM_LOW)//只告诉完成,不发送响应(response)seq_item_port.item_done();endendtaskendclassclass env extends uvm_env;seqr seqr0;dri dri0;`uvm_component_utils(env)function new(string name="env" ,uvm_component parent = null);super.new(name,parent);endfunctionfunction void build_phase(uvm_phase phase);seqr0 = seqr::type_id::create("seqr0",this);        dri0 = dri::type_id::create("dri0",this);        endfunctionfunction void connect_phase(uvm_phase phase);dri0.seq_item_port.connect(seqr0.seq_item_export);endfunctionendclassclass test1 extends uvm_test;env env0;`uvm_component_utils(test1)function new(string name = "test1", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env0 = env::type_id::create("env0",this);`uvm_info("test1",$sformatf("build"), UVM_LOW)endfunctiontask run_phase(uvm_phase phase);top_seq seq0;phase.raise_objection(this);`uvm_info("test1",$sformatf("run"), UVM_LOW)seq0 = new();seq0.start(env0.seqr0);phase.drop_objection(this);//退出run_phase需要先落手endtaskendclassendpackage//--------------------------------------module---------------------------------
module hardware1;import pack1::*;import uvm_pkg::*; //+UVMinitial beginrun_test("test1");    endendmodule

使用start启动sequence

启动sequence的start可以在另一个sequence内部,如 II 中的topseq 和 childseq (sequence嵌套sequence)
也可以在别的地方使用,如I 和 II 中的test

函数原型:
virtual task start (uvm_sequencer_base sequencer,

uvm_sequence_base parent_sequence = null,

int this_priority = -1,

bit call_pre_post = 1);
sequencer:指定了当前sequence要挂载的是哪个sequencer
parent_sequence :如果要start的这个sequence是个底层sequence(sequence套sequence)
就可以来为他指定parent。指定后会在这个start的过程中,调用父类的pre_do、mid_do、post_do
this_priority : 指明产生transaction的优先级,sequencer在某些条件下会根据优先级来将transaction发送给sequence。
call_pre_post :如果为1, 要启动的这个sequence的 pre_do(), mid_do(), post_do() 将会被调用。
调用顺序如下:
(sub指此sequence,parent即参数2)

使用start启动item

启动item的start只能在sequence中使用,

通常只使用第一个参数(想发送的item句柄)
调用顺序如下:
(sequencer是该item挂载的sequencer,parent_seq是该item所在的sequence)

发送item和sequence的小知识总结

1:sequence和item都有自身的优先级,可以决定什么时刻可以获得sequencer的授权
2:在发送item 或者在发送底层sequence的过程中,会调用上层sequence的一些方法:pre_do,mid_do,post_do,但一般情况都是让上层的这些方法为空,不然验证环境的可读性会变差。
3:在发送sequence的过程中,在执行body任务的前后,还会执行pre_body()和post_body(),但这个机制可以通过将start函数的第四个参数call_pre_post置0来关闭掉。

UVM-使用start发送item,sequence相关推荐

  1. UVM 使用start_item和finish_item指定sequencer发送item,比uvm_do_on更灵活。

    我们使用uvm_do_on(item,sqr)是可以指定那个sequencer发送此.而且uvm_do系列宏第一个参数即可以是sequence也可以是transaction,当是sequence时使用 ...

  2. (22)UVM 虚拟类序列(virtual sequence)

    UVM 虚拟类序列(virtual sequence) 文章目录 UVM 虚拟类序列(virtual sequence) virtual sequence介绍 virtual存在对于sequence和 ...

  3. UVM—virtual sequencer and virtual sequence详解

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

  4. 【UVM实战】第二章:一个简单的UVM验证平台(4)UVM 的终极大作:sequence

    文章目录 2.4.1.在验证平台中加入sequencer 2.4.2.sequence机制 2.4.3.default_sequence的使用 2.4.1.在验证平台中加入sequencer sequ ...

  5. UVM——sequence item

    此处sequence泛指uvm_sequence_item类,item泛指uvm_sequence_item类. sequence用来实现激励生成和场景控制:item实现对激励所需要的具体数据和控制要 ...

  6. (16)UVM sequence和item

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

  7. UVM学习笔记--sequence和sequencer

    1. UVM sequence机制的意义 UVM的sequence机制最大的作用就是将test case和testbench分离开来. 对一个项目而言,testbench是相对稳定的框架,而针对各个m ...

  8. sequence和sequencer — UVM

    文章目录 简介 1.sequence 和 item 2.sequencer 和 driver 1. 通信方式--TLM端口 2.事务传输 3. 通信时序 3.sequence和sequencer 1. ...

  9. UVM基础-Sequence、Sequencer(二)

    目录 sequence和sequencer 将sequence挂载到sequencer 将item挂载到sequencer 宏定义使用实例 sequencer仲裁特性 实例 sequencer的锁定机 ...

最新文章

  1. LeetCode简单题之判断能否形成等差数列
  2. 将字符串下标为奇数的字符按ASCII码大小递增排序,并将排序后下标为奇数的字符取出
  3. NETMF Versions 4.1 Release 发布
  4. loading动画_超干货 CSS3/SVG Loading动画集合
  5. aix升级openssh_AIX5.3如何安装openssh | 学步园
  6. 浅谈javaweb三大框架和MVC设计模式
  7. 使用腾讯云轻量应用服务器搭建视频直播服务器
  8. 小米运动蓝牙耳机重新配对_小米运动蓝牙耳机怎么连接手机
  9. 【UNI-APP】新闻资讯APP总结
  10. 斑马zpl指令二维码换行
  11. 如何看待华文的《二十岁无资本无未来》?
  12. Oracle数据性能优化
  13. C#结合天敏VC4000采集卡视频监控
  14. linux如何压缩为gz文件,将一个.gz文件拆分为多个1GB压缩(.gz)文件
  15. 使用静默方式安装Oracle数据库软件
  16. 音乐制作软件中文版-Studio One 4.5.1 WiN-MAC
  17. Gogs项目管理使用教程
  18. 新疆计算机网络应急预案,计算机网络故障应急预案
  19. 几何画板中功能使用技巧[剪切、延长、对齐、垂线段、平行线段]
  20. 对于自媒体,papi酱和咪蒙的变现方式

热门文章

  1. signature=0d1f35d89893214a8c8444df416b5518,Page 1
  2. python实现搜索引擎——搜索引擎架构(一)
  3. win7能用office365吗?问题分析如下
  4. [展览人周刊]华展云20170626期
  5. 转载丨区块链还有价值吗?我们采访了行业从业者
  6. 我的DUILIB常用库
  7. 一代传奇!经典播放器 Winamp 的开源实现
  8. python爬虫实战-豆瓣小组搜索关键字话题
  9. 首次支持国际赛事,搜狗如何为AI同传正名?
  10. ovs hot upgrade