SystemVerilog Verification Test Platform Writing Guide Chapter 6 Randomization

6.1 Introduction
Reason: It is becoming more and more difficult to produce a complete stimulus set test design function, and it is impossible to write a sufficient directional test set; the relationship of the function items is the source of most errors, and the error is difficult to be eliminated by the list check method.
A constrained random test (CRT: constrained random test) is used to automatically generate a test set.
The CRT environment not only needs to generate stimulus, but also needs to predict the output result through the reference model, transfer function or other methods.
The CRT consists of two parts: using random data streams to generate the input test code for the DUT, and the seed of the pseudo-random number generator (PRNG).
6.2 What is needed for randomization
? All key points in the DUT must be randomized. Randomization allows each branch in the control path to be tested.
Consider various aspects of design input, such as:
(1) Device configuration;
In RTL-level design, enough configuration needs to be tested.
(2) Environment configuration;
usually the device you design works in an environment containing several devices. When verifying the DUT, it is connected to a test platform that simulates this environment. You should randomize the entire environment, including the number of objects and how they are configured.
(3) Original data input;
(4) Encapsulated input data;
(5) Protocol exceptions, errors, and violations;
anything that may go wrong will eventually go wrong. Good verification engineers will test the behavior of the design at the boundary of the design specification, and even test the behavior outside the design specification.
The test platform should be able to generate functionally correct stimuli, and then flip a certain configuration bit to generate random error types at random time intervals.
(6) Delay;
The test platform should use random and effective delays in each test in order to discover bugs in the design.
(7) Transaction status
6.3 Randomization in System Verilog
When used simultaneously with OOP, the generation of random excitation in System Verilog is the most effective. First create a class with a set of related random variables, then use random functions to assign random values ​​to these variables, and use constraints to limit the range of random values. Constrained random stimuli are generated at the transaction level and usually do not produce only one value at a time.
6.3.1 Simple class with random variables
Example 6.1 Simple random class

class packet;
	//随机变量
	rand bit [31:0] src, dst, data[8]; 
	randc bit [7:0] kind; 
	//src的约束
	constraint c {src > 10;
					src<15;} 
endclass

Packet p;
	initial begin
	p=new(); // 产生一个包
	assert (p.randomize());//断言,随机化成功,函数返回1
	else $fatal(0,“Packet::randomize failed”); //随机化失败,函数返回0,并显示错误信息
	transmit (p);
end

Ordinary random number rand Modifiers, these variables are assigned a value each time this class is randomized.
Cyclic random number randcModifier, periodic randomness, that is, random values ​​may be repeated only after all possible values ​​have been assigned.
A constraint is a set of relational expressions used to determine the range of variable values. The value of the expression is always true.Constraint expressions are placed in {…} brackets, Because this code is declarative, not procedural.
The randomize () function returns 0 when encountering constraints. The above example uses an assertion to check the result of the randomize function, and uses $ fatal to terminate the simulation. For different simulation tools, the corresponding options need to be used to enable the assertion to terminate the simulation process.

6.3.2 Check the result of
randomization The randomize () function assigns a random value to all random variables of type rand and randc in the class, and guarantees that all valid constraints are not violated. When there are contradictory constraints in the code, the randomization process will fail, so be sure to check the results of randomization. If it is not checked, the variable may be assigned an unknown value, causing the simulation to fail.
Example 6.1 uses assertions to check the result of randomize (). If the randomization is successful, the function returns 1. If it fails, the function returns 0, and an error message is displayed after the assertion detects an error. You must make some settings for the emulator, so that the emulator can automatically end the simulation when an error occurs.

6.3.3 Constraint Solving
Constraint expressions are solved by System Verilog's constraint solver. The solver can choose a value that satisfies the constraint. This value is generated by System Verilog's PRNG from an initial value (seed).

6.3.4 What can be randomized
System Verilog can randomize integer variables, that is, variables composed of bits. Although only 2-value data types can be randomized, the bits can also be 2-value or 4-value types. So you can use integers and bit vectors, but you cannot use random strings, or point handles when constrained.

6.4 Constraints You
need to use constraint blocks containing one or more constraint expressions to define the relationship between the excitation vectors. System Verilog will choose random values ​​that satisfy all expressions.
At least one variable in each expression must be a random variable of type rand or randc.

