【UVM】virtual sequencer 与 virtual sequence (含可运行示例代码)

Virtual sequencer

Virtual sequencer 有三个属性:
Virtual sequencer 中装有其他的sequencer的句柄
Virtual sequencer并不和任何driver相连
Virtual sequencer本身并不处理item

m_sequencer 与 p_sequencer

m_sequencer是uvm_sequencer类型的句柄,是每个sequence中自带的属性
一旦sequence被挂载到某个sequencer,那么m_sequencer就会指向这个sequencer

p_sequencer可以理解为将m_sequencer做了类型转换,使m_sequencer适应多种子类sequencer

示例

在这里插入图片描述

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

	
	initial begin
		run_test("test1"); 	
	end
		
endmodule


//-------------------------------------package--------------------------------
package pack1; //pack1头
	import uvm_pkg::*; //+UVM
  	`include "uvm_macros.svh"//+工厂

//-----------------------------------A----------------------------------------//	
//A-item
	class item_a extends uvm_sequence_item;
		rand bit [7:0] data_a;
		`uvm_object_utils_begin(item_a)
			`uvm_field_int(data_a,UVM_ALL_ON)
		`uvm_object_utils_end
		function new(string name = "item_a");
			super.new(name);
		endfunction
	endclass


//A-sequence
	class seq_a extends uvm_sequence;
		rand int database = 0;
		`uvm_object_utils(seq_a)
		function new(string name = "seq_a");
			super.new(name);
		endfunction
		task body();
			item_a req;
			repeat(3) begin
			#20ns;
			`uvm_do_with(
					req,
					{data_a inside {[database:database+9]};}
				)
			end
			#20ns;
		endtask
	endclass

//A-sequencer
	class seqr_a extends uvm_sequencer;
		`uvm_component_utils(seqr_a)
		function new(string name = "seqr_a", uvm_component parent = null);
			super.new(name, parent);
		endfunction
	endclass

//A-driver
	class dri_a extends uvm_driver;
		`uvm_component_utils(dri_a)
		function new(string name = "dri_a", uvm_component parent = null);
			super.new(name, parent);
		endfunction
		task run_phase(uvm_phase phase);
			uvm_sequence_item temp;
			item_a req;
			forever begin
				seq_item_port.get_next_item(temp);
				void'($cast(req,temp));
				$display("\n=================================================");
				`uvm_info("dri_a","driver already recive item", UVM_LOW)
				`uvm_info("dri_a",$sformatf("item in sequence:%s",req.get_parent_sequence().get_name()), UVM_LOW)
				`uvm_info("data",$sformatf("%d",req.data_a), UVM_LOW)
				$display("=================================================\n");
				seq_item_port.item_done();
			end
		endtask
	endclass


//A-agent
	class agent_a extends uvm_agent;
		dri_a driver;
    		seqr_a sequencer;
    		`uvm_component_utils(agent_a)
    		function new(string name = "agent_a", uvm_component parent);
      			super.new(name, parent);
    		endfunction

    		function void build_phase(uvm_phase phase);
      			super.build_phase(phase);
      			driver = dri_a::type_id::create("driver", this);
      			sequencer = seqr_a::type_id::create("sequencer", this);
    		endfunction

   	 	function void connect_phase(uvm_phase phase);
      			super.connect_phase(phase);
      			driver.seq_item_port.connect(sequencer.seq_item_export);
    		endfunction

  	endclass



//-----------------------------------B----------------------------------------//	
//B-item
	class item_b extends uvm_sequence_item;
		rand bit [7:0] data_b;
		`uvm_object_utils_begin(item_b)
			`uvm_field_int(data_b,UVM_ALL_ON)
		`uvm_object_utils_end
		function new(string name = "item_b");
			super.new(name);
		endfunction
	endclass

//B-sequence
	class seq_b extends uvm_sequence;
		rand int database = 0;
		`uvm_object_utils(seq_b)
		function new(string name = "seq_b");
			super.new(name);
		endfunction
		task body();
			item_b req;
			`uvm_do_with(
					req,
					{data_b inside {[database:database+9]};}
				)
		endtask
	endclass
//B-sequencer
	class seqr_b extends uvm_sequencer;
		`uvm_component_utils(seqr_b)
		function new(string name = "seqr_b", uvm_component parent = null);
			super.new(name, parent);
		endfunction
	endclass

