randomize()における制約(constraint)の一つ、insideによる制約の活用方法についてまとめます。

SystemVerilogでinsideというメンバシップ演算子が追加されていますが、ここで取り上げているのは乱数における制約についてとなります。


insideによりrandomize()により生成される乱数に制限をかけることができます。

これを用いることで本来回路中に"入力される可能性のない値"の組み合わせ検証について試行する必要がなくなるため無駄を省けます。



insideで乱数で出現する値を直接指定


以下は制約により生成する値を直接指定する場合の例です。
8行目~10行目でx, y, zという変数に対して、制約を追加しています。

直接値指定:SystemVerilog

class Transaction;
    rand bit                x;
    rand bit  [(8-1):0]     y;
    rand bit  [(8-1):0]     z;
    logic     [(8-1):0]     a = 255;
    // random constraint
    constraint c1 {
        x   inside  {0, 1};
        y   inside  {70, 122, a};     // 変数指定
        z   inside  {10, 100, 1000};  // 1000は取れない値
    }
endclass
//- Instance
Transaction tr = new();
initial begin
    repeat(10) begin
        if(!tr.randomize()) $finish; // 乱数生成
        $display("x : %d,  y : %d,  z : %d", tr.x, tr.y, tr.z);
    end
    $finish();
end

直接値指定:実行結果

x   inside  {0, 1};
y   inside  {70, 122, a(=255)};
z   inside  {10, 100, 1000};
----------------------------
x : 1,  y : 122,  z :  10
x : 1,  y : 122,  z : 100
x : 0,  y : 122,  z : 100
x : 1,  y :  70,  z :  10
x : 1,  y : 255,  z : 100
x : 0,  y : 122,  z :  10
x : 1,  y : 122,  z :  10
x : 1,  y : 255,  z : 100
x : 1,  y :  70,  z :  10
x : 1,  y : 255,  z : 100
実装9行目のように、変数を用いて制約を与えることも可能です。

また、10行目では8bitのレジスタz(最大値255)に対して、ランダムに取ることのできる値として1000を指定しています。ツールにもよるかもしれませんが、シミュレーション実行時に特にエラーとして通知されることはなく、実行結果を見ると指定が無いものとして10と100だけが制約として認識されていることが分かります。



insideで乱数の遷移する範囲を指定


上の例では、randomize()で出現する値を直接指定していましたが、以下では、値の範囲を指定しています。

範囲指定:SystemVerilog

class Transaction;
    rand bit  [(8-1):0]     y;
    rand bit  [(8-1):0]     z;
    // random constraint
    constraint c1 {
        y   inside  {[0:99]};
        z   inside  {0, [70:75], 100, [250:255]};
    }
endclass
//- Instance
Transaction tr = new();
initial begin
    repeat(10) begin
        if(!tr.randomize()) $finish;
        $display("y : %d,  z : %d", tr.y, tr.z);
    end
    $finish();
end

範囲指定:実行結果

y   inside  {[0:99]};
z   inside  {0, [70:75], 100, [250:255]};
----------------------------
y :  80,  z :   0
y :  35,  z : 251
y :  94,  z : 253
y :   2,  z :  73
y :  82,  z : 100
y :  36,  z : 255
y :   4,  z :  74
y :  79,  z : 255
y :   2,  z :  71
y :   7,  z :  75
"[]"書きで値の範囲を指定します。

実装の7行目のように、範囲指定と値指定を組み合わせることも可能です。



insideで乱数の遷移する範囲の排他的な指定


指定した値"以外"として乱数に制約を掛けるには以下のように記述します。

排他的に制限:SystemVerilog

class Transaction;
    rand bit  [(8-1):0]     y;
    rand bit  [(8-1):0]     z;
    // random constraint
    constraint c1 {
        !(y   inside  {[10:255]});
        !(z   inside  {[0:99], [200:255]});
    }
endclass
//- Instance
Transaction tr = new();
initial begin
    repeat(10) begin
        if(!tr.randomize()) $finish;
        $display("y : %d,  z : %d", tr.y, tr.z);
    end
    $finish();
end

排他的に制限:実行結果

!(y   inside  {[10:255]});
!(z   inside  {[0:99], [200:255]});
----------------------------
y :   6,  z : 162
y :   3,  z : 139
y :   2,  z : 104
y :   5,  z : 163
y :   1,  z : 184
y :   2,  z : 138
y :   7,  z : 144
y :   6,  z : 182
y :   8,  z : 147
y :   2,  z : 117
実装6,7行目のように!( )でinsideを用いた制約を囲うことで、指定した範囲以外の値とする制約をとることができます。

出現する値の範囲より、出現しない値の範囲が大きい場合には便利です。



randomize()制約一覧





参考:
・https://verificationguide.com/systemverilog/systemverilog-constraint-inside/

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

コメント

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