6.4.1 What is a constraint
Example 6.3 Constrained random class

class Stim;
	const bit [31:0] CONGEST_ADDR=42;
	typedef enum {READ, WRITE, CONTROL} Stim_e;
	randc stim_e kind; //枚举变量
	rand bit [31:0] len, src, dst;
	bit congestion_test;

	constraint c_stim { //约束块
		len<1000; //控制变量len的范围
		len>0; //变量可以在多个使用
		if (congestion_test) {
			dst inside {[CONGEST_ADDR-100: CONGEST_ADDR+100]};
			src==CONGEST_ADDR
		}
else 
	src inside {0, [2:10], [100:107]};
		}
endclass

6.4.2 Simple expression
The class in Example 6.3 has a constraint block that contains several expressions. The first two expressions control the range of the variable len. Variables can be used in multiple expressions.
At most one relational operator (<, <=, ==,> =,>) can be used in an expression.

6.4.3 Equivalent expressions
Constraint blocks can only contain expressions, so assignments cannot be made in constraint blocks. Instead, you should use a relational operator to assign a fixed value to a random variable, for example, len = = 42. You can also use more complex relationship expressions between multiple random variables, such as len == header.addr_mode * 4 + payload.size ().

6.4.4 Weight distribution The
dist operator allows weight distributions to be generated, so that some values ​​have a greater chance of being selected than others. The dist operator comes with a list of values ​​and corresponding weights,In the middle: = or: / separate. The value or weight can be a constant or a variable. The value can be a value or a range of values, for example [lo: hi]. The weights are not expressed as percentages, and the sum of the weights need not be 100.The: = operator indicates that the weight of each value in the range is the same, and the / operator indicates that the weight of the value is equally divided into each value in the value range.
Weight distribution cannot target randc variables
Example 6.7 Random distribution of weights using dist

rand int src,dst;
constraint c_dist {
	src dist {0:=40,[1:3]:=60};
	dst dist {0:/40, [1:3]:/60};
}

The probability of src taking 0 is 40/220, the probability of taking 1, 2, 3 is 60/220;
the probability of dst taking 0 is 40/100, and the probability of taking 1, 2, 3 is 20/100;
by changing The weight can change the probability distribution of the value at any time, and you can even set the weight to 0 to delete a value.

6.4.5 collection (set) inside members and operators
usinginside {}The operator produces a set of values. Unless there are other constraints on the variables, when System Verilog takes random values ​​in the set of values, the chances of selecting each value are equal. Variables can also be used in collections.
Example 6.9 Collection of random values

rand int c; //随机变量c
int lo, hi; //作为上限和下限的非随机变量
constraint c_range {
	c inside {[lo:hi]}; // lo < = c 并且 c < = hi
}

The value range of c in Example 6.9 is determined by lo and hi. With this method, the constraints can be parameterized so that the test platform can change the behavior of the excitation generator without modifying the constraints. If lo> hi, it will cause constraint error.
You can use $ to represent the maximum and minimum values ​​in the range.

Example 6.10 Use "$" to specify the maximum and minimum values

rand bit [6:0] b; //0 < = b < = 127
rand bit [5:0] e; // 0 < = e < = 63
constraint c_range {
	b inside {[$ : 4],[20 : $]}; //0 < = b < = 4 || 20 < = b < = 127
	e inside {[$ : 4],[20 : $]}; //0 < = e < = 4 || 20 < = e < = 63
}

If you want to select a value outside a set, just useInvert operator! Negate the constraint.
Example 6.11 Inverting a random set constraint

constraint c_range {
 !(c inside {[lo:hi]}) ;//c < lo 或 c > hi
}

6.4.6 Using arrays in collections
You can use these values ​​after saving the values ​​in the collection into an array.
Example 6.12. Random set constraints using arrays

rand int f;
int fib[5]='{1、2、3、5、8};
constraint c_fibonacci{
	f inside fib;
}

Example 6.13 Equivalent constraints

constraint c_fibonacci{
	(f = = fib[0]) || f = =1
	(f = = fib[1]) || f= =2
	(f = = fib[2]) || f= =3
	(f = = fib[3]) || f= =5
	(f = = fib[4]) || f= =8
}

The probability of each value in the set is the same, even if the value appears multiple times in the value.

