UVM组件家族

一、概述

SV验证环境中的验证组件按照功能需要,被称之为激励器、监测器和检查器,这三个核心组件与验证环境的三个关键特性对应,即激励、监测和检查,并且有与其对应的组件(component)。UVM组件家族是从UVM基类继承的一个核心分支即uvm_component类。从uvm_component类继承的类都可以构成验证环境,这是因为它们都从uvm_component类继承了phase机制,也都会经历各个phase阶段。在UVM模块中,主要的构成验证环境的常见组件类包括:uvm_driveruvm_monitoruvm_sequenceruvm_agentuvm_scoreboarduvm_envuvm_test

在这里插入图片描述

二、uvm_driver类

1、概述

  • 该类会从uvm_sequencer中获取事务(transaction),经过转化进而在接口中对DUT进行时序激励。任何继承于uvm_driver的类需要注意的是,该类是参数化类,因此在定义时需要声明参数的类型。

  • uvm_driver类的定义:在定义新的driver类时,应当声明该类所需要获取的事务参数REQ类型,默认情况下,RSP参数类型同REQ类型保持一致。

class uvm_driver#(type REQ=uvm_sequence_item, type RSP=REQ) extends uvm_component;
  • uvm_driveruvm_component基础上没有扩展新的函数,而只是扩展了一些用来通信的端口和变量。
uvm_seq_item_pull_port#(REQ, RSP) seq_item_port;
uvm_analysis_port#(RSP) rsp_port;
REQ req;
RSP rsp;
  • driver类与sequencer类之间的通信就是为了获取新的事务对象,这一操作是通过pull的方式实现的。
driver.seq_item_port.connect(sequencer.seq_item_export);
driver.rsp_port.connect(sequencer.rsp_export);

2、示例

class dut_driver extends uvm_driver#(basic_transaction);		//参数化为sequence item类型
	virtual chip_if vif;										//虚接口
	bit[7:0] addr, data;
	`uvm_component_utils(dut_driver)							//在factory中注册dut_driver
	function new(string name, uvm_component parent);
		super.new(name, parent);
	endfunction
	extern task run_phase(uvm_phase phase);						//在运行过程中自动执行的run_phase
endclass

三、uvm_monitor类

1、概述

  • 这个类是为了监测接口数据,而任何自定义数据监测行为的monitor都应当继承于该类。
  • 虽然uvm_monitor与它的父类相比,并没有增添新的成员和方法,但是将新定义的monitor类继承于uvm_monitor类会有助于实现父类uvm_monitor的方法和特性。
  • 该类通常执行的功能包括:
    1、观测DUT的interface,并且收集总线信息。
    2、永远保持PASSIVE模式,即永远不会驱动DUT。
    3、在总线协议或者内部信号协议观察时,可以做一些功能和时序的检查。
    4、对于更加复杂的检查要求,它们可以将数据发送至其它验证组件,例如scoreboardreference model或者coverage collector

2、示例

class serial_monitor extends uvm_monitor;
	virtual serial_if.monitor mi;						//virtual interface + modport
	`uvm_component_utils(serial_monitor)
	function new(string name, uvm_component parent);
		super.new(name, parent);
	endfunction
	function void run_phase(uvm_phase phase);
		super.build_phase(phase);
	endfunction
	task run_phase(uvm_phase phase);
		serial_transaction tr;
		tr = new();
		forever begin
			wait(mi.rts);
			@(negedge mi.line);
			#(bit_period/2);
			for(int i = 0; i <= 7; i++) begin
				#(bit_period);
				tr.parity_error ^= mi.line;		
				tr.data[i] = mi.line			//监测数据
			end
			#(bit_period) assert(mi.line == 1'b1) 		//检查协议
			else
				`uvm_warning("MON", "Framing error");
			...
		end
	endtask
endclass

四、uvm_sequencer类

1、概述

  • uvm_sequencer就如同一个管道,从这个管道中会产生连续的激励事务,并最终通过TLM端口送至driver一侧。sequencer既管理着sequence,同时也将sequence中产生的transaction item传送到一侧,可以说是整个激励环节中得“路由器”。
  • uvm_sequencer也可以从uvm_driver那里获取随后的RSP对象来得知数据通信是否正常。
  • uvm_sequencer类的定义来看,它也同uvm_driver一样是个参数类,需要在定义sequencer时声明REQ的类型。

在这里插入图片描述

2、示例

class my_sequencer extends uvm_sequencer#(basic_transaction)		//参数化为sequence item类型
	`uvm_component_utils(my_sequencer)
	function new(string name, uvm_component parent);				//在factory中注册my_sequencer
		super.new(name, parent);
	endfunction
endclass

五、uvm_agent类

1、概述

  • uvm_agent相当于一个标准的验证环境“单位”,这样的一个标准单位通常包含一个driver、一个monitor以及一个sequencer。这三个组件通常组合在一起形成一个agent“团体”。
  • 为了复用,有的时候uvm_agent中只需要包含一个monitor,而不需要driversequencer,这就需要通过一个变量来进行有条件的例化uvm_active_passive_enum is_active = UVM_ACTIVEis_activeagent的一个成员,缺省值是UVM_ACTIVE,这表示在active模式的agent需要例化drivermonitorsequencer,而如果is_active的值是UVM_PASSIVE,这就表示agentpassive模式,只可以例化monitoractive模式的agent既有激励功能也有监测功能,passive模式的agent只有监测功能。
  • active模式对应着DUT的接口暴露给agent且需要激励的场景,而passive模式对应着DUT的接口已经与其它设计连接而只需要监测的场景。
  • 通过is_active变量,agent需要在build_phase()connect_phase()等函数中通过选择语句来对driversequencer进行有条件的例化和连接。

在这里插入图片描述
agent在存在是为了验证环境的复用。按照总线的传输方向划分,可以分为masterslaveMaster agent是用来向DUT发起transaction,而Slave agent是用来响应DUT的events

2、示例

class my_agent extends uvm_agent;
	my_sequencer m_sqr;			//agent中所包含的常见组件
	my_driver 	 m_drv;
	my_monitor   m_mon;
	dut_if vif;
	uvm_active_passive_enum is_active = UVM_ACTIVE;		//决定agent内部结构的变量is_active
	...
	extern function void build_phase(uvm_phase phase);
	extern function void connect_phase(uvm_phase phase);
	`uvm_component_utils(my_agent)
endclass
function void template_master_agent::build();
	super.build();
	monitor = template_master_monitor::type_id::create("monitor", this);
	if(is_active == UVM_ACTIVE) begin
		sequencer = template_master_sequencer::type_id::create("sequencer", this);
		driver = template_master_driver::type_id::create("driver", this);
	end
endfunction

function void template_master_agent::connect();
	if(is_active == UVM_ACTIVE) begin
		driver.seq_item_port.connect(sequencer.seq_item_export);
	end	
endfunction

六、uvm_scoreboard类

1、概述

  • uvm_soreboard担任着同SV中checker一样的功能,即进行数据比对和报告。
  • uvm_scoreboard本身也没有添加额外的成员变量和方法,但建议将自定义的scoreboard类继承于uvm_scoreboard类,这便于子类在日后可以自动继承于可能被扩充到uvm_scoreboard类中的成员。
  • 在实际环境中,uvm_scoreboard会接收来自于多个monitor的检测数据,继而进行比对和报告。

由于uvm_scoreboard通用的比较数据特性,UVM自带的其它两个用来做数据比较的类其实很少被使用到

uvm_in_order_comparator#(type T)
uvm_algorithm_comparator#(type BEFORE, type AFTER, type TRANSFORMER)

uvm_in_order_comparator是一个参数类,并且它有两个端口befor_exportafter_export分别从DUT的输入端monitor和输出端monitor获取观测到的数据事务。这些数据事务是将多个时钟周期内的数据整合为更高抽象级的数据对象,而且要求前后端检测到的数据事务类型应该相同。

uvm_algorithm_comparator也是一个参数类,它的参数数目要更多,这是为了贴合在更多实际场景中,DUT的输入端检测数据格式不同于输出端数据格式,因此type BEFOREtype AFTER两个事务类可以不相同,也应该提供用来将BEFORE类转换为AFTER类的转换类type TRANSFORMER

2、示例

scoreboard中通常会声明TLM端口以供monitor传输数据,对于简单比较的方法,可以采用UVM预定义的comparator,但是对于复杂的设计,可以在scoreboard中分别创建reference modelcomparator

class cpu_scoreboard extends uvm_scoreboard;
	uvm_analysis_export#(bus.xact) in_export;
	uvm_analysis_export#(bus.xact) out_export;
	typedef uvm_in_order_comparator#(bus.xact) comp_t;
	comp_t m_comp;
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		in_export = new("in_export", this);
		out_export = new("out_export", this);
		m_comp = comp_t::type_id::create("m_comp", this);
	endfunction
	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		in_export.connect(m_comp.before_export);
		out_export.connect(m_comp.after_export);
	endfunction
endclass	

在这里插入图片描述

七、uvm_env类

1、概述

从环境层次结构而言,uvm_env可能包含多个uvm_agent和其他component,这些不同组件共同构成一个完整的验证环境,而这个环境在将来复用中可以作为子环境被进一步集成到更高的环境中。uvm_env就是一个结构化的容器,它可以容纳其它组件同时也可以作为子环境在更高层的集成中被嵌入。

在这里插入图片描述

2、示例

class top_env extends uvm_env;
	sub_env m_se;
	my_agent m_agt;
	my_scoreboard m_sb;
	`uvm_component_utils(top_env)
	extern function new(string name, uvm_component parent);
	function void build_phase(uvm_phase);
		m_se = sub_env::type_id::create("m_se", this);
		m_agt = my_agent::type_id::create("m_agt", this);
		m_sb = my_scoreboard::type_id::create("m_sb", this);
	endfunction
endclass

八、uvm_test类

1、概述

  • uvm_test类本身没有什么新成员,但是作为测试用例的“代言人”,它不但决定着环境的结构和连接关系,也决定着使用哪一个测试序列。
  • 如果没有uvm_test,整个环境都无从建立,所以uvm_test是验证环境建立的唯一入口,只有通过它才能正常运转UVM的phase机制。

2、示例

在一个顶层test中可以例化多个组件,譬如uvm_env或者uvm_agent,而在仿真时通过uvm_test可以实现验证环境的运转。最好在uvm_test中只例化一个顶层uvm_env,这便于提供一个唯一环境节点以形成树状的拓扑结构,而这种树状环境结构也会对应着一种树状配置结构。

class env extends uvm_env;
	`uvm_component_utils(env)
	...
endclass

class agent extends uvm_agent;
	`uvm_component_utils(agent)
	...
endclass

class test1 extends uvm_test;
	`uvm_component_utils(test1)
	env e1, e2;
	agent a1;
	...
	function void build_phase(uvm_phase phase);
		e1 = env::type_id::create("e1", this);
		e2 = env::type_id::create("e2", this);
		a1 = agent::type_id::create("a1", this);
	endfunction
endclass

在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值