In constrain random verification,
it may take a long time for a particular corner case to be generated. Sometime even
after running test-case for N number of time corner case may not be generated
and you may see holes in functional coverage. To resolve this you can use a weighted
distribution to drive stimulus in particular direction.
The dist keyword in
systemverilog allows you to create weighted distributions so that some values
are chosen more often than others. There are 2 different kind of distribution
operators available in systemverilog.
The := operator assigns the specified
weight to the item or, if the item is a range, to every value in the range.
The
:/ operator assigns the specified weight to the item or, if the item is a
range, to the range as a whole. If there are n values in the range, the weight
of each value is range_weight / n.
Limitation:
dist expressions cannot appear in other
expressions.
dist operation shall not be applied to randc variables.
Let's go through below example to understand how it works,
----------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class my_class; | |
rand bit [1:0] a; | |
rand bit [1:0] b; | |
constraint dist_a_cn { | |
a dist {0 := 40, | |
[1:3] := 60}; | |
// a = 0, weight = 40/(40+60+60+60) = 40/220 | |
// a = 1, weight = 60/220 | |
// a = 2, weight = 60/220 | |
// a = 3, weight = 60/220 | |
} | |
constraint dist_b_cn { | |
b dist {0 :/ 40, | |
[1:3] :/ 60}; | |
// b = 0, weight = 40/(40+60) = 40/100 | |
// b = 1, weight = (60/3)/100 = 20/100 | |
// b = 2, weight = (60/3)/100 = 20/100 | |
// b = 3, weight = (60/3)/100 = 20/100 | |
} | |
endclass : my_class | |
module top(); | |
`define ITR 15000 | |
my_class dist_c; | |
bit [1:0] a[`ITR]; | |
bit [1:0] b[`ITR]; | |
bit [1:0] temp_q[$]; | |
initial begin | |
dist_c = new(); | |
for (int i=0; i<`ITR ; i++) begin | |
if (!dist_c.randomize()) begin | |
$error("Randomization failed"); | |
end | |
a[i] = dist_c.a; | |
b[i] = dist_c.b; | |
end | |
for(int i=0; i<4; i++) begin | |
temp_q = a.find with (item == i); | |
$display("for array a : number of elements with %0d : %0d, dist : %f", | |
i, temp_q.size(), (real'(temp_q.size())*220)/`ITR ); | |
end | |
$display(); | |
for(int i=0; i<4; i++) begin | |
temp_q = b.find with (item == i); | |
$display("for array b : number of elements with %0d : %0d, dist : %f", | |
i, temp_q.size(), (real'(temp_q.size())*100)/`ITR ); | |
end | |
end | |
endmodule : top | |
//Output: | |
// for array a : number of elements with 0 : 2725, dist : 39.966667 | |
// for array a : number of elements with 1 : 4069, dist : 59.678667 | |
// for array a : number of elements with 2 : 4094, dist : 60.045333 | |
// for array a : number of elements with 3 : 4112, dist : 60.309333 | |
// for array b : number of elements with 0 : 6024, dist : 40.160000 | |
// for array b : number of elements with 1 : 2935, dist : 19.566667 | |
// for array b : number of elements with 2 : 3079, dist : 20.526667 | |
// for array b : number of elements with 3 : 2962, dist : 19.746667 |
----------------------------------------------------------------------------
Reference:
1) SystemVerilog LRM 2012
2) SystemVerilog for Verification 3rd edition by Chris Spear
No comments:
Post a Comment