distオペレータはclass内の変数に対して、ランダム制約を付加する際に使用します。
ランダムデータを一定の分布になるように発生させます。
constraint 制約名 { 制約を設定する変数 dist {分布条件} ; }
均等分布:=
:=は重みを均等に分配します。
記述例
ランダム生成する値を2,3,4,5([2:5])のどれかとし、:=(均等に分布)を使用した場合の記述例を示します。
100回ランダム実行し、それぞれの値が何回選択されるかを見ています。
//クラスの定義
class c_dist ;
rand int a00 ;
constraint C01 { a00 dist {[2:5]:=1 } ; }
endclass
//テストベンチ
module test ()
c_dist class00 ;
int cnt2,cnt3,cnt4,cnt5 ;
initial begin
cnt2=0;cnt3=0;cnt4=;cnt5=0;
class00 = new ;
for (int iii=0;iii=100;iii++) begin
class00.randomize() ;
if(class00.a00==2) cnt2++ ;
if(class00.a00==3) cnt3++ ;
if(class00.a00==4) cnt4++ ;
if(class00.a00==5) cnt5++ ;
end
$display("2:%3d 3:%3d 4:%3d 5:%3d",cnt2,cnt3,cnt4,cnt5) ;
end
endmodule
実行結果
2: 22 3: 28 4: 17 5:33
結果は2が22回、3が28回、4が17回、5が33回となっています。5がちょっと大きいですが、大体どの値も同じ割合で出てきています。
[2:5]:=1は、以下のように書き換えても同じです。
constraint C01 { a00 dist {2:=1,3:=1,4:=1,5:=1 }
この場合の実行結果は以下のようになり、こちらのほうがほぼ均等に出力されています。100を1000、10000と増やしていけばさらに均等に分布します。
2: 24 3: 25 4: 25 5:26
重みを1以外に設定すると、どういう意味合いになるかというと、
例えば 2:=1 3:=2 4:=3 5:=4 と記述した場合は、
2が1回出る間に3は2回、4は3回、5は4回 分布されることを期待した設定をおこなったことになります。
つまり、ランダム生成を100回実行すると、大体2の出現割合は10回(10%)3の出現割合は20回(20%)4の出現割合は30回(30%)5の出現割合は40回(40%)となります。
制約と実行結果は以下のようになります。(実行回数100回)
constraint C01 { b00 dist { 2:=1,3:=2,4:=3,5:=4} ; }
2: 13 3: 19 4: 34 5: 34
今回は4と5の出現頻度がたまたま同じとなりました。
ランダム実行を行う回数を100から1000(for文の100を1000に変更)に変更して再度実行してみました。以下結果ですが、概ね予想通りになっています。
2: 96 3: 204 4: 304 5:396
w/nでn固全体に割り当て
:=1 の代わりに:/1を指定することができます。
[2:5]:/1 と設定すると、2,3,4,5それぞれの値が25%で割り当てられます。
つまり単独で使用する限りは:=1 :/1は同様の結果を出力します。
記述例
2から5までの数値ともう一つ10を追加して出現頻度を確認する記述例です。制約はそれぞれ以下のようにしています。
C01:2から5までの任意の値が50%、10が50%の制約
C02:2から5までの数値が同一割合で、10が50%の制約
class c_dist ;
rand int a00,b00 ;
constraint C01 { a00 dist {[2:5]:=1,10:=1 } ; }
constraint C02 { b00 dist {[2:5]:/1,10:=1 } ; }
endclass
module test () ;
c_dist class00 ;
int cnt2a,cnt3a,cnt4a,cnt5a ;
int cnt2b,cnt3b,cnt4b,cnt5b ;
int cnt10a,cnt10b ;
initial begin
cnt2a=0; cnt2b=0 ;
cnt3a=0; cnt3b=0 ;
cnt4a=0; cnt4b=0 ;
cnt5a=0; cnt5b=0 ;
cnt10a=0;cnt10b=0;
for(int iii=0;iii<1000;iii++) begin
class00.randimize() ;
if(class00.a00==2) cnt2a++ ;
if(class00.a00==3) cnt3a++ ;
if(class00.a00==4) cnt4a++ ;
if(class00.a00==5) cnt5a++ ;
if(class00.a00==10)cnt10a++;
if(class00.b00==2) cnt2b++ ;
if(class00.b00==3) cnt3b++ ;
if(class00.b00==4) cnt4b++ ;
if(class00.b00==5) cnt5b++ ;
if(class00.b00==10)cnt10b++;
end
$display("[C01] 2:%3d 3:%3d 4:%3d 5:%3d 10:%3d",cnt2a,cnt3a,cnt4a,cnt5a,cnt10a) ;
$display("[C02] 2:%3d 3:%3d 4:%3d 5:%3d 10:%3d",cnt2b,cnt3b,cnt4b,cnt5b,cnt10b) ;
end
endmodule
実行結果
実行回数を1000回で確認しました。
[C01]の均等分布の結果はどの値も大体均等(1000の20%=200)
[C02]の2から5については1/4、10は均等割を期待していましたが、10が500より若干小さい値となりました。
[C01] 2:207 3:222 4:194 5:189 10:188
[C02] 2:143 3:135 4:111 5:117 10:494
10:=1を10:=2に変更すると、1:1から1:2の割合に代わります。実行結果は以下の通りです。
概ね10が2/3(666)の割合で出力されました。
[C02] 2: 93 3:105 4: 87 5: 82 10:633

コメント