SystemVerilog Verification Test Platform Writing Guide Chapter VIII OOP Object Oriented Programming Advanced Skills Guide

8.1 Inheritance
Create a complex class for bus transactions that can inject errors and has a variable delay.
Method 1: Use composition, that is, instantiate another type of class in the class. Sometimes it is difficult to separate functions into separate parts. If you use composition, you need to create different classes for correct and wrong transactions, and the test platform for the right class needs to be rewritten to handle the wrong class of objects.
Method 2: Use extension classes. When you need to add transactions, the fewer modifications to the existing test code, the better, for example, adding error injection.
The difference between extension class and class synthesis:
extension class solves and adds new transactions; when using class synthesis, it is troublesome to modify the code a lot.
How to use: The
extension class shares the variables and subroutines of the base class.
1) The methods in the basic class need to be marked as virtual so that they can be redefined in the extended class. When the function in the extension class is the same as the function name in the base class, the function in the base class is called by the super. Function name. System Verilog does not allow super.super.new to make multiple calls.
2) If the base class constructor new () has parameters, then the extension class must have a constructor and call the base class constructor on the first line of the constructor.
Example 8.3 Constructor with parameters in extended class

class Basel;
	int var;
	function new(input int var);//带有参数的构造函数
		this.var=var;
	endfunction
endclass

class Extended extends Basel;
	function new(input int var); //需要参数
		super.new(var);//必须是new构造函数的第一行
		//构造函数的其它行为
	endfunction
endclass

3) The OOP rule states that the handle of the base class can also point to the object of the extended class.

8.2 Blueprint (Blueprint) mode
1) Background: A simple generator that transfers data to the driver via a mailbox.
Example 8.5 The generator class
// The generator class using the Transaction object
// The first try ... only limited functionality

class Generator;
	mailbox gen2drv;
	Transaction tr;

	function new(input mailbox gen2drv);
		this.gen2drv=gen2drv;//this->类一级变量
	endfunction

	task run;
		forever begin
			tr=new();//创建事务
			assert(tr.randomize);//随机化
			gen2drv.put(tr);//送入驱动器
		end
	endtask

endclass

There is a problem: this example creates a transaction object inside the loop instead of outside the loop to avoid common test platform errors.
New () is placed outside the loop. The reason for the error is that the handle is placed in the mailbox, not the object. All handles point to the same object. (1) Task Run creates a thing and immediately randomizes it, which means that the transaction uses all the default constraints. To modify, you must modify the transaction class. (2) The extension cannot be used

Solution: Separate the creation and initialization of tr and use blueprint mode.

Another question: If you simply separate creation and initialization, and put them outside the loop, to avoid test platform errors (P200), how to solve them? How to solve the blueprint pattern

2) The concept of blueprint mode
first builds an object blueprint (metal mold), then modify its constraints, and even replace it with an extended object. When randomizing this blueprint, you get the random value you want to assign; then copy this object, copy Send to the downstream.
Blueprint: is a hook that allows you to change the behavior of the generator class without modifying its class code. Blueprint objects are constructed in one place (new ()) and used in another place (task run).
Example 8.6
Class Generator using blueprint mode ;
mailbox gen2drv;
Transaction blueprint;

	function new(input mailbox gen2drv);
		this.gen2drv=gen2drv;
		blueprint=new();
	endfunction

	task run;
		Transaction tr;
		forever begin
			assert(blueprint.randomize);//随机化
			tr=blueprint.copy();
			gen2drv.put(tr);//送入驱动器
		end
	endtask

endclass

3) Comparative analysis of P200 and P221: the important
blueprint mode, there is one more copy function than the new () generator in the loop field.
Question (1) Blueprint mode, new () outside the loop, there is only one object, and the mailbox can only be a handle, how to solve common platform errors?
Because copy is the copy of the object, not the copy of the handle. In this way, the blueprint mode has only one handle, but after randomization, copying is equivalent to creating many objects in recycling. The essence of common errors in the test platform is that only one object is created. This avoids problems.
Question (2) In the blueprint mode, because there is only one ID number, then in the task run loop, a lot of data was issued, and these only have an ID number?
Because copy is a copy of an object, the ID number will also increase in copy. Each data sent has its own ID number.
4)
In order to inject errors using the extended transaction , the blueprint object transaction needs to be changed to Badtransaction (change the blueprint). This operation must be completed between the creation and operation of the environment. Note: All badTr references are in this file, so there is no need to change the environment class or generator class.

