SV Random手册笔记

一、关于“随机验证”的思考

验证挑战

如今芯片规模很大,验证量很大,对应的工作量就很大,大到不可能完全覆盖所有场景。因此,对验证方法提出了更高要求:

    1)量大的事情,就要想办法让机器自动执行

    2)机器都不能完全覆盖的场景,就要划分颗粒度、优先级

抽象

    办法很容易想到,且这种思想我们在直接测试中也可能已经用到——抽象、或模板化:先编写向量模板,该模板提供一些可以修改的参量,如包长、地址、数据(UVM方法学其实就是一个巨大的模板,不只是测试向量的模板,而且是整个测试环境的模板)

随机

1)随机的原因

    经过抽象后,我们可以反复调用模板向量来快速得到由任意参量控制产生的具体向量。但依然剩下一个十分繁重的工作:如何按照我们希望的颗粒度来穷举参量,从而穷举向量。咋一看,这个工作很简单,穷举这些参量,就等于穷举多维空间上的整数点,和数数是一个原理。但是,数数大家都会,但要从1数到10000,且不数错一个数字,是几乎不可能办到的。因为人对这种机械的事情很容易厌倦,效率会越来越低,更严重的是,越来越容易出错。自然而然,我们需要让机器自动遍历参量空间

    那如何自动遍历参量空间呢?和我们数多维空间整数点的原理一样,我们往往按照从左到右、从上到下、从前到后的顺序,一个不落地数完整个空间。但是,将这种方法用于遍历参量空间是行不通的。原因如下:

    1)因为参量空间的维数很多,如果一维一维地数,那最后一维地空间要很晚才能数到,如果BUG发生在最后一维,那我们将很晚才能发现BUG。BUG的分布是未知的,未知就等于随机(和中彩票是一个道理)。BUG是随机的,那遍历向量空间的顺序也应该是随机的(只有这样,才能保证维维平等)。

    2)选择随机的另一个重要原因是,芯片实际工作时的向量,通常不是按序的,而是随机的——随机更符合实际

    3)另外按序遍历向量空间,本身就遗漏了向量空间,因为“顺序”本身是构成向量空间的又一维。真正遍历向量空间,必须遍历向量顺序。所以,我们要随机。虽然随机也不可能遍历所有顺序,但总比“按序排列向量”覆盖率高很多。

   4)即使随机变量是相互独立的(不需要相互组合),随机也能大大提高验证效率。如两个变量a、b,各有100种情况需要覆盖,假如直接构造case,方法有 (1)分别设置100个case,共200个case   (2)或者进一步,将200个case合并成2个case,一个case遍历a,一个case遍历b   (3)或者再进一步,将两个case合并成一个case,同时遍历a、b。第三种方法更节省仿真时间,需要验证工程师人工去组合a、b。随机验证的又一个好处,与方法3相对于方法1的好处是一样的,可以并行覆盖独立变量,减少仿真时间。

2)随机的要求

   1)随机要有约束(没有绝对的随机,因为验证要有颗粒度、优先级)

   2)随机要有效率(好像是句废话,任何事都要求效率,但这句话实在太好听,就放这吧)

 

3)随机的方法

   根据上述要求,产生随机数的过程肯定是:先有约束,然后再根据约束产生随机数。约束,是SystemVerilog相比于Verilog新增加的语法。其实,用Verilog的也能实现约束(原理很简单):产生随机数 --> 检查约束 --> 约束不满足则重新产生随机数、约束满足则使用该随机数。这会大大增加验证工程师的coding工作量。有没有更好的办法呢?答案很容易想到,我们必须将这种原理清晰、工作量巨大、容易出错的事,交给机器自动完成。我们要做的只是交代清楚约束要求,为此,我们需要一种语法来连接工程师和机器。SV的constraint random value generation相关语法因此诞生。

 

知道了为什么要学习SV constraint random value generation,那就赶紧开始吧。学习SV手册中相关章节,笔记如下:

二、SV Random手册笔记

1、Random概述

2、Random Varialbe

3、Constraint Block

4、Randomization methods

5、Randomization Control

6、System Functions and Methods

7、Random Stability 简略

8、randcase

9、randsequence  略

 

