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 %
上の結果のように、「(x == 0) -> (y == 0);」で「xが0のとき、yは0」という制約のみ付与すると、x,yの組み合わせのうち、出現可能な組み合わせがおよそすべて等確率で出現することが分かります。
このような場合、xが0のときには、[x,y] = [0, 0]の1通りしか出現可能な組み合わせが存在しないにも関わらず、x=1の場合と同じ頻度でこの組み合わせが出現することになります。カバレッジなど考慮すると、より多くx=1の場合の組み合わせを検証したい場合があるかもしれません。

そこで、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 %
「solve x before y」のようにすることで、xの値が決まった後にyの値が決まるというような以下の図で示す関係をツールに渡すことができます。
xの値は0か1の2択で50%の確率で遷移し、yの値は0~3の4通りに遷移します。また、(x==0)のとき(y==0)の制約を加えているので、上記のような結果となりました。

順序を明確に指定:実行結果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 %
上の実行結果の例1とは異なり、「solve y before x」とすることで、yの値が決まった後に、xの値が決まるというような以下の図で示す関係を制約として加えています。
yの値に応じて、値の組み合わせの出現確率が決まることが分かるかと思います。



randomize()制約一覧






参考:
http://japanese.sugawara-systems.com/systemverilog/constraint_random_value_generation.htm
https://www.chipverify.com/systemverilog/systemverilog-solve-before

このエントリーをはてなブックマークに追加
コメントを閉じる

コメント

コメントフォーム
記事の評価
  • リセット
  • リセット