SV--隨機


a:系統函數:$random/$urandom/$urandom_range,$dist_uniform/$dist_normal/$dist_exponetial/$dist_possion/$dist_chi_square/$dist_t/$dist_erlang。注意返回值的位寬、范圍。

b:randcase、randsquence實現分支選擇。

c:基於對象的隨機。rand/randc申明、randomize、約束:indise/dist/->/if else/foreach/soft約束。

d:標准隨機函數stb::randomize();隨時對任意變量進行隨機化並添加約束。

 

1:  主要使用$urandom_range/$urandom/$random.

       $urandom_randge(max,min):返回32位無符號數,包括邊界。

       $urandom(seed):返回32bit無符號數。

       $random(seed)返回32位有符號數,可正可負。

2:randcase

         3:x = 1;

         1:x = 2;

         2:x = 3;

       endcase  // x的隨機權重為3:1:2.

       如果權重為0,則不會隨機到此條目。此外,權重還可以是任意表達式。

 

3:每次調用randomize都會重新隨機。

       randc的變量,在隨機完本輪的所有值后,自動開啟新周期的隨機。

       dist分布注意:/      =/數組中共享此權重。dist操作不能應用於randc變量。缺省值為:=1。

       約束是雙向的,注意概率。

       約束僅支持2態值。4態會報錯。

       solve a before b,先解a,再解b。

       子類中的約束與基類相同時,那么他會改寫基類的約束。

 

       randomize是虛方法,返回int變量,不可改寫。sv中還提供pre_/post_randomize函數,可以改寫。randomize……with動態修改約束。

       rand_mode、constraint_mode。0表示關閉,1表示打開。默認打開。rand_mode可以關閉句柄中的所有rand變量,也可以關閉某一個變量。

 

4:randomzie……with。

       soft約束,一般用於正常的約束,在異常包時,以后面約束的為准。

 

由於對象class由數據和操作組成,所以對數據的隨機化一般放在一個class內。(對環境或環境的配置也可以反映在配置參數的隨機化上)

一個constraint包括兩部分:rand/randc變量聲明,constraint約束塊。其中randc會在重復之前,周期性取值,constraint約束塊中的變量至少有一個rand/randc

                                     變量,constraint約束塊必須在{}內,用;來表示多個約束。約束塊是一種聲明性的代碼,並行運行。

SV中的randomize函數有兩種引用方法:

1)直接用任意一個class類型的對象引用,作用在整個class的rand/randc類型變量上。 this.randomize(var),只隨機var,但是pre/post_randomize也會被調用

  obj.randomize(null),此時的randomize只是作為一個checker,檢查solver是否成功,不是作為一個generator。現有值符合constraint,success返回1,failed返回0。

2)std::randomize(,,,) with {} ,其中()內的變量便是需要random的variable,with表示一些random constraint

                    success = std::randomize(a,b,c) with{a<b,a+b<length} ,隨機化成功,返回success為1.

  with約束中的變量如果與調用randomize的obj相同,需要用local::來為變量定位。

3)直接使用$urandom/$urandom_range()等函數。

constraint的引用:一般在一個initial模塊或program中引用,采用assert的形式來:assert( p.randomize() );隨機化失敗后,返回值為0,assert將會打印log,

                         並退出。還有兩個隱性function:pre_randomize(),post_randomize(), 可以加入非randomize變量的初始化,同時留下hook。

 

幾種約束方式:

1) constraint  longth { low < mid;

                                 mid < high;}    //關系操作符必須分開來寫

2)constraint   length { len == mid - low;}    //約束塊內不能有賦值語句,相反應該用關系運算符

3)constraint   c_dist  { src_dist {0:= 40, [1:3]:=60;}     //:=后表示權重---相等

                                  dst_dist {0:/ 40,  [1:3]:/ 60};}  //:/后表示權重---比例

4)constraint   c_rang { c inside {[lo:hi]};                       //inside:low-high

                                  b inside {[10:$]};                      //$可以表示邊界

                                  !(c inside {[$:30]}); }               //加()可以加!表示非

5)constraint   c_io { (io_space_mode) -> addr[31]==1'b1;    //--->表示if

                              if (op==READ) len inside {[BYTE:WORD]}; }  //--->if--else

6)constraint   c_xy  {(x==0) -> y==0;      //solve..before可能改變解的概率

                                solve x before y;}

7)assert (t.randmize() with {addr > 50;    //內嵌式的約束,addr的作用域是class這一級的,randomize的效果等價

                                         addr < 150;} )

                                       

 

隨機化的開關控制:

rand bit[7:0] length;

p.length.rand_mode(0);    //設置包長為非隨機值 

 

約束的開關控制:

              p.c_short.constraint_mode(0);   //句柄+約束塊+mode,控制這個約束塊mode

              p.constraint_mode(0);                //句柄+mode,控制整個句柄的mode

 

對數組的約束:

1)constraint    d_size   {

          d.size inside {[1:10]} ;

                                    d.sum == 4'h4;   }  //sum的位數與數組中的數的位數相同,所以又是可能達不到想要的范圍。

 

在實際應用中,應該多用變量來控制約束。  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM