SV中的覆蓋率


SV采用CRT的激勵形式,而判斷驗證進度的標准也就是覆蓋率(coverage)。

覆蓋率的兩種指定形式:顯式的,直接通過SV來指定出的,如SVA,covergroup。

                               隱式的,在驗證過程中,隨"register move"就可以由simulator得到的,如代碼覆蓋率等。

覆蓋率類型:代碼覆蓋率---由仿真器直接提供,只能表示設計的冗余度,與spec關系不大。(toggle/expression/block)

                 功能覆蓋率---與spec比較來發現,design是否行為正確,需要按verification plan來比較進度。(assertion/covergroup)

                 斷言覆蓋率---用於檢查幾個信號之間的關系,常用在查找錯誤。

                 漏洞率-------同一功能驗證,運行多個seed,尋找bug

 

功能覆蓋率的兩個重要部分是采樣的數據和數據被采樣的時刻。數據被采樣的時刻可以是1)使用wait或@來阻塞賦值,2)使用sample的方法。采樣的數據則需要在代

           碼中加入覆蓋組(Covergroup)和倉(Bin),覆蓋組可以定義在類中,程序塊,模塊中。使用覆蓋組之前必須先進行實例化。所以一般在類中使用覆蓋組時,將

           覆蓋組的實例化加在類的構造函數new()中。Covergroup和Coverpoint的命名應當盡可能的明確,這樣方便檢查覆蓋率文件。

      class  Driver_cbs_coverage  extends  Driver_cbs;                           event  trans_ready; //@event來觸發采樣

                  covergroup  CovPort;                                                                    covergroup  CovPort  @(trans_ready)

                            .......                                                                                        coverpoint    ifc.cb.port;

                   endgroup                                                                                    endgroup  

                   virtual  task  post_tx(Transaction tr);

                            CovPort.sample();        //顯示通過callback來回調sample函數,完成采樣

                   endtask

 

SV支持自動倉的創建,但是更多地適用於2的冪次方,因為這樣才有可能100%命中,最大的自動創建倉的數目是64。auto_bin_max限制自動創建倉的個數,SV這

        時,會將值域平分在各個倉。

               covergroup  CovPort;                                                                        covergroup  CovPort;

                   coverpoint  tr.port                                                                                 options.auto_bin_max = 2;  //對整個covergroup有效

                         {options.auto_bin_max=2;}   //只對此coverpoint有效                          coverpoint  tr.port;

               endgroup                                                                                         endgroup         

 

用戶自定義創建倉(bin),將coverpoint和倉分別明確的命名。

              covergroup   Covkind;                                           

                     kind:coverpoint  tr.kind{           //用kind為coverpoint命名

                                       bins zero={0};          //自定義一個名為zero的倉,值為0

                                       bins lo={[1:3],5};     //自定義一個名為lo的倉,值為[1:3]或5

                                       bins hi[]={[8:$]};     //自定義$-8個倉,8個值得范圍在[8:$]

                                       bins misc=default;     //定義一個default的倉,所示所有的剩下的不關心的值

                      }

              endgroup

 

為覆蓋點增加條件控制采樣時間段,關鍵字iff 。                                                                   

              covergroup  CoverPort;                                                                      

                    coverpoint   port_value  iff(!bus_if.reset);                                      

              endgroup                                                                                                                                                                                   

為枚舉類型創建倉(bin),所有枚舉類型之外的值都會被忽略,SV默認每個枚舉的值一個倉。

              typedef enum{INIT, DECODE, IDLE}fsmstate_e;

                    fsmstate_e  pstate, nstate;

                    covergroup  cg_fsm;

                          coverpoint  pstate;

                    engroup

忽略某個coverpoint的某些值,覆蓋率不在檢查該值,關鍵字ignore_bins。             illegal_bins不僅忽略某個coverpoint的值,還會報錯。                     

              bit [2:0]low_ports_0_5;                                                                 bit [2:0]low_ports_0_5;   

              covergroup  CoverPort;                                                                  covergroup  CoverPort;

                    coverpoint  low_ports_0_5{                                                            coverpoint  low_ports_0_5{    

                           options.auto_bin_max=4;                                                               options.auto_bin_max=4; 

                           ignore_bins hi={[6,7]};                                                                  illegal_bins hi={[6,7]};

                    }                                                                                                   }

              endgroup                                                                                      endgroup