//B-driver
	class dri_b extends uvm_driver;
		`uvm_component_utils(dri_b)
		function new(string name = "dri_b", uvm_component parent = null);
			super.new(name, parent);
		endfunction
		task run_phase(uvm_phase phase);
			uvm_sequence_item temp;
			item_b req;
			forever begin
				seq_item_port.get_next_item(temp);
				void'($cast(req,temp));
				$display("\n=================================================");
				`uvm_info("dri_b","driver already recive item", UVM_LOW)
				`uvm_info("dri_b",$sformatf("item in sequence:%s",req.get_parent_sequence().get_name()), UVM_LOW)
				`uvm_info("data",$sformatf("%d",req.data_b), UVM_LOW)
				$display("=================================================\n");
				seq_item_port.item_done();
			end
		endtask
	endclass

//B-agent
	class agent_b extends uvm_agent;
		dri_b driver;
    		seqr_b sequencer;
    		`uvm_component_utils(agent_b)
    		function new(string name = "agent_b", uvm_component parent);
      			super.new(name, parent);
    		endfunction

    		function void build_phase(uvm_phase phase);
      			super.build_phase(phase);
      			driver = dri_b::type_id::create("driver", this);
      			sequencer = seqr_b::type_id::create("sequencer", this);
    		endfunction

   	 	function void connect_phase(uvm_phase phase);
      			super.connect_phase(phase);
      			driver.seq_item_port.connect(sequencer.seq_item_export);
    		endfunction

  	endclass



//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//-----------------------------------------------------------------------------
//=============================================================================
//*****************************************************************************
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//-------------------------------vseqr,vseq,env,test---------------------------
	class v_seqr extends uvm_sequencer;
		seqr_a sequencer_a;
		seqr_b sequencer_b;
		`uvm_component_utils(v_seqr)
		function new(string name="v_seqr" ,uvm_component parent = null);
				super.new(name,parent);
		endfunction
	endclass

	class v_seq extends uvm_sequence;
		`uvm_object_utils(v_seq)
		`uvm_declare_p_sequencer(v_seqr)	
		//这个宏的作用:声明p_sequencer指针
		//并完成m_sequencer到p_sequencer的类型转化
		//(记住p_sequencer是指向virtual_sequencer的就行)
		function new(string name="v_seq");
				super.new(name);
		endfunction
		task body();
			seq_a sequence_a;
			seq_b sequence_b;
			fork
				`uvm_do_on_with(sequence_a,p_sequencer.sequencer_a,{database == 10;} )
				`uvm_do_on_with(sequence_b,p_sequencer.sequencer_b,{database == 100;})
				//由于virtual_sequence里面要发送多个挂载到不同
				//sequencer的sequence,所以使用`uvm_do_on宏可以直接指
				//明待发送sequence要挂载的sequencer
			join
		endtask
	
	endclass	
	

	class env extends uvm_env;
		agent_a ag_a;
		agent_b ag_b;
		v_seqr  vir_seqr;
		`uvm_component_utils(env)
		function new(string name="env" ,uvm_component parent = null);
			super.new(name,parent);
		endfunction
		function void build_phase(uvm_phase phase);
			ag_a = agent_a::type_id::create("ag_a",this);		
			ag_b = agent_b::type_id::create("ag_b",this);		
			vir_seqr = v_seqr::type_id::create("vir_seqr",this);		
			//例化所有的agent,和一个virtual_sequencer
		endfunction
		function void connect_phase(uvm_phase phase);
			//将virtual_sequencer中悬空的句柄,连接到具体对象
			vir_seqr.sequencer_a = ag_a.sequencer;
			vir_seqr.sequencer_b = ag_b.sequencer;
		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);
			v_seq seq0;
			phase.raise_objection(this);
			`uvm_info("test1",$sformatf("run"), UVM_LOW)
			this.print();
			$display("======================================================");
			
			seq0 = new();
			seq0.start(env0.vir_seqr);
			
			phase.drop_objection(this);//退出run_phase需要先落手
		endtask
	endclass

endpackage

输出结果:
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搞IC的那些年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值