6.4.7 Conditional constraints (to make a constraint expression only valid at certain times)
Usually all constraint expressions in the constraint block are valid, and operate through two relationships:- >和if-elseMake the expression effective at certain times.
Operator-> can produce a block of statements similar to the case operator, used to enumerate expressions.
Example 6.19. Constraint block with-> operator

class BusOp;
	...
	constraint c_io {
		(io_space_mode) - > 
		addr [31]= = 1'b1; 
}

Example:

mode==small -> len <10; //mode为small时 len约束为小于10;
mode==large -> len >100; //mode为large时 len约束为大于100;

The if-else operator is more suitable for "true-false" type expressions.
Example 6.20 Constraint block with if-else operator

 class BusOp;
    	...
    	constraint c_len-rw {
    		if (op== READ)
  	  		len inside {[BYTE:LWRD]};
    		else
    		len==LWRD;
   }

6.4.8 Bidirectional constraints
Constraint blocks are parallel declarative code, and all constraints are valid at the same time.
6.4.9 Use appropriate mathematical operations to improve efficiency
Any constant in System Verilog that does not show a declared bit width is treated as a 32-bit value, for example: 42.

6.5 Probability of Solution
System Verilog does not guarantee that the random constraint solver will give an accurate solution, but you can intervene in the probability distribution of the solution.

6.5.1 Classes without constraints
6.5.2 Relational operations The relational operations in the
constraint block determine the value.
6.5.3 Relational operations and bidirectional constraints
6.5.4 Use solve ... before constraints to guide the probability distribution
solve ... before constraints do not change the number of solutions, only the probability of each value.
At the same time, solve x before y is different from solve y before x, which is quite different.
Unless you are not satisfied with the probability of certain values, do not use solve ... before. Excessive use of solve ... before will slow down the calculation speed and make the constraints difficult to understand.
You can only use rand, not randc random variables; the
variables must be integer types;

6.6 Controlling multiple constraint blocks
A class can contain multiple constraint blocks.
During operation, use the built-in constraint_mode () function to turn constraints on or off.constraint_mode (1) is the opening constraint, and constraint_mode (0) is the closing constraint.
Use handle.constraint.constraint_mode () to control a constraint block, and handle.constraint_mode () to control all constraint blocks of an object.
Example 6.28 Using the constraint_mode () function

class Packet;
	rand int length;
	constraint c_short {length inside {[1:32]};}
	constraint c_long {length inside {[1000:1023]};}
endclass

Packet p;
initial begin
	p=new();
	//通过禁止c_short约束产生长包
	p.c_short.constraint_mode(0);
	assert (p.randomize());
	transmit (p);
	//通过禁止所有的约束,然后使能短包约束来产生短包
	//then enabling only the short constraint
	p.constraint_mode(0);
	p.c_short.constraint_mode(1);
	assert (p.randomize());
	transmit (p);
end

6.7 Validity Constraints
Setting multiple constraints to ensure the correctness of random excitation is a good randomization technique, also known as "validity constraints".
6.8 Inline constraints
Many codes only randomize objects in one place.SystemVerilog allows the use of randomize () with {} to add additional constraints, which is equivalent to adding constraints in the class.
Constraint blocks should use {}, inline constraints should also use {}, {} for declarative code.
6.9 pre_randomize and post_randomize functions
SystemVerilog can use two special void type pre_randomize and post_randomize functions to complete some operations before and after calling randomize (). The void type function has no return value. Since the function is not a task, it does not consume time.
6.10 Randomization function
(1) $ random ()-average distribution, returns 32-bit signed random number;
(2) $ urandom ()
-average distribution, returns 32-bit unsigned random number; (3) $ urandom_range ( )
—Average distribution within a specified range; (4) $ dist_exponential () — exponential decline;
(5) $ dist_normal () —bell distribution;
(6) $ dist_poisson () — bell distribution;
( 7) $ dist_uniform ()-average distribution;
$ urandom_range () function has two parameters, an upper limit parameter and an optional lower limit parameter.
Example setting random seed
class Packet;
rand bit [15: 0] header;

function new (int seed);
this .srandom (seed);
endfunction

endclass
// Create a class, initialize seed
Packet p = new (200); // Creat p with seed 200
p.srandom (300); // Re-seed p with seed 300

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

Guess you like

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