SV -- Coverage 覆蓋率


SV -- Coverage 覆蓋率

本文內容來自:

  1. http://www.asic-world.com/systemverilog/coverage.html
  2. https://verificationguide.com/systemverilog/systemverilog-array-manipulation-methods/
  3. https://blog.csdn.net/bleauchat/article/details/90445713 (本文的主要來源,只做了部分補充和修改)

————————————————
版權聲明:本文為CSDN博主「bleauchat」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bleauchat/article/details/90445713

@(SV)

1. Coverage概念

覆蓋率用來衡量設計中已經被測部分和未測部分的比例,通常被定義為已達到所需驗證部分的百分比.
目標覆蓋率是指在驗證計划中規定的需要驗證點的目標值。 在驗證計划中, 當驗證點實際覆蓋率沒有達到 100% 的時候, 說明驗證工作還未完成目標方案。 沒有達到 100% 的項目需要通過\(\color{red}{添加測試用例或者修改約束}\)等來對其進行充分的驗證;
驗證計划中列出的項目都要一一被測試, 當然這需要一個比較全面和完整的驗證計划。為此, 在驗證環境搭建的前期, 制定驗證計划, 明確驗證點並確定目標覆蓋率是一項艱巨而且細致的工作;

制定驗證計划中的功能點的時候, 需要考慮如下三個問題:
1) 哪些功能點需要檢查?
2) 這個功能點的哪些數據需要檢查?
3) 如何對這些數據進行采樣?

哪些功能點需要檢查呢? 這要根據設計的具體情況而定, 一般情況下, 以下幾類是參考的對象: 功能要求、 接口要求、 系統規范、 協議規范等。 具體驗證計划中可能表現為:FIFO 是否溢出和空讀、 外部接口是否遵從以太網物理層的傳輸協議、 是否滿足系統規范要求的支持發送超長包、 內部的AMBA 總線是否符合協議要求等;

主要有兩種coverage評估方式:

  • 代碼覆蓋率
    • 代碼覆蓋率度量執行了多少“設計代碼”。
    • 包括行覆蓋率FSM狀態機覆蓋率分支覆蓋率條件覆蓋率path路徑覆蓋率
      • 行覆蓋率: 檢查某行代碼是否被執行過
      • 分支覆蓋率: 檢查條件分支是否都被執行過
      • 條件覆蓋率, 表達式覆蓋率: 通過真值表分析表達式各種邏輯組合
      • 有限狀態機覆蓋率: 檢查每個狀態是否被覆蓋, 狀態之間的跳轉是否被執行
    • 仿真工具將自動從設計代碼中提取代碼覆蓋率.代碼覆蓋率就算達到100%,這並不意味着不存在bug.
  • 功能覆蓋率
    • 功能覆蓋是一個用戶定義的度量,它度量在驗證中執行了多少設計規范。
    • 面向數據的覆蓋(Data-oriented Coverage)——檢查數據值的組合。對已進行的數據組合檢查.我們可以通過編寫覆蓋組(coverage groups)、覆蓋點(coverage points)和交叉覆蓋(cross coverage)獲得面向數據的覆蓋率.
    • 面向控制的覆蓋(Control-oriented Coverage)——檢查行為序列(sequences of behaviors)是否已經發生.通過編寫SVA來獲得斷言覆蓋率(assertion coverage).

2. 功能覆蓋率

使用覆蓋組結構定義覆蓋模型.覆蓋組結構(covergroup construct)是一種用戶自定義的類型,一旦被定義就可以創建多個實例就像類一樣,也是通過new()來創建實例的.覆蓋組可以定義在module、program、interface以及class中.在動手編寫測試代碼之前,我們需要首先弄清楚相關設計的關鍵特性、邊界情形和可能的故障模式,這其實就是驗證計划的內容

每一個覆蓋組都必須明確一下內容:

  • 覆蓋點(coverage points),也就是需要測試的變量;
  • 一個時鍾事件以用來同步對覆蓋點的采樣(sampling of coverage points);
  • 可選的形式參數(Optional formal arguments);
  • 覆蓋點之間的交叉覆蓋(Cross coverage between coverage points);
  • 覆蓋選項(Coverage options);

語法:

covergroup cov_grp @(posedge clk);
  cov_p1: coverpoint a;//定義覆蓋點