1、Random概述

  Random验证效率更高,一般用在面向对象的数据抽象结构中(如class):

      1)在class中定义random variables、

      2)在class中定义constraint (约束是双向的,包括 ->)

      3)调用object.randomize(); (调用时可加约束with {constraint})

      4)约束可以被disable,obj_name.constr_name.constraint_mode(0)

      5)变量可以被进制随机,obj_name.variable_name.rand_mode(0)

      6)可在random前后进行一些操作,override the methods in class:

         pre_randomize() post_randomize()

2、Random Varialbe

rand

标准随机

randc

遍历随机 random cyclic

Permutation sequence is computed on every call of new() function. So if randc variables won't behave like random cyclic, if new() is called for every randomization. In the following example variable Var is not behaving like random cyclic.

http://testbench.in/CR_05_RANDOM_VARIABLES.html

 

randc variables cannot be specified in ordering constraints (see solve...before in 18.5.10).

3、Constraint Block

   constraint block是类的成员,可继承。

extern

Constraint blocks can be declared outside their enclosing class declaration

extern constraint proto2;

class C;
rand int x;

constraint proto1; // implicit form
extern constraint proto2; // explicit form
endclass

 

constraint C::proto1 { x inside {-4, 5, 7}; }
constraint C::proto2 { x >= 0; }

pure

An abstract class (i.e., a class declared using the syntax virtual class, as described in 8.21) may contain pure constraints.

virtual class D;
pure constraint Test;
endclass

inside

 

constraint c1 {x inside {3, 5, [9:15], [24:32], [y:2*y], z};}

 

integer fives[4] = '{ 5, 10, 15, 20 };
rand integer v;
constraint c3 { v inside {fives}; }

dist

:=

:/

dist expressions cannot appear in other expressions

 

A dist operation shall not be applied to randc variables.

x dist {100 := 1, 200 := 2, 300 := 5}

 

x dist { [100:102] := 1, 200 := 2, 300 := 5}

weighted:1-1-1-2-5

 

x dist { [100:102] :/ 1, 200 := 2, 300 := 5}
weighted:1/3-1/3-1/3-2-5

unique

All members of the group of variables so specified shall be of equivalent type.

 

No randc variable shall appear in the group.

rand byte a[5];
rand byte b;
rand byte excluded;
constraint u { unique {b, a[2:3], excluded}; }
constraint exclusion { excluded == 5; }

–>

if the expression
is true, then random numbers generated are constrained by the constraint (or constraint set).

 

Otherwise, the
random numbers generated are unconstrained.

a -> b is (!a || b)

 

bit [3:0] a, b;
constraint c { (a == 0) -> (b == 1); }

the probability a == 0 is thus 1/(256-15) or 1/241.

if else

Just like implication, if–else style constraints are bidirectional.

 

In the preceding declaration, the value of
mode constrains the value of len, and the value of len constrains the value of mode.

if (mode == little)
len < 10;
else if (mode == big)
len > 100;

 

which is equivalent to
mode == little -> len < 10 ;
mode == big -> len > 100 ;

 

foreach

The foreach construct specifies iteration over the elements of an array.

constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }

constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }

 

foreach( A [ i, j, k ] ) ...
foreach( B [ q, r, , s ] ) ...

array.sum

 

Array reduction iterative constraints

class C;
rand bit [7:0] A[] ;
constraint c1 { A.size == 5; }
constraint c2 { A.sum() with (int'(item)) < 1000; }
endclass
The constraint c2 will be interpreted as
( int'(A[0])+int'(A[1])+int'(A[2])+int'(A[3])+int'(A[4]) ) < 1000

Global constraints

Constraint expressions involving random variables from other objects are called global constraints

 

The following rules determine which objects, variables, and constraints are to be randomized:

 

a) First, determine the set of objects that are to be randomized as a whole.

 

b) Second, select all of the active constraints from the set of active random objects.

 

c) Third, select all of the active random variables from the set of active random objects. These are the variables that are to be randomized. All other variable references are treated as state variables, whose current value is used as a constant.

class A; // leaf node
rand bit [7:0] v;
endclass


class B extends A; // heap node
rand A left;
rand A right;
constraint heapcond {left.v <= v; right.v > v;}
endclass

solve  before

normal ordering:

All legal value combinations are equally probable, which
allows randomization to better explore the whole design space.

 

The constraint c says “s implies d equals zero.” Although this reads as if s determines d, in fact s and d are determined together.

 

sovle before:

Variable ordering can be used to force selected corner cases to occur more frequently than they would otherwise.

 

The constraints provide a mechanism for ordering variables so that s can be chosen independently of d

 

randc variables are not allowed. randc variables are always solved before any other

class B;
rand bit s;
rand bit [31:0] d;
constraint c { s -> d == 0; }
endclass

s

d

Probability

1

'h00000000

1/(1 + 2^32)

0

'h00000000

1/(1 + 2^32)

0

'h00000001

1/(1 + 2^32)

0

'h00000002

1/(1 + 2^32)

0

...

 

0

'hfffffffe

1/(1 + 2^32)

0

'hffffffff

1/(1 + 2^32)

 

class B;
rand bit s;

rand bit [31:0] d;
constraint c { s -> d == 0; }
constraint order { solve s before d; }
endclass

s

d

Probability

1

'h00000000

1/2

0

'h00000000

1/2 × 1/2^32

0

'h00000001

1/2 × 1/2^32

0

'h00000002

1/2 × 1/2^32

0

...

 

0

'hfffffffe

1/2 × 1/2^32

0

'hffffffff

1/2 × 1/2^32

 

static

calls to constraint_mode() shall affect all instances of the specified constraint in all objects

static rand int a;

function

Some properties are unwieldy or impossible to express in a single expression. function could be used to constrain variables.

function int count_ones ( bit [9:0] w );
for( count_ones = 0; w != 0; w = w >> 1 )
count_ones += w & 1'b1;
endfunction

 

constraint C1 { length == count_ones( v ) ; }

guard

if && || !

 

Constraint guards are predicate expressions that function as guards against the creation of constraints and not as logical relations to be satisfied by the solver.

 

This enables users to write constraints that avoid errors due to nonexistent object handles or array indices out of bounds.

 

Every subexpression within a predicate expression is evaluated to yield one of the above four values:

FALSE TRUE ERROR RANDOM

class SList;
rand int n;
rand Slist next;
// constraint sort { n < next.n; }

constraint sort { if( next != null ) n < next.n; }
endclass

 

class C;
rand int x, y;
D a, b;
constraint c1 { (x < y || a.x > b.x || a.x == 5 ) -> x+y == 10; }
endclass

soft

The (normal) constraints described up to this point can be denoted as hard constraints because the solver must always satisfy them, or result in a solver failure.

 

In contrast, a constraint expression defined as soft designates a constraint that is to be satisfied unless contradicted by another constraint—either by a hard constraint or by a soft constraint with higher priority

 

Soft constraints only express a preference for one solution over another; they are discarded when they are contradicted by other more important constraints.

The following rules determine the priorities of soft constraints: 18.5.14.1

class Packet;
rand int length;
constraint deflt { soft length inside {32,1024}; }
endclass
Packet p = new();
p.randomize() with { length == 1512; }

 

 

disable soft

A disable soft constraint causes lower priority soft constraints to be discarded regardless of whether those constraints create a contradiction. This feature is very useful to extend the solution space beyond the default values specified by any preceding soft constraints.

class B;
rand int x;
constraint B1 { soft x == 5; }
constraint B2 { disable soft x; soft x dist {5, 8};}
endclass

 

4、Randomization methods

randomize()

The randomize() method returns 1 if it successfully

The randomize() method is built-in and cannot be overridden.

The randomize() method implements object random stability. An object can be seeded by calling its srandom() method (see 18.13.3).

pre_randomize()

post_randomize()

They are automatically called by randomize() before and after computing new random values.

The built-in methods pre_randomize() and post_randomize() are functions and cannot block.

5、Randomization Control

rand_mode()

The function form of rand_mode() only accepts singular variables; thus, if the specified variable is an unpacked array, a single element shall be selected via its index.

class Packet;
rand integer source_value, dest_value;
... other declarations
endclass


int ret;
Packet packet_a = new;
// Turn off all variables in object
packet_a.rand_mode(0);


// ... other code
// Enable source_value
packet_a.source_value.rand_mode(1);


ret = packet_a.dest_value.rand_mode();

constraint_mode()

The constraint_mode() method can be used to control whether a constraint is active or inactive. When a constraint is inactive, it is not considered by the randomize() method.

class Packet;
rand integer source_value;
constraint filter1 { source_value > 2 * m; }
endclass
function integer toggle_rand( Packet p );
if ( p.filter1.constraint_mode() )
p.filter1.constraint_mode(0);
else
p.filter1.constraint_mode(1);
toggle_rand = p.randomize();
endfunction

randomize() with

local:: Scope

The randomize() with construct can be used anywhere an expression can appear.

 

The randomize() with constraint block can reference both class properties and variables local to the method call.

 

Unqualified names in an unrestricted in-lined constraint block are then resolved by searching first in the scope of the randomize() with object class followed by a search of the scope containing the method call—the local scope

 

class SimpleSum;
rand bit [7:0] x, y, z;
constraint c {z == x + y;}
endclass
task InlineConstraintDemo(SimpleSum p);
int success;
success = p.randomize() with {x < y;};
endtask

 

class C;
rand integer x;
endclass
function int F(C obj, integer x);
F = obj.randomize() with { x < local::x; };
endfunction

 

randomize(x,y)

Calling randomize() with arguments allows changing the random mode
of any class property, even those not declared as rand or randc.

class CA;
rand byte x, y;
byte v, w;
constraint c1 { x < v && y > w );
endclass
CA a = new;

a.randomize();
a.randomize( x );
a.randomize( v, w );
a.randomize( w, x );

randomize(null)

This causes the randomize method to behave as a checker instead of a generator. A checker evaluates all constraints and simply returns 1 if all
constraints are satisfied and 0 otherwise.

success = a.randomize( null );

std::randomize() with

The ease with which classes and their associated random variables and constraints can be manipulated makes classes an ideal vehicle for describing and manipulating random data and constraints.

 

However, some less-demanding problems that do not require the full flexibility of classes can use a simpler mechanism to randomize data that do not belong to a class. The scope randomize function, std::randomize(), enables users to randomize data in the current scope without the need to define a class or instantiate a class object.

module stim;
bit [15:0] addr;
bit [31:0] data;
function bit gen_stim();
bit success, rd_wr;

success = randomize( addr, data, rd_wr ); return rd_wr ; 

endfunction
...
endmodule

 

 

task stimulus( int length );
int a, b, c, success;
success = std::randomize( a, b, c ) with { a < b ; a + b < length ; };
...
success = std::randomize( a, b ) with { b - a > length ; };
...
endtask

 

6、System Functions and Methods

$urandom

generating 32-bit pseudo-random numbers

addr[32:1] = $urandom( 254 );

// get 32-bit random number

 

addr = {$urandom, $urandom };

// 64-bit random number

 

number = $urandom & 15;

// 4-bit random number

$urandom_range()

returns an unsigned integer within a specified range.

val = $urandom_range(7,0);

val = $urandom_range(0,7);

srandom()

manually seeding the RNG of objects or threads

 

Calling srandom() in an object’s new() function assures the object’s RNG is set with the new seed before any class member values are randomized

class Packet;
rand bit[15:0] header;

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

get_randstate()

 

 

set_randstate()

 

 

 

7、Random Stability

Random stability applies to the following:
— The system randomization calls, $urandom() and $urandom_range()
— The object and process random seeding method, srandom()
— The object randomization method, randomize()

 

Random stability encompasses the following properties:

— Initialization RNG.

— Thread stability.

— Object stability.

— Manual seeding.

8、randcase

randcase

randomly selects one of its branches.

 

The randcase weights can be arbitrary expressions, not just constants.

randcase
3 : x = 1;
1 : x = 2;
4 : x = 3;
endcase

 

The sum of all weights is 8; therefore, the probability of taking the first branch is 0.375, the probability of taking the second is 0.125, and the probability of taking the third is 0.5

 

byte a, b;
randcase
a + b : x = 1;
a - b : x = 2;
a ^ ~b : x = 3;
12'b800 : x = 4;
endcase

9、randsequence  略

 

发布了20 篇原创文章 · 获赞 4 · 访问量 3092

猜你喜欢

转载自blog.csdn.net/niceshotgoodball/article/details/104046173