UVM-使用start发送item,sequence
当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相关推荐
- UVM 使用start_item和finish_item指定sequencer发送item,比uvm_do_on更灵活。
我们使用uvm_do_on(item,sqr)是可以指定那个sequencer发送此.而且uvm_do系列宏第一个参数即可以是sequence也可以是transaction,当是sequence时使用 ...
- (22)UVM 虚拟类序列(virtual sequence)
UVM 虚拟类序列(virtual sequence) 文章目录 UVM 虚拟类序列(virtual sequence) virtual sequence介绍 virtual存在对于sequence和 ...
- UVM—virtual sequencer and virtual sequence详解
目录 1.前言 2.virtual sequencer使用环境 3. virtual sequencer 和virtual sequence的作用 4.m_sequencer与p_sequencer ...
- 【UVM实战】第二章:一个简单的UVM验证平台(4)UVM 的终极大作:sequence
文章目录 2.4.1.在验证平台中加入sequencer 2.4.2.sequence机制 2.4.3.default_sequence的使用 2.4.1.在验证平台中加入sequencer sequ ...
- UVM——sequence item
此处sequence泛指uvm_sequence_item类,item泛指uvm_sequence_item类. sequence用来实现激励生成和场景控制:item实现对激励所需要的具体数据和控制要 ...
- (16)UVM sequence和item
UVM sequence和item 文章目录 UVM sequence和item 一.概述 二.sequence item介绍 三.item使用时的特点 四.item与sequence的关系 五.fl ...
- UVM学习笔记--sequence和sequencer
1. UVM sequence机制的意义 UVM的sequence机制最大的作用就是将test case和testbench分离开来. 对一个项目而言,testbench是相对稳定的框架,而针对各个m ...
- sequence和sequencer — UVM
文章目录 简介 1.sequence 和 item 2.sequencer 和 driver 1. 通信方式--TLM端口 2.事务传输 3. 通信时序 3.sequence和sequencer 1. ...
- UVM基础-Sequence、Sequencer(二)
目录 sequence和sequencer 将sequence挂载到sequencer 将item挂载到sequencer 宏定义使用实例 sequencer仲裁特性 实例 sequencer的锁定机 ...
最新文章
- LeetCode简单题之判断能否形成等差数列
- 将字符串下标为奇数的字符按ASCII码大小递增排序,并将排序后下标为奇数的字符取出
- NETMF Versions 4.1 Release 发布
- loading动画_超干货 CSS3/SVG Loading动画集合
- aix升级openssh_AIX5.3如何安装openssh | 学步园
- 浅谈javaweb三大框架和MVC设计模式
- 使用腾讯云轻量应用服务器搭建视频直播服务器
- 小米运动蓝牙耳机重新配对_小米运动蓝牙耳机怎么连接手机
- 【UNI-APP】新闻资讯APP总结
- 斑马zpl指令二维码换行
- 如何看待华文的《二十岁无资本无未来》?
- Oracle数据性能优化
- C#结合天敏VC4000采集卡视频监控
- linux如何压缩为gz文件,将一个.gz文件拆分为多个1GB压缩(.gz)文件
- 使用静默方式安装Oracle数据库软件
- 音乐制作软件中文版-Studio One 4.5.1 WiN-MAC
- Gogs项目管理使用教程
- 新疆计算机网络应急预案,计算机网络故障应急预案
- 几何画板中功能使用技巧[剪切、延长、对齐、垂线段、平行线段]
- 对于自媒体,papi酱和咪蒙的变现方式