endgroup
 
cov_grp cov_inst = new();//實例化覆蓋組

上面例子使用時鍾上升沿作為采樣點。

covergroup cov_grp;
  cov_p1: coverpoint a;//cov_p1為覆蓋點名,a為覆蓋點中的變量名,也就是模塊中的變量名
endgroup
 
cov_grp cov_inst = new();
@(abc) cov_inst.sample();

通過.sample()函數在外部申明采樣點。

此外,覆蓋組中允許帶形式參數,外部在引用覆蓋組時可以通過傳遞參數,從而對該覆蓋組進行復用,如下:

covergroup address_cov (ref logic [7:0] address,
           input int low, int high) @ (posedge ce);
        ADDRESS : coverpoint address {
          bins low    = {0,low};
          bins med    = {low,high};
        }
      endgroup
     
    address_cov acov_low  = new(addr,0,10);
    address_cov acov_med  = new(addr,11,20);
    address_cov acov_high = new(addr,21,30);

3. 覆蓋點

一個覆蓋組可以包含多個覆蓋點,一個覆蓋點可以是一個整型變量也可以是一個整型表達式(integral variable or an integral expression);在驗證環境中,覆蓋點可以放置在下面四個位置:

推薦覆蓋點一般放在DUT的輸入輸出的接口位置,也就是上圖中的F2和F4.

每一個覆蓋點都與"bin(倉)"關聯,在每一個采樣時鍾仿真器都會自增關聯的bin值(increment the associated bin value)
bin可以自動創建或者顯示定義:

自動或隱式bin(Automatic Bins or Implicit Bins)

對於覆蓋點變量范圍內的每一個值都會有一個對應的bin,這種稱為自動或隱式的bin.例如,對於一個位寬為nbit的覆蓋點變量,2^n個自動bin將會被創建.看下面例子:

    module cov;
      logic       clk;
      logic [7:0] addr;
      logic       wr_rd;
     
      covergroup cg @(posedge clk);
        c1: coverpoint addr;
        c2: coverpoint wr_rd;
      endgroup : cg
      cg cover_inst = new();
      ...
    endmodule

對於覆蓋點addr,將會有c1.auto[0] c1.auto[1] c1.auto[2] … c1.auto[255]等256個bin被自動創建;
對於覆蓋點wr_rd,將會有c2.auto[0]這一個bin被創建;

隱式bin示例:

module tb;
 
  // Declare some variables that can be "sampled" in the covergroup
  bit [1:0] mode;
  bit [2:0] cfg;
 
  // Declare a clock to act as an event that can be used to sample
  // coverage points within the covergroup
  bit clk;
  always #20 clk = ~clk;
 
  // "cg" is a covergroup that is sampled at every posedge clk
  covergroup cg @ (posedge clk);//覆蓋組中只有mode,取值范圍為0~3,而且沒有創建bin,這樣系統自動創建4個bin
    coverpoint mode;
  endgroup
 
  // Create an instance of the covergroup
  cg  cg_inst;
 
  initial begin
    // Instantiate the covergroup object similar to a class object
    cg_inst= new();
 
    // Stimulus : Simply assign random values to the coverage variables
    // so that different values can be sampled by the covergroup object
    for (int i = 0; i < 5; i++) begin
      @(negedge clk);
      mode = $random;
      cfg  = $random;
      $display ("[%0t] mode=0x%0h cfg=0x%0h", $time, mode, cfg);
    end
  end
 
  // At the end of 500ns, terminate test and print collected coverage
  initial begin
    #500 $display ("Coverage = %0.2f %%", cg_inst.get_inst_coverage());
    $finish;
  end
endmodule

輸出:

mode只取到了1和0兩個值,所以只覆蓋了兩個自動創建的bin,所以覆蓋率為50%.覆蓋點的覆蓋率就是用觸發的bin的數目除以總的bin的數目

例二:

module tb;
 
  bit [1:0] mode;
  bit [2:0] cfg;
 
  bit clk;
  always #20 clk = ~clk;
 
  // "cg" is a covergroup that is sampled at every posedge clk
  // This covergroup has two coverage points, one to cover "mode"
  // and the other to cover "cfg". Mode can take any value from
  // 0 -> 3 and cfg can take any value from 0 -> 7
  covergroup cg @ (posedge clk);//覆蓋組定義了4個coverpoint
 
    // Coverpoints can optionally have a name before a colon ":"
    cp_mode    : coverpoint mode;
    cp_cfg_10  : coverpoint cfg[1:0];
    cp_cfg_lsb : coverpoint cfg[0];
    cp_sum     : coverpoint (mode + cfg);
  endgroup
 
  cg  cg_inst;
 
  initial begin
    cg_inst= new();
 
    for (int i = 0; i < 5; i++) begin
      @(negedge clk);
      mode = $random;
      cfg  = $random;
      $display ("[%0t] mode=0x%0h cfg=0x%0h", $time, mode, cfg);
    end
  end
 
  initial begin
    #500 $display ("Coverage = %0.2f %%", cg_inst.get_coverage());
    $finish;
  end
endmodule

輸出:

在modelsim中仿真,使用`view covergroups`可以得到報表信息:
可以看到各個倉的覆蓋率如下: **cp\_mode:50% | cp\_cfg\_10 :100% | cp\_cfg\_1sb :100% | cp\_sum : 62.5% | Average = 78.125%** 其中,cp\_mode和cp\_cfg\_1sb都沒問題,主要是cp\_sum和cp\_cfg\_10。cp\_sum的因為是一個表達式,覆蓋點倉的數量實際是根據表達式最大位寬的變量來創建的,也就是cp\_sum創建了包含0-7這8個數值的倉,所以cp\_sum覆蓋率是理論上應該是4/8=50%,但是實際上,這段代碼的覆蓋點是在上升沿采樣的,而數據變化是在下降沿,這就導致在最開始的20ns的時候,mode和cfg都是0,這時采樣后cp\_sum兩個數的和就是0,所以多覆蓋了一個0值,因此cp\_sum覆蓋率為5/8=62.5。同理,因為一開始多采了一個0的緣故,cp\_cfg\_10的覆蓋率為100%。

顯式bin

"bins"關鍵字被用來顯示定義一個變量的bin,可以為給定范圍內的變量的每個值創建單獨的bin,也可以將一個或多個bin指向變量的某個范圍.使用顯示bin,也就是用戶自定義bin可以增加覆蓋的准確度!它可以將變量的取值范圍限定在你感興趣的區域內!

顯示bin緊跟在對應的覆蓋點后面,用{ }包圍起來,關鍵字"bins"后跟着bin名以及變量的值或范圍。

格式如下:

covergroup 覆蓋組名 @(posedge clk);//時鍾可以沒有
  覆蓋點名1: coverpoint 變量名1{ bins bin名1   = (覆蓋點取值范圍);
                               bins bin名2   = (覆蓋點取值范圍);
                               bins bin名3   = (覆蓋點取值范圍);
                                  .......
                                  }//一般會將bin的數目限制在8或16
      覆蓋點名2: coverpoint 變量名2{ bins bin名1   = (覆蓋點取值范圍);
                                    bins bin名2   = (覆蓋點取值范圍);
                                    bins bin名3   = (覆蓋點取值范圍);
                                    .......
                                  }
                               。。。。。。
    endgroup : 覆蓋組名

    //注意對coverpoint的bin的聲明使用的是{},這是因為bin是聲明語句而非程序語句,后者才用begin..end
    //圍起來,而且{}后也沒有加分號,這和end是一樣的

示例:

module cov;
  logic       clk;
  logic [7:0] addr;
  logic       wr_rd;
 
  covergroup cg @(posedge clk);
    c1: coverpoint addr { bins b1 = {0,2,7};
                          bins b2[3] = {11:20};
                          bins b3   = {[30:40],[50:60],77};                       
                          bins b4[] = {[79:99],[110:130],140};
                          bins b5[] = {160,170,180};
                          bins b6    = {200:$};
                          bins b7 = default;}

    c2: coverpoint wr_rd {bins wrrd};
  endgroup : cg
   
  cg cover_inst = new();
  ...
endmodule

上面幾個倉的含義如下:

bins b1    = {0,2,7 };               //bin “b1” increments for addr = 0,2 or 7
bins b2[3] = {11:20};                //creates three bins b2[0],b2[1] and b2[3].
//and The 10 possible values are distributed as follows: (11,12,13),(14,15,16) 
//and (17,18,19,20) respectively.當不能均等分配時,最后一個數組要多
bins b3    = {[30:40],[50:60],77};   //bin “b3” increments for addr = 30-40 or 50-60 or 77
bins b4[]  = {[79:99],[110:130],140};//creates three bins b4[0],b4[1] and b4[2] with values 79-99,50-60 and 77 respectively
bins b5[]  = {160,170,180};          //creates three bins b5[0],b5[1] and b5[2] with values 160,170 and 180 respectively
bins b6    = {200:$};                //bin “b6” increments for addr = 200 to max value i.e, 255.
default bin;                         // catches the values of the coverage point that do not lie within any of the defined bins.
  • 說白了,覆蓋組的作用就是將覆蓋點的取值范圍分為了多個bin,每個bin表示了一段取值范圍
  • bin就表示了addr的取值范圍,如果這個范圍內有一個值被取到了,則這個bin就被覆蓋了
  • 如果所有的bin都被覆蓋,則覆蓋率為100%
  • default 不會用於計算覆蓋率,default的意思就是其他值

bins for transitions (bin值域的轉變)

可以通過指定序列(sequence)來進行覆蓋點的轉換:

value1 =>  value2;
range_list_1 => range_list_2;//覆蓋點的值從value1轉變到value2,value1和value2可以是某個值,也可以是范圍

covergroup cg @(posedge clk);
  c1: coverpoint addr{ bins b1   = (10=>20=>30);
                       bins b2[] = (40=>50),(80=>90=>100=>120);
                       bins b3   = (1,5 => 6, 7);
                       bins b4   = default sequence;}
  c2: coverpoint wr_rd;
endgroup : cg
 
bins b1   = (10=>20=>30);                // addr的值轉換次序為 10->20->30,如果沒有執行這個次序,則這個bins沒有覆蓋
bins b2[] = (40=>50),(80=>90=>100=>120); // b2[0] = 40->50 and b2[1] = 80->90->100->120
bins b3 = (1,5 => 6, 7);                // b3 = 1=>6 or 1=>7 or 5=>6 or 5=>7
bins b4 = default sequence;  //其余沒有出現的轉換序列(sequence) 

consecutive repetions creation 連續轉換

有的時候希望某個變量值連續出現幾次,這個時候就需要用來連續轉換序列,如下:

WRITE=>WRITE=>WRITE=>WRITE;//WRITE出現4次
 
//上面的寫法過於復雜,可以寫成下面:
 
WRITE[*4];
 
 
//例子:
covergroup address_cov () @ (posedge ce);
  ADDRESS : coverpoint addr {
    bins adr_0_2times          = (0[*2]);//0連續出現2次
    bins adr_1_3times          = (1[*3]);//1連續出現3次
    bins adr_2_4times          = (2[*4]);//2連續出現4次
    bins adr1[]          = (1[*1:2]);//1連續出現1~2次
  }
endgroup

Non consecutive repetition 非連續轉換

上面介紹的重復都要求是連續的,下面介紹非連續重復,這用到關鍵字->和=:

    	
    WRITE[->2];
     
    等效於: 	 
     	 	
    ......=>WRITE.......=>WRITE;
     
     
    covergroup address_cov () @ (posedge ce);
      ADDRESS : coverpoint addr {
        bins adr  = (0=>2[->2]=>1);//addr=0,然后2出現2次,不要求連續,然后1
      }
    endgroup

或者:

    WRITE[=2];//WRITE至少出現兩次,不要求連續
     
    等效於: 	 	
     
    ....=>WRITE.....=>WRITE.....=>WRITE;
     
    例子:
    covergroup address_cov () @ (posedge ce);
      ADDRESS : coverpoint addr {
        bins adr  = (0=>2[=2]=>1);//addr=0,然后2至少出現兩次,不要求連續,然后1
      }
    endgroup

wildcard bins 不定值bins

可以用x,z,?來表示某一位可以不定。

wildcard bins abc = {2'b1?};//覆蓋10,11
 
wildcard bins abc = (2'b1x => 2'bx0};
 
//覆蓋 10=>00 ,10=>10 ,11=>00 ,11=>10
 
covergroup address_cov () @ (posedge ce);
  ADDRESS : coverpoint addr {
    // Normal transition bibs
    wildcard bins adr0  = {3'b11?};
    // We can use wildcard in transition bins also
    wildcard bins adr1  = (3'b1x0 => 3'bx00);
    wildcard bins adr2  = (3'b1?0 => 3'b?00);
  }
endgroup

ignore_bins 忽略bin

一組與覆蓋點相關聯的值的轉換可以顯式地進行,除了被ignore_bins修飾的bin,ignore_bins用於排除一些取值,如一個3位的數據,假如它的取值僅在0~5之間,如果使用自動bin那么它的覆蓋率永遠不會到100%,這個時候就可以使用ignore_bins來忽略6、7的取值; ignore_bins 不會用於計算覆蓋率;

    covergroup cg @(posedge clk);
      c1: coverpoint addr{ ignore_bins b1 = {6,60,66};
                           ignore_bins b2 = (30=>20=>10); }//被ignore_bins修飾的值都不在覆蓋范圍之內
    endgroup : cg

illegal_bins 非法bin

觸發illegal bins會終止仿真並報錯

    covergroup cg @(posedge clk);
      c1: coverpoint addr{ illegal_bins b1 = {7,70,77};
                           ignore_bins b2 = (7=>70=>77);}
    endgroup : cg

Examples

 module tb;
  bit [2:0] mode;
  
  // This covergroup does not get sample automatically because
  // the sample event is missing in declaration
  covergroup cg;
    coverpoint mode {
      
      // Declares 4 bins for the total range of 8 values
      // So bin0->[0:1] bin1->[2:3] bin2->[4:5] bin3->[6:7]
      bins range[4] = {[0:$]};//將mode的取值分為4個bin,如上
    }
  endgroup
  
  // Stimulus : Simply randomize mode to have different values and
  // manually sample each time
  initial begin
    cg cg_inst = new();
    for (int i = 0; i < 5; i++) begin
	  #10 mode = $random;
      $display ("[%0t] mode = 0x%0h", $time, mode);
      cg_inst.sample();//聲明的覆蓋組沒有定義時鍾,所以得調用sample()方法進行采樣
    end
    $display ("Coverage = %0.2f %%", cg_inst.get_inst_coverage());
  end
 
endmodule

輸出:

取到了3個bin,覆蓋率為3/4.

4. Cross Coverage 交叉覆蓋

交叉覆蓋是在覆蓋點或變量之間指定的,必須先指定覆蓋點,然后才能定義覆蓋點之間的交叉覆蓋.

可以通過覆蓋點名或者變量名來定義交叉覆蓋,看下面例子:

    //通過覆蓋點來定義交叉覆蓋
    bit [3:0] a, b;
    covergroup cg @(posedge clk);
      c1: coverpoint a;
      c2: coverpoint b;
      c1Xc2: cross c1,c2;
    endgroup : cg
     
    //通過變量名來定義交叉覆蓋
    bit [3:0] a, b;
    covergroup cov @(posedge clk);
      aXb : cross a, b;
    endgroup
     
    //交叉覆蓋的通用定義格式:
     
    交叉覆蓋名:cross 交叉覆蓋點名1,交叉覆蓋點名2;

由於上面每個覆蓋點都有16個bin,所以它們的交叉覆蓋總共有256個交叉積(cross product),也就對應256個bin。

    bit [3:0] a, b, c;
    covergroup cov @(posedge clk);
      BC  : coverpoint b+c;
      aXb : cross a, BC;
    endgroup

注意:覆蓋點中的表達式位寬按照表達式中最大數的位寬來看,所以b+c的位寬仍然是4,倉內有16個數。要符合實際情況(兩個4位相加為5位)可以寫為a+b+5'b0.
上例的交叉覆蓋總共有256個交叉積(cross product),也對應256個bin.

User defined cross bins

在交叉覆蓋中,除了使用上面自動創建的bins之外,還可以用戶自定義交叉bins,這就用到關鍵字binsof和intersect,如下:

    covergroup address_cov () @ (posedge ce);
      ADDRESS : coverpoint addr {
        bins addr0 = {0};
        bins addr1 = {1};
      }
      CMD : coverpoint cmd {
        bins READ = {0};
        bins WRITE = {1};
        bins IDLE  = {2};
      }
      CRS_USER_ADDR_CMD : cross ADDRESS, CMD {
        bins USER_ADDR0_READ = binsof(CMD) intersect {0};//默認的bins本來應該是2*3=6個,但是這里只定義了兩個bins
      }
      CRS_AUTO_ADDR_CMD : cross ADDRESS, CMD {
        ignore_bins AUTO_ADDR_READ = binsof(CMD) intersect {0};
        ignore_bins AUTO_ADDR_WRITE = binsof(CMD) intersect {1} && binsof(ADDRESS) intersect{0};
      }
     
    endgroup

5. Coverage Options 覆蓋率選項

覆蓋率選項用來控制覆蓋組、覆蓋點和交叉覆蓋之間的行為.用下面幾個關鍵字來控制:

at_least

定義一個bin在執行代碼過程中至少觸發的次數,低於這個觸發次數的話,這個bin不算覆蓋,默認值是1;

auto_bin_max

當沒有bin為顯示創建時,定義一個覆蓋點的自動bin的最大數量,默認值為64;

cross_auto_bin_max

定義一個交叉覆蓋的交叉積(cross product)的自動bin的最大數量,沒有默認值;

    covergroup cg @(posedge clk);
      c1: coverpoint addr  { option.auto_bin_max = 128;}//addr自動bin的數目最大為128
      c2: coverpoint wr_rd { option.atleast = 2;}//wr_rd的每個bin至少要觸發兩次,否則不算覆蓋
      c1Xc2: cross c1, c2  { option.cross_auto_bin_max = 128;}//交叉積的自動bin數目最大為128
    endgroup : cg
     
    //覆蓋選項如果是在某個coverpoint中定義的,那么其作用范圍僅限於該coverpoint;
    //如果是在covergroup中定義的,那么其作用范圍是整個covergroup;

6. Coverage methods 覆蓋率方法

  • void sample() : 觸發覆蓋組的采樣
  • real get_coverage() : 返回覆蓋組覆蓋率
  • real get_inst_coverage() 返回覆蓋組實例的覆蓋率
  • void set_inst_name(string) : 設置實例名
  • void start() : 開啟覆蓋率收集
  • void stop() : 結束收集覆蓋率

樣例:

    module test();
     
    logic [2:0] addr;
    wire [2:0] addr2;
     
    assign addr2 = addr + 1;
     
    covergroup address_cov;
      ADDRESS : coverpoint addr {
        option.auto_bin_max = 10;
      }
      ADDRESS2 : coverpoint addr2 {
        option.auto_bin_max = 10;
      }
    endgroup
     
    address_cov my_cov = new;
     
    initial begin
      my_cov.ADDRESS.option.at_least = 1;
      my_cov.ADDRESS2.option.at_least = 2;
      // start the coverage collection
      my_cov.start();
      // Set the coverage group name
      my_cov.set_inst_name("ASIC-WORLD");
      $monitor("addr 8'h%x addr2 8'h%x",addr,addr2);
      repeat (10) begin
        addr = $urandom_range(0,7);
        // Sample the covergroup
        my_cov.sample();
        #10;
      end
      // Stop the coverage collection
      my_cov.stop();
      // Display the coverage
      $display("Instance coverage is %e",my_cov.get_coverage());
    end
     
    endmodule

7. Coverage system task 覆蓋率系統任務

  • $set_coverage_db_name(name) : sets the filename of the coverage database into which coverage information is saved at the end of a simulation run.
  • $load_coverage_db(name) :loads from the given filename the cumulative coverage information for all coverage group types.
  • $get_coverage() :returns as a real number in the range of 0 to 100 the overall coverage of all coverage group types. This number is computed as described above
    module test();
     
    logic [2:0] addr;
    wire [2:0] addr2;
     
    assign addr2 = addr + 1;
     
    covergroup address_cov;
      ADDRESS : coverpoint addr {
        option.auto_bin_max = 10;
      }
      ADDRESS2 : coverpoint addr2 {
        option.auto_bin_max = 10;
      }
    endgroup
     
    address_cov my_cov = new;
     
    initial begin
      // Set the database name
      $set_coverage_db_name("asic_world");
      $monitor("addr 8'h%x addr2 8'h%x",addr,addr2);
      repeat (10) begin
        addr = $urandom_range(0,7);
        my_cov.sample();
        #10;
      end
      // Get the final coverage
      $display("Total coverage %e",$get_coverage());
    end
     
    endmodule


免責聲明!

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



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