Вы находитесь на странице: 1из 28

The Top Most Common

SystemVerilog Constrained
Random Gotchas
Author: Ahmed Yehia
Presenter: Gabriel Chidolue

© Accellera Systems Initiative 1


Motivation
• More time is
taken in debug Test Planning
than any other 36%
4%
project task Testbench
Development
16% Creating and
• Time wasted in 23% Running Test
debugging 22% Debug
constrained
random related
problems is Wilson Research Group and Mentor Graphics, 2012 Functional Verification Study, Used with permission

significant

© Accellera Systems Initiative 2


Contribution
• Illustrates top most common SystemVerilog
and UVM constrained random gotchas
• Helps
– Eliminate/reduce unnecessary debug times when
encountering randomization failures
– Eliminate/reduce unexpected randomization
results
– Eliminate/reduce code random instability
– Ensure efficiency when coding random constraints

© Accellera Systems Initiative 3


Outline

• Introduction to Constrained Random Verification


• Randomization Failures Gotchas
• Randomization Results Gotchas
• Randomization Runtime Performance Gotchas

© Accellera Systems Initiative 4


Constrained Random Verification
Checker
Does it work?
• Defines stimulus at high level
How efficient is
of abstraction (random space) my constrained
random stimuli?
– Random variables and their
range
0101010101
1010101010
– System Constraints 1101101101
Device 000001000
1011011010
111011101
• More efficient than directed 0111011101
1101101110
Under
Verification
1101101101
1011011011
0101101101
tests 1101101101
0001001001
001001011
– Usually complemented by Functional
Coverage
directed tests to close coverage Are we done?
Constraints
• Requires a measurement Header Payload Checksum

strategy to assess the Manipulate


random space
verification progress
– Metric Driven Verification
Introduction to SystemVerilog
Constrained Random
Random Variables
F x
U Constraints Solver
A x
x x xx xx
H x x xx x
Q xx x
Y x x x x x xx
Z x
G x x x
M x x
x xx x x x
xxx

Random Solution
Constraints RNG
Failure
© Accellera Systems Initiative 6
Introduction to SystemVerilog
Constrained Random
SystemVerilog Randomization SystemVerilog Randomization
Methods Constraints
• randomize() • Expressions need to be held true by the Solver
– Built-in class method when solving a randomization problem
– Randomizes class fields with rand/randc qualifiers
according to predefined constraints • May include random variables, non-random state
– Accepts inline constraints using the “with” clause variables, operators, distributions, literals, and
– can be called to recursively randomize all random constants
variables of a class, or to randomize specific
variable(s) • Can be hard (default) or soft
• $urandom() • Can be switched on/off using constraint_mode()
– Called in a procedural context to generate a
pseudo-random number • special operators
• $urandom_range() – inside (set membership),
– Returns an unsigned random integer value within a – -> (implication),
specified range
– dist (distribution/weighting),
• std::randomize()
– foreach (iteration),
– Can be called outside the class scope to randomize
non-class members. – if..else (conditional),
– Can accept inline constraints using the “with” – and solve..before (probability and distribution)
clause.
– unique,…

© Accellera Systems Initiative 7


Constraints Solver
How it works ?(obj.randomize())
Start
Orders randsets
(randc randsets, followed by
pre_randomize() (top->down) rand args to functions, followed
by other randsets) Updates all rand variables with
Solves random variables with random generated values
simple equality constraints No
Remaining
randsets? Generate random values for
Executes Simple functions unconstrained rand variables
Yes
called in constraints (with no
args, const/non-rand args) Solve Next randset (Take as post_randomize() (top->down)
many iterations as required)
Updates constraints with
values generated in #2 & 3 Flags Randomization Success
Yes Randset (randomize() returns 1)
solved?
Groups rand vars and
No
constraints into independent
randsets Flags Randomization Failure
End
(randomize() returns 0)

8
Outline
• Introduction to Constrained Random
Verification
• Randomization Failures Gotchas
• Randomization Results Gotchas
• Runtime Performance Gotchas

© Accellera Systems Initiative 9


My randomization attempt failed and I was not
notified !
What
class instr_burst;  happens
rand bit [15:0] addr, start_addr, end_addr; when result
rand bit [3:0] len;
constraint addr_range {addr >= start_addr; addr <= end_addr – len;}
of
endclass randomize()
instr_burst i1 = new; is NOT
i1.randomize() with {start_addr != 0; end_addr == 16'h0008; len == 4'h8;};
captured?

if (! i1.randomize())

$error ("Randomization of object c1 failed!");
Always capture randomize() result to
avoid implicit void casting
!
assert(i1.randomize());

© Accellera Systems Initiative 10


I am only randomizing a single variable in a class,
yet I am encountering a randomization failure!
class trans; 
rand bit [7:0] a, b, c ;
constraint constr { b < a; }
All constraints
endclass still need to be
initial begin
trans t1 = new;
satisfied!
assert (t1.randomize (b)); //Randomization failure!
end

trans t1 = new;

• Always issue at least one full randomize() before
assert (t1.randomize);
selected variables randomize()
!
assert (t1.randomize (b));

• Avoid (as possible) assigning other rand variables


manually without solver jurisdiction

© Accellera Systems Initiative 11


I am encountering cyclic dependency errors
between random variables!
class instr;
 
class instr;
rand bit [7:0] a, b, c ; rand bit [7:0] a ;
constraint prob{solve a before b; constraint c { a[0] == foo (a) ;}
solve b before c; endclass
solve c before a;}
endclass
What is the probability 8-bits of “a” are solved first
of randomization before solver attempt to
success? satisfy the equality!

• Random variables passed as function arguments are function void post_randomize();



a[0] = foo (a);
forced to be solved first by the Solver ! endfunction
• Solver does not look into functions contents

© Accellera Systems Initiative 1212


I am encountering cyclic dependency errors
between randc variables!
 Are “a” and “b” evaluated
class instr;
randc bit [7:0] a ;
together or separately?
randc bit [3:0] b ; If evaluated separately, what is
constraint c { a == b; } the order of evaluation?
endclass
instr i = new;
assert(i.randomize());

• randc cycles operate on single variables


 • randc variables are evaluated separately !
constraint c { a[3:0] == b; }

• Beware equality between unmatched size randc


variables
• Because of this, cyclic nature of randc variables
What if “b” can even be compromised!
was rand?

© Accellera Systems Initiative 13


I am getting randomization failures when using
array.sum()/array.product() reduction methods in
constraints!
class trans;

rand bit descr [];
constraint c {
descr.sum() == 50; What is the width/precision of sum() result?
descr.size() == 100;
}
endclass

• sum()/product() results are computed with


 a width/precision of array base type
constraint c {
descr.sum() with (int'(item)) == 50; !
descr.size() == 100; • Explicitly cast the array element
} (i.e. item) to an int data type when
needed

© Accellera Systems Initiative 14


Guidelines Summary
Randomization Failures Gotchas

© Accellera Systems Initiative 15


Outline
• Introduction to Constrained Random
Verification
• Randomization Failures Gotchas
• Randomization Results Gotchas
• Randomization Runtime Performance Gotchas

© Accellera Systems Initiative 16


Random values generated change from run to run; I
could not reproduce a test failure or validate a fix!
virtual task body;

random_seq rand_s = new; //Line A
Does line “A” affect the random stability of line “B”?
simple_seq rw_s = new;
fork begin
assert (rw_s.randomize()); //Line B • Randomize() results depends on previous state of
rw_s.start(); RNG
end
...
• Object initial RNG depends on parent’s RNG,
join while it changes state after each randomize()
endtask

• Use Manual seeding to manually set


 the RNG of a given thread or an
object to a specific known state
static int global_seed = $urandom; //Static global seed
... • In UVM, components are re-seeded
fork begin during their construction based on
rw_s.srandom(global_seed + "rw_s"); //Reseed sequence their type and full path names, while
assert (rw_s.randomize()); sequences are re-seeded
rw_s.start(); automatically before their actual
end
start.
!

© Accellera Systems Initiative 17


My inline constraints are not applied
class trans;

rand bit [31:0] addr;
What is the randomization result w.r.t.
endclass the constraint intent?
class seq;
rand bit [31:0] addr;
trans t;
assert(t.randomize() with {t.addr == addr;}); Equivalent Constraint
endclass assert(t.randomize() with {t.addr == t.addr;});

• Unqualified names are resolved by


searching first in the scope of
 the randomize() with object,
assert(t.randomize() with { addr == local::addr; });
followed by a search in the local
scope. !

Will ‘this’ • The local:: qualifier modifies the


resolution search order.
work?

© Accellera Systems Initiative 18


My foreign language random generation is not
affected by the initial simulation seed change

• Normally, the initial SystemVerilog simulation seed, does not affect foreign language code !
• This can be resolved by passing the simulation initial seed to the foreign language code

// C/C++ side  // SystemVerilog side 


static int sim_seed; import "DPI-C" context function void
void set_foreign seed(int seed){ set_foreign_seed(int seed);
sim_seed = seed; int global_seed = $urandom;
} initial
int stimgen () { set_foreign_seed (global_seed);
int desc; DPI/PLI
...
srand(sim_seed);
desc = rand();
...
return 0;
}

© Accellera Systems Initiative 19


Unexpected negative values are generated upon
randomize!
 rand bit [31:0] start_addr; 
class trans;
rand bit [5:0] length;
rand int addr;
bit [31:0] start_end_addr_hash [bit[31:0]];
constraint c {
constraint c { //Generate Non-Overlapping address ranges
addr < MAX_ADDR;
if (start_end_addr_hash.num()) {
}
foreach (start_end_addr_hash [i]) {
endclass
!(start_addr inside {[i-length+1 :
class seq;
start_end_addr_hash [i]]});
rand bit [31:0] addr;
}
trans t;
}
endclass
length == 6'h10;
}...
int, byte, and variables start_end_addr_hash [start_addr] = start_addr + length - 1;
declared as signed can hold
negative random values
foreach (start_end_addr_hash [i]) { 
if (i >= length ) {
!(start_addr inside {
[i-length+1 :
start_end_addr_hash [i]]});
What happens when “start_addr” } else {
of a previous randomization !(start_addr inside {
attempt was picked to be smaller [0 : start_end_addr_hash [i]]});
}
than the address range “length”? }

© Accellera Systems Initiative 20


I am getting unexpected random results when using
default constraints

default constraint c1 {x < 10; y > z;}



... What is the probability of getting “z” be
constraint c2 {x < 5;} greater than “y”?

• Default constraints are not part with the


SystemVerilog standard; several simulators
allow them for legacy purposes
constraint c1 {soft x < 10; y > z;}

constraint c2 {x < 5;} • Once any variable used in default
constrained is used in another constraint ,
the entire default constraint is ignored

• Do NOT use default constraints; use soft


constraints instead.
!

© Accellera Systems Initiative 21


Guidelines Summary
Randomization Results Gotchas

© Accellera Systems Initiative 22


Outline
• Introduction to Constrained Random
Verification
• Randomization Failures Gotchas
• Randomization Results Gotchas
• Randomization Runtime Performance Gotchas

© Accellera Systems Initiative 23


Writing Efficient Constraints

• Often users write //Dynamic array with unique elements
class trans;
rand bit [31:0] addrs [];
constraints constraint unique_arr{ Foreach is
foreach (addrs[i])
performance
focusing on foreach (addrs[j])
if (j < i) greedy!
functionality and }
addrs [i] != addrs [j];

endclass
not performance
• Surprises at class dummy_c; 
randc bit [31:0] val;
runtime w.r.t. endclass
class trans;
Solver overhead rand bit [31:0] addrs [];
function void post_randomize();
dummy_c dc = new;
foreach (addrs[i]) begin
assert (dc.randomize);
addrs[i] = dc.val;
end
endfunction
endclass

© Accellera Systems Initiative 24


Writing Efficient Constraints (cont.)
constraint arith {
 constraint arith {  Bitwise operations
Avoid complex b == a * 64; b == a << 6;
d == c / 8; d == c >> 3;
are relatively easy
operations that
f == 2 ** e; f == 1 << e; to solve even with
overburden the addr % 4 == 0; addr [1:0] == 0; a BDD engine
Solver } }

dist
 rand bit [4:0] rd; 
operators rand bit [4:0] rd;
rand bit [1:0] rd_eq_15;
constraint mode_32bit{
can have mode == 32 -> rd < 16;}
constraint mode_32bit{
runtime mode == 32 -> rd < 15;
constraint rd_dist {
}
overhead. mode == 32 -> rd [3:0] dist
function void post_randomize();
{
Reduce [4'b0000:4'b1110]: 3,
if (mode == 32)
usage as if (rd_eq_15 == 2’b11)
4'b1111 : 1
rd = 5’b01111;
possible };
endfunction
}

© Accellera Systems Initiative 25


Guidelines Summary
Performance Gotchas

© Accellera Systems Initiative 26


References
• Mentor Graphics Verification Academy,
www.verificationacademy.com
• IEEE Standard for SystemVerilog, Unified Hardware Design,
Specification, and Verification Language, IEEE Std 1800-2012,
2012
• UVM User Manual, uvmworld.org.
• UVM Random Stability: Don’t leave it to chance, Avidan Efody,
DVCon 2012.
• Verilog and SystemVerilog Gotchas: 101 Common Coding Errors
and How to Avoid Them, Stuart Sutherland and Don Mills,
Springer

© Accellera Systems Initiative 27


Questions

© Accellera Systems Initiative 28

Вам также может понравиться