randomize制約 dist

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

コメント

Copied title and URL