08. UVM component family (must see the basics)

I. Overview

The verification components in the SV verification environment are called stimulators, monitors, and checkers according to their functional requirements. These three core components correspond to the three key characteristics of the verification environment, namely, excitation, monitoring, and inspection, and there are corresponding The component (component).

The UVM component family is a core branch inherited from the UVM base class , namely the uvm_component class. The classes inherited from the uvm_component class can constitute a verification environment, because they all inherit the phase mechanism from the uvm_component class, and they will all go through various phase stages.

In the UVM module, common component classes include: uvm_driver, uvm_monitor, uvm_sequencer, uvm_agent, uvm_scoreboard, uvm_env, uvm_test.

 parent represents the upper level of its component, and the relationship between hierarchical indexes is bidirectional. 

 2. uvm_driver class - first understand briefly, and learn in the fourth week

1 Overview

  • This class will obtain transactions from uvm_sequencer , convert them and then stimulate the timing of DUT in the interface . Any class that inherits from uvm_driver needs to pay attention to that this class is a parameterized class , so it is necessary to declare the type of the parameter when defining it.
  • Definition of uvm_driver class: When defining a new driver class, you should declare the transaction parameter REQ type that the class needs to obtain. By default, the RSP parameter type is consistent with the REQ type.
class uvm_driver#(type REQ=uvm_sequence_item, type RSP=REQ) extends uvm_component;

// # 代表参数类  参数类型REQ默认是uvm_sequence_item
// 此类型可以改变,要取决于获取的参数类型
// type RSP=REQ  : 默认的 RSP 和 REQ类型都是一样的,都是uvm_sequence_item
  • uvm_driveruvm_componentThere is no new function extended on the basis, but only some ports and variables used for communication are extended . (Understand first, learn carefully in the fourth week)
uvm_seq_item_pull_port#(REQ, RSP) seq_item_port; //这两个端口以后和sequencer做通信
uvm_analysis_port#(RSP) rsp_port;
REQ req;
RSP rsp;
  • The communication between the driver class and the sequencer class is to obtain a new transaction object, and this operation is realized by pull.
driver.seq_item_port.connect(sequencer.seq_item_export);
driver.rsp_port.connect(sequencer.rsp_export);

2. Examples

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

Three, uvm_monitor class

1 Overview

This class is for monitoring interface data, and any monitor that customizes data monitoring behavior should inherit from this class.
Although uvm_monitor does not add new members and methods compared with its parent class, inheriting the newly defined monitor class from the uvm_monitor class will help implement the methods and characteristics of the parent class uvm_monitor.
The functions usually performed by this class include:
1. Observing the interface of the DUT and collecting bus information.
2. Always keep the PASSIVE mode, that is, never drive the DUT. That is, only checks are made, and no incentives are made.
3. When observing the bus protocol or internal signal protocol, some function and timing checks can be done.
4. For more complex inspection requirements, they can send data to other verification components, such as scoreboard, reference model or coverage collector.

2. Examples

Remember the template: 1/2/3 steps and several main phases

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

Four, uvm_sequencer class

1 Overview

  • uvm_sequencer is like a pipeline , from which continuous incentive transactions will be passed , and finally sent to the driver side through the TLM port. The sequencer not only manages the sequence , but also transmits the transaction item generated in the sequence to one side , which can be said to be the " router " in the entire incentive link.
  • uvm_sequencer can also obtain subsequent RSP objects from uvm_driver to know whether the data communication is normal .
  • From the definition of the uvm_sequencer class , it is also a parameter class like uvm_driver , and the type of REQ needs to be declared when defining the sequencer.

For the transaction generated in the sequence, the sequencer is like a pipeline for transferring the transaction. They share the role of generator.

2. Examples

// 组件中最简单的
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

Five, uvm_agent class

1 Overview

  • uvm_agent is equivalent to a standard verification environment "unit". Such a standard unit usually includes a driver, a monitor and a sequencer . These three components are often grouped together to form an agent "corporation".
  • In order to reuse, sometimes only one monitor needs to be included in uvm_agent, instead of driver and sequencer, which requires conditional instantiation of uvm_active_passive_enum is_active = UVM_ACTIVE through a variable. is_active is a member of agent, the default value is UVM_ACTIVE , which means that the agent in active mode needs to instantiate driver, monitor and sequencer , and if the value of is_active is UVM_PASSIVE , it means that the agent is in passive mode , and only monitor can be instantiated . The agent in active mode has both incentive function and monitoring function, while the agent in passive mode only has monitoring function.
  • The active mode corresponds to the scenario where the interface of the DUT is exposed to the agent and needs to be stimulated, while the passive mode corresponds to the scenario where the interface of the DUT has been connected with other designs and only needs to be monitored.
  • Through the is_active variable, the agent needs to conditionally instantiate and connect the driver and sequencer through selection statements in functions such as build_phase() and connect_phase().
     

 agentIt exists to verify the reuse of the environment. According to the transmission direction of the bus, it can be divided into masterand slave, Master agentwhich are used to initiate to the DUT transaction, Slave agentbut are used to respond to the DUT events.

2. Examples

class my_agent extends uvm_agent; //  1
	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
	...                           //  3
	extern function void build_phase(uvm_phase phase);
	extern function void connect_phase(uvm_phase phase);
	`uvm_component_utils(my_agent)    //2
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

Six, uvm_scoreboard class

1 Overview

  • uvm_soreboard serves the same function as the checker in SV, that is, data comparison and reporting.
  • uvm_scoreboard itself does not add additional member variables and methods, but it is recommended to inherit the custom scoreboard class from the uvm_scoreboard class, which is convenient for subclasses to automatically inherit members that may be extended to the uvm_scoreboard class in the future.
  • In the actual environment, uvm_scoreboard will receive detection data from multiple monitors, and then compare and report.

Due to the general comparison data characteristics of uvm_scoreboard, the other two classes that come with UVM for data comparison are rarely used

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

uvm_in_order_comparator is a parameter class, and it has two ports before_export and after_export to obtain observed data transactions from the input monitor and output monitor of the DUT respectively. These data transactions integrate data within multiple clock cycles into higher-level data objects, and require that the types of data transactions detected by the front and back ends should be the same.

uvm_algorithm_comparator is also a parameter class. It has more parameters. This is to fit in more practical scenarios. The input detection data format of DUT is different from the output data format. Therefore, there are two transaction classes of type BEFORE and type AFTER It can be different, and the conversion class type TRANSFORMER used to convert the BEFORE class to the AFTER class should also be provided

2. Examples

scoreboardTLM ports are usually declared for data transfer in , monitorfor simple comparison methods, UVM predefined ones can be used comparator, but for complex designs, they can be scoreboardcreated separately in reference modeland comparator.

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	

Seven, uvm_env class

1 Overview

From the perspective of environment hierarchy, uvm_env may contain multiple uvm_agents and other components. These different components together form a complete verification environment, and this environment can be further integrated into a higher environment as a sub-environment in future reuse. uvm_env is a structured container that can accommodate other components and can also be embedded as a sub-environment in higher-level integration.

There is a one-to-one correspondence between the hierarchical relationship of the hardware module and the hierarchical relationship of the verification environment , which is a rule.

  2. Examples

class top_env extends uvm_env;  //1
	sub_env m_se;
	my_agent m_agt;
	my_scoreboard m_sb;
	`uvm_component_utils(top_env)   //2
	extern function new(string name, uvm_component parent);  //3
	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

Eight, uvm_test class

1 Overview

  • uvm_testThe class itself has no new members, but as the "spokesperson" of the test case, it not only determines the structure and connection relationship of the environment , but also determines which test sequence to use .
  • If not uvm_test, the entire environment cannot be established, so uvm_testit is the only entrance to verify the establishment of the environment, and only through it can the phase mechanism of UVM operate normally.

2. Examples

Multiple components can be instantiated in a top-level test, such as uvm_env or uvm_agent, and the operation of the verification environment can be realized through uvm_test during simulation.

It is best to instantiate only one top-level uvm_env in uvm_test , which is convenient to provide a unique environment node to form a tree-like topology, and this tree-like environment structure will also correspond to a tree-like configuration structure.

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;  //实际工作中在这里只有一个env,或者用top_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

Guess you like

Origin blog.csdn.net/Arvin_ing/article/details/127655101