randomizeにおける制約solve-beforeを使用することで、値の組み合わせの出現確率を調節することができます。これだけ読んでもよく意味が分からないと思うので、以下で詳細をまとめます。
solve-beforeは、他の制約と少し立ち位置的に違い、機能的に必ず必要というものではなく、乱数の出現確率を調整するための記述です。
solve-beforeを使用しない場合
まずは、solve-beforeを使用しない場合の実装例と実行結果を見てみます。
以下では、solve-beforeの構文をコメントアウトしています。
solve-before未使用:SystemVerilog
class Transaction;
rand bit x;
rand bit [(2-1):0] y;
// random constraint
constraint c1 {
(x == 0) -> (y == 0);
// solve x before y;
// solve y before x;
}
endclass
Transaction tr = new();
real xy00 = 0; real xy01 = 0; real xy10 = 0; real xy11 = 0;
real xy02 = 0; real xy03 = 0; real xy12 = 0; real xy13 = 0;
localparam repeat_num = 10000;
initial begin
repeat(repeat_num) begin
if(!tr.randomize()) $finish;
if (tr.x == 0 && tr.y == 0) xy00++; if (tr.x == 0 && tr.y == 1) xy01++;
if (tr.x == 0 && tr.y == 2) xy02++; if (tr.x == 0 && tr.y == 3) xy03++;
if (tr.x == 1 && tr.y == 0) xy10++; if (tr.x == 1 && tr.y == 1) xy11++;
if (tr.x == 1 && tr.y == 2) xy12++; if (tr.x == 1 && tr.y == 3) xy13++;
end
$display("[x, y] 0, 0 : %f %%", (xy00/repeat_num)*100);
$display("[x, y] 0, 1 : %f %%", (xy01/repeat_num)*100);
$display("[x, y] 0, 2 : %f %%", (xy02/repeat_num)*100);
$display("[x, y] 0, 3 : %f %%", (xy03/repeat_num)*100);
$display("[x, y] 1, 0 : %f %%", (xy10/repeat_num)*100);
$display("[x, y] 1, 1 : %f %%", (xy11/repeat_num)*100);
$display("[x, y] 1, 2 : %f %%", (xy12/repeat_num)*100);
$display("[x, y] 1, 3 : %f %%", (xy13/repeat_num)*100);
$finish();
end
solve-before未使用:実行結果
(x == 0) -> (y == 0);
----------------------------
[x, y] 0, 0 : 19.790000 %
[x, y] 0, 1 : 0.000000 %
[x, y] 0, 2 : 0.000000 %
[x, y] 0, 3 : 0.000000 %
[x, y] 1, 0 : 20.130000 %
[x, y] 1, 1 : 20.030000 %
[x, y] 1, 2 : 19.590000 %
[x, y] 1, 3 : 20.460000 %
そこで、solve-beforeを用いて、値が決まる順番を明示的に指定することで、出現確率を調節することが可能です。
solve-beforeを使用した場合
以下でsolve-beforeを用いた場合について、2通りの例を示します。実装コードは、上記7行目8行目のコメントアウト部分を片方ずつ有効にした結果です。
順序を明確に指定:実行結果1
(x == 0) -> (y == 0);
solve x before y;
----------------------------
[x, y] 0, 0 : 49.710000 %
[x, y] 0, 1 : 0.000000 %
[x, y] 0, 2 : 0.000000 %
[x, y] 0, 3 : 0.000000 %
[x, y] 1, 0 : 12.380000 %
[x, y] 1, 1 : 12.770000 %
[x, y] 1, 2 : 12.510000 %
[x, y] 1, 3 : 12.630000 %
順序を明確に指定:実行結果2
(x == 0) -> (y == 0);
solve y before x;
----------------------------
[x, y] 0, 0 : 12.560000 %
[x, y] 0, 1 : 0.000000 %
[x, y] 0, 2 : 0.000000 %
[x, y] 0, 3 : 0.000000 %
[x, y] 1, 0 : 12.780000 %
[x, y] 1, 1 : 24.760000 %
[x, y] 1, 2 : 24.370000 %
[x, y] 1, 3 : 25.530000 %
randomize()制約一覧
参考:
・http://japanese.sugawara-systems.com/systemverilog/constraint_random_value_generation.htm
・https://www.chipverify.com/systemverilog/systemverilog-solve-before