使用cross關鍵字創建交叉覆蓋率。                                                                  //使用串聯值的方式來替換交叉覆蓋

               covergroup  Covport;                                                                   covergroup   CrossBinnames;

                   port:coverpoint   tr.port                                                                                   a:coverpoint   tr.a{bins a0={0};  bins a1={1};}

                               {bins  port[] = {[0:$]};}                                                                     b:coverpoint   tr.b{bins b0={0}; bins b1={1};}

                   kind:coverpoint   tr.kind                                                                         ab:cross  a,b  {bins a0b0=binsof(a.a0)&&binsof(b.b0);

                                {bins zero={0};                                                                                             bins a1b0=binsof(a.a1)&&binsof(b.b0);

                                  bins lo={[1:3],5};  //注釋同上,只創建一個倉                                                    bins b1=binsof(b.b1);}

                                  bins hi[]={[8:$]};                                                                  ab:coverpoint{tr.a, tr.b}  //用串聯值得方式來替換

                                  bins misc=default;}                                                                                {bins a0b0={2'b00};bins a1b0={2'b10};}   

                   cross  kind,port{                                                                       endgroup

                                 ignore_bins  hi=binsof(port) intersect{7}; //去除port這個coverpoint的倉7

                                 ignore_bins  md=binsof(port) intersect{0} &&

                                                          binsof(kind) intersect{[9:11]};

                                 ignore_bins  lo=binsof(kind.lo);}  //去除kind這個coverpoint的lo倉         

               endgroup

對於單個的covergroup,它的覆蓋率是由簡單覆蓋點和交叉覆蓋點兩部分組成的,可以通過關鍵字option.weight來控制整體的覆蓋率傾向。

              covergroup   CovPort;

                        Kind:coverpoint   tr.kind   {bins zero={0};    option.weight=5;}

                        port:coverpoint   tr.port   {bins  port={0};    option.weight=0;}   //計算該covergroup的覆蓋率時,忽略該coverpoint

                        cross kind,port {option.weight = 10;}

              endgroup

當需要編寫的覆蓋組之間十分接近時,可以寫出一個通用的覆蓋組,然后通過new函數或ref的形式來傳遞參數。

              bit[2:0]port;                                                                            bit[2:0]port_a,port_b;                                              

              covergroup  CoverPort (int mid);                                               covergroup  CoverPort (ref bit[2:0]port, input int mid);  //定義ref形式

                        coverpoint port{bins lo={[0:mid-1]};                                       coverpoint port{bins lo={[0:mid-1]};

                                                bins hi={mid:$};};                                                                 bins hi={mid:$};};

              endgroup                                                                                          endgroup

              CoverPort  cp;              //定義新的covergroup                              CoverPort  cpa, cpb;              //定義新的covergroup

              initial    cp=new(5);     //例化covergroup並傳遞參數                       initial  begin  cpa=new(port_a,4);     //例化covergroup並傳遞參數

                          .............                                                                                          cpa=new(port_b,4);

 

設置某個covergroup的inst_name,set_inst_name();

 

 使用VCS等仿真工具可以追溯到每個實例的覆蓋率,但此時covergroup中應該添加聲明。

              covergroup  CoverLength(string comment);

                    coverpoint  tr.length;

                    option.per_instance=1;    //指定需要單個實例的覆蓋率

                    option.comment=$psprintf("%m");

                    /或者指定自己的注釋

                    option.comment = comment;

               endgroup

               CoverLength  cp_lo = new("Low port numbers");

 

option.at_least,在無法有效的建立bin時,通過該設置保證bin被擊中N次后,就算是覆蓋完全。

 

還有兩個重要的命令:option.cross_num_print_missing = N;  // 讓仿真工具給出所有的倉,柏闊那些沒有被命中的倉(默認不會報出)

                           option.goal=N;  // 設置覆蓋組或覆蓋點的目標 如90等

 

在長仿真過程中:

$get_coverage:Covergroup::get_coverage()/cgInst:Covergroup()得到某個覆蓋組或者inst的coverage

$get_inst_coverage:得到特定inst的覆蓋率。

 


免責聲明!

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



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