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  略

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章