SystemVerilog constraintでrand変数に制約をつける

はじめに

SytemVerilogのclassの変数はrandを付けることで乱数にすることができます。

rand変数はrandomizeメソッドで乱数が生成されます。

このとき、constraintで生成される乱数に制約を付けることができます。

module top;
    class A;
        rand bit [3:0] a;
        rand bit [3:0] b;
        rand bit [3:0] c;
        rand bit [3:0] d;
        rand bit [3:0] e;
        rand bit [3:0] f;
        rand bit [3:0] g;
        rand bit [3:0] h;
        constraint c1{
            b == 3;
            c inside {[0:10]};
            b == 3 -> d == 1;
            if (e == 1)
                f == 3;
            else
                f == 4;
            g dist {1 := 10, 2 := 30, [3:4] := 30};
            h dist {1 :/ 10, 2 :/ 30, [3:4] :/ 60};
        }
        constraint c2;
    endclass

    A a;
    constraint A::c2 {a < 4;}  // c2をあとから設定できる。

    initial begin
        a = new();
        a.randomize();
        $display("a:%d b:%d c:%d d:%d e:%d f:%d g:%d h:%d",
            a.a, a.b, a.c, a.d, a.e, a.f, a.g, a.h);

        a.randomize() with {a == 3;};
        $display("a:%d b:%d c:%d d:%d e:%d f:%d g:%d h:%d",
            a.a, a.b, a.c, a.d, a.e, a.f, a.g, a.h);
    end
endmodule

randomizeで値を確定する

<クラス>.randomize()

<クラス>.randomize()で値を確定します。

module top;
    class A;
        rand bit [3:0] a;
    endclass

    A a;
    initial begin
        a = new();
        a.randomize();
        $display("a:%d", a.a);
    end
endmodule

<クラス>.randomize() with <constraint>

<クラス>.randomize() with <constraint>で制約付きで値を確定します。

module top;
    class A;
        rand bit [3:0] a;
    endclass

    A a;
    initial begin
        a = new();
        a.randomize() with {a == 3;};
        $display("a:%d", a.a);  // a:3
    end
endmodule

制約を付ける

「==」指定した値にする

rand bit [10:0] a;
constraint c1{
    a == 5; // a は 5になる
}

「inside」範囲を指定する

rand bit [10:0] a;
constraint c1{
    a inside {[0:100]};  // 0 <= a < 100の範囲で乱数を生成する
}

「->」<条件1>が成り立ったとき、<条件2>になる

rand bit [10:0] a;
rand bit [10:0] b;
constraint c1{
    a == 1 -> b == 2;  // a == 1 のとき b == 2 になる
}

「if」条件式

rand bit [10:0] a;
rand bit [10:0] b;
constraint c1{
    if (a == 2)
        b == 3;
    else if (a == 3)
        b == 4;
}

「dist」重みづけ

<値> := <重み> or <値> :/ <重み>で<値>を重みづけできます。

rand bit [10:0] a;
rand bit [10:0] b;
constraint c1{
    // 1:10%, 2:30%, 3:30%, 4:30%
    g dist {1 := 10, 2 := 30, [3:4] := 30};
    // 1:10%, 2:30%, 3:60/2%, 4:60/2%
    h dist {1 :/ 10, 2 :/ 30, [3:4] :/ 60};
}

あとから制約を付ける

constraint <クラス名>::<constraint名>で制約をクラスの外側から設定できます。

module top;
    class A;
        rand bit [3:0] a;
        rand bit [3:0] b;
        constraint c1{
            b == 3;
        }
        constraint c2;
    endclass

    A a;
    constraint A::c2 {a == 4;}  // c2をあとから設定できる。

    initial begin
        a = new();
        a.randomize();
        $display("a:%d b:%d", a.a, a.b);  // a: 4 b:3
    end
endmodule

制約に初期値を付ける

制約を付けている変数に対して相反する制約を付けると、randomizeが正しく実行されなくなります。

softを付けることで制約がないときに使用される制約を付けることができます。

module top();
    class sample;
        rand bit [2:0] val;
        constraint c{
            soft val == 0;
        }
    endclass

    sample a;
    initial begin
        a = new();
        a.randomize() with {val == 2;};  // val == 2が優先される。 
        // a.randomize();  // valは0になる。
        $display("%d", a.val);
    end
endmodule

コメント

タイトルとURLをコピーしました