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

コメント

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