ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UVM-sequence,sequencer,driver

2022-01-23 14:58:40  阅读:189  来源: 互联网

标签:sequence req driver item UVM sequencer phase data uvm


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_end
		function new(string name = "item");
			super.new(name);
		endfunction
	endclass
	
	class seq extends uvm_sequence;
		`uvm_object_utils(seq)
		function new(string name = "seq");
			super.new(name);
		endfunction
		task 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();
		endtask
	endclass

			
	class seqr extends uvm_sequencer;
		`uvm_component_utils(seqr)
		function new(string name = "seqr", uvm_component parent = null);
			super.new(name, parent);
		endfunction
	endclass

	class dri extends uvm_driver;
		`uvm_component_utils(dri)
		function new(string name = "dri", uvm_component parent = null);
			super.new(name, parent);
		endfunction
		
		task 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需要先落手
		endtask

	endclass

	class 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 和 driver
		function 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);
		endfunction
		
	endclass


	class test1 extends uvm_test;
		env env0;
		`uvm_component_utils(test1)
		function new(string name = "test1", uvm_component parent = null);
			super.new(name, parent);
		endfunction

		function void build_phase(uvm_phase phase);
			super.build_phase(phase);
			env0 = env::type_id::create("env0",this);
			`uvm_info("test1",$sformatf("build"), UVM_LOW)
		endfunction

		task 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需要先落手
		endtask
	endclass

endpackage

//--------------------------------------module---------------------------------
module hardware1;
	import pack1::*;
	import uvm_pkg::*; //+UVM

	
	initial begin
		run_test("test1"); 	
	end
		
endmodule

标签:sequence,req,driver,item,UVM,sequencer,phase,data,uvm
来源: https://blog.csdn.net/helloworld573/article/details/122651582

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有