Env.build ();
Begin
Badtr bad = new ();
Env.gen.blueprint = bad;
End
Env.run
aims to replace one object with another. After New (), they are all objects. Assign objects to objects. What is this way of writing? Not a copy? The essence of replication is to point a handle to an object.
Explanation: The above is a copy of the handle. Assign the extension class handle bad to the base class handle blueprint so that the base class handle points to the extension class object. When the following code is called, it directly points to the extension class bad and changes the blueprint.
The difference between Env.new () and nev.build ()
Env.new () only new () function
nev.build () is to each module new (), and conveys some parameters, through these parameters will connect each module of the environment, stand up.
8.3 Type downcasting and virtual methods

8.3.1 $ cast as type down conversion
background: the base class handle can point to the extended class object, no additional code is required; the extended class handle points to the base class object, it will usually go wrong, but sometimes it is possible, provided that the premise is The base class handle points to one of its extension class objects.
Function: When the handle of the extension class points to the base class object, use the $ cast () function. In the case of illegal, will not compile error, will return a 0.
$ castWhen used for tasks, systemverilog will check that the source object type and destination object type do not match at runtime, and will report an error
$castWhen used as a function, the type check is still performed. When there is no match, no error is reported and the function returns 0.
1) The base class handle points to the extended class object-Occurrence: Modify the blueprint without changing too much code, add functionality
Example 8.12 Copy an extended class handle into a base class handle

Transaction tr;   //基类句柄
BadTr bad;        //扩展类句柄
bad = new();     //构建BadTr 扩展对象
tr = bad;         //基类句柄指向扩展类对象
$display(tr.src);//显示基类对象的变量成员
tr.display;        //调用的是扩展类的方法

2) The extension class handle points to the base class object-occurrence: the base class virtual method copy function, the copy function in its inherited class
assigns the base class handle to the extension class handle, so that the extension class handle points to the base class object, general compiler It will make mistakes and cannot run, so be very careful;When only the base class handle points to the extended class object, when the extended class handle points to the base class object, no error occurs. In order to detect whether the base class handle points to an extension object and does not let the compiler report an error, you can use the $ cast () function to detect it.
What happens when you point an extension class handle to a base class object?
Example 8.13 Copy a base class handle to an extended class handle

 tr= new();            //创建一个基类 对象
 bad = tr;               //扩展类句柄指向基类句柄 ERROR:这一行不会被编译
 $display(bad.bad_crc);//基类对象不存在bad_crc成员

The above error will occur and the compilation will not be passed. Because some attributes do not exist in the base class; but it is not always illegal for the extension class handle to point to the base class handle (see the code below, it is possible),It is allowed when the base class handle points to an extended class object.
Example 8.14 using $ cast to copy the handle

Transcation tr; //基类句柄
BadTr bad,bad2; //扩展类句柄
Bad= new();//构建BadTr扩展对象
Tr = bad;   //基类句柄指向扩展类对象
 
//检查对象类型并拷贝。如果类型失配则在仿真时报错
//如果成功,bad2就指向tr所引用的对象
$cast(bad2,tr);      //扩展类句柄指向基类对象

//检查类型失配,如果类型失配,在仿真时也不会输出错误信息
if(!$cast(bad2,tr);
	$display(“cannot assign tr to bad2”);
$display(bad2.bad_crc);//原始对象中存在bad_crc成员

Handle type and object type difference (inaccurate translation in the book, type of handdle and object)
Personal understanding:
Transaction tr; Handle tr type is transaction
handle type: Keyword
Object type: Type difference of members in the class
8.3.2 Virtual method And polymorphism
Polymorphism: The phenomenon of multiple programs using a common name (polymorphism).
Polymorphic problem solving: a problem faced by computer construction. When the physical memory is small, the processor can address a large address space. In response to this problem, virtual memory was introduced.
The disadvantage of virtual method inheritance:
the virtual method is used in the base class, and the same "signature" must be used in the extension class. The virtual subroutine in the extension class cannot add or delete parameters, which means that it must be planned in advance.
8.5 Copy of object
1) Because it is a virtual function, the copy method in the extension class must also be transaction type, consistent with the base class. But the type to be copied is badtr, so a new
example of bad 8.20 base class of things with copy virtual function

Class transaction ;
	Rand bit[31:0] src,dst,data[8]; //变量
	Bit[31:0] crc;

	Virtual function transaction copy ();
		Copy   = new();
		Copy.src = s rc;
		Copy.dst = dst;
		Copy.data = data;
		Copy.crc  = crc;
	Endfunction
Endclass

Example 8.21 Extended transaction class with copy virtual function

Calss badtr extends transaction
	Rand bit bad_crc;
	Virtual function badtr copy(); //错误
	Virtual function transaction copy();
		Badtr bad;
		Bad = new();
		Bad.src = src; //复制数据域
		bad.dst = dst;
		bad.data = data;
		bad.crc = crc;
		Bad.bad_crc = bad_crc;
		Return bad;
	endfunction
endclass

2) First optimization route:Create an independent function copy_data, so that each class is only responsible for copying its local variables, that is, the copy function in the extended class uses super.copy_data (tr), instead of copying the variables in the base class. Code reuse is improved.
Example 8.23 ​​Extended transaction class using the copy_datd function
$ cast (bad, tr); // The extended class handle points to the base class handle, the base class handle type is converted to the case of the extended class use: Because of the virtual function, in the inheritance, the virtual function must The names and parameters in the base class are also consistent. In this way, the copy_data function parameter in the extension class is still a transaction type tr, so that the parameter is the base class handle, but the copy_data function is indeed a member of the extension class, and the base class handle parameter must be assigned to the extension class handle. The data of the extended class badtr type is returned, so you must use $ cast (bad, tr).
Optimization method two: the previous copy subroutine will create a new object, one way to improve isSpecify the storage address of the copy object.
Example 8.24 base class of transaction using copy function

class Transaction;
	Virtual function transaction copy(transaction to =null);
		if(to == null)
			copy = new(); //创建新对象
		else
			copy = to;//或者使用现有对象
		copy_data(copy);
endfunction

8.6 Abstract classes and pure virtual methods
Background: One of the goals of verification is to create code shared by multiple projects.
Purpose: systemverilog has two methods to create a shared base class: abstract class and pure virtual method
Virtual class (abstract class): can be extended but not directly instantiated.
Pure virtual function: A method prototype without an entity, equivalent to a declaration.
Classes extended from abstract classes can only be instantiated when all virtual methods have entities, and pure virtual methods can only be defined in abstract classes.
In the abstract class, pure virtual methods have no entities, and non-pure virtual methods are best not to write entities.
8.7 Callback
Background: The purpose of the test platform: to create a verification environment that can be used in all tests without any modification. The key to this is that the test platform uses hooks, (what are hooks?) Hooks, which inject new code without modifying the original class. Using the virtual method, you can also override the base class method in the extension class, but you need to repeat all the code of the original method, and its modifications will be propagated to all its extension classes.
Purpose: The callback is a hook to inject new code without modifying the original class.
Implementation: The callback task is created in the top layer and called in the lowest level, namely the drive. In this way, the driver does not need to know any information about the test, it only needs to use a common class that can be extended in the test.
1) Use callback to inject interference
A common use of callbacks is to inject interference, Such as introducing an error or delay. The following test platform uses callback objects to randomly discard data packets.
How does the extension class work? Inject errors in the extended callback class, how does it work in the driver?
The key is the role of the data queue. It is used in the driver. The data queue of the
callback base class is an abstract class. Error injection is added to the extended callback class, and the drive driver class is the data queue of the callback base class. In the environment, the extension class handle is let into the driver class, and the data queue of the base class is called back.
Example 8.13 Use callback for error injection test create error injection callback

begin
	Driver_cbs_drop dcd = new();//创建错误注入的回调任务
	env.drv.cbs.push_back(dcd); // Put into driver放入驱动器队列
end

What is the difference with the previous extension class?
In the previous code, to add code to the extension class, you need to make the base class handle point to the extension class handle.
Driver class:
How to interpret the following code The
callback can also send data to the scoreboard or collect function coverage.
Advantages: You may have thought of putting the scoreboard and the functional coverage data group in a transaction processor and connecting it to the test platform through the mailbox. This is a clumsy method for the following reasons: almost all test platform components are passive and asynchronous , The component is only awakened when the test platform gives him data, and will not actively pass information to the downstream transaction processor. Trouble: 1) Such a transaction processor that needs to monitor multiple mailboxes at the same time is complicated; 2) You may collect data in multiple places, but the transaction processor is designed to handle a single data source callback

Published 38 original articles · Like 29 · Visits 10,000+

Guess you like

Origin blog.csdn.net/weixin_45270982/article/details/95910838