文章目錄
- 一、交叉覆寫率
-
- 1、基本的交叉覆寫率的例子
- 2、對交叉覆寫倉進行标号
- 3、排除掉部分交叉覆寫倉
- 4、從總體覆寫率的度量中排除掉部分覆寫率
- 5、從多個值域中合并資料
- 6、交叉覆寫的替代方式
- 二、通用的覆寫組
-
- 1、通過數值傳遞覆寫組參數
- 2、通過引用傳遞覆寫組參數
- 三、覆寫選項
-
- 1、單個執行個體的覆寫率
- 2、覆寫組的注釋
- 3、覆寫門檻值
- 4、列印空倉
- 5、覆寫率目标
- 四、覆寫率資料的分析
- 五、在仿真過程中進行覆寫率統計
一、交叉覆寫率
覆寫點記錄的是單個變量或者表達式的觀測值,而交叉覆寫率可以同時測量兩個或者兩個以上覆寫點的值。若其中一個有N種取值,另個一有M種取值,則SV需要N*M個交叉倉來存儲所有的組合。
1、基本的交叉覆寫率的例子
SV中的cross結構可以用來記錄一個組裡兩個或兩個以上覆寫點的組合值。但是即使每個覆寫點都達到了100%的覆寫率,交叉組合可能會達不到100%。
基本的交叉覆寫率
/*
在tr.kind和tr.port上建立了覆寫點,然後這兩個點便交叉顯示出各種組合。
SV總共建立了128(8*16)個倉。
*/
class Transaction;
rand bit[3:0] kind;
rand bit[2:0] port;
endclass
Transaction tr;
covergroup CovPort;
kind: coverpoint tr.kind; //建立覆寫點kind
port: coverpoint tr.port; //建立覆寫點port
cross kind,port; //把kind和port交叉
endgroup
2、對交叉覆寫倉進行标号
指定交叉覆寫倉的名稱
covergroup CovPortKind;
port: coverpoint tr.port{
bins port[] = {0:$};
}
kind: coverpoint tr.kind{
bins zero = {0}; //一個倉zero,對kind采樣值為0進行計數
bins lo = {[1:3],5}; //lo倉代表1:3和5的值
bins hi[] = {[8:$]}; //8個獨立的倉8-15,分别儲存
bins misc = default; //一個倉用來儲存沒有被選中的值
}
cross kind,port;
endgroup
3、排除掉部分交叉覆寫倉
== 在交叉覆寫中,可以使用binof和intersect分别指定覆寫點和數值集,這樣可以使用單個的ignore_bins結構清除掉個體倉。==
在交叉覆寫中排除掉部分bin
covergroup CovPort;
port: coverpoint tr.port{
bins port[] = {0:$};
}
kind: coverpoint tr.kind{
bins zero = {0}; //一個倉zero,對kind采樣值為0進行計數
bins lo = {[1:3],5}; //lo倉代表1:3和5的值
bins hi[] = {[8:$]}; //8個獨立的倉8-15,分别儲存
bins misc = default; //一個倉用來儲存沒有被選中的值
}
cross kind,port{
ignore_bins hi = binof(port) intersect {7}; //排除掉了所有代表port為7和任意kind值組合的倉
ignore_bins md = binof(port) intersect {0} && //排除掉了port為0和kind為9、10、11的組合,共3個倉。
binof(kind) intersect {[9:11]};
ignore_bins lo = binof(kind.lo); //使用倉名排除掉了整個倉
}
endgroup
4、從總體覆寫率的度量中排除掉部分覆寫率
指明交叉覆寫率的權重
covergroup CovPort;
port: coverpoint tr.port{
bins port[] = {0:$};
options.weight = 0; //不占任何分量
}
kind: coverpoint tr.kind{
bins zero = {0}; //一個倉zero,對kind采樣值為0進行計數
bins lo = {[1:3],5}; //lo倉代表1:3和5的值
bins hi[] = {[8:$]}; //8個獨立的倉8-15,分别儲存
bins misc = default; //一個倉用來儲存沒有被選中的值
options.weight = 5; //在總體中所占比重
}
cross kind,port{
options.weight = 10; //給予交叉更高的權重
}
endgroup
5、從多個值域中合并資料
交叉覆寫的一個問題就是,可能需要從不同的時間域裡采樣資料。可以拷貝信号到臨時變量中,然後在一個新的覆寫組裡對它們進行采樣,這個新的覆寫組可以用于計算交叉覆寫率。
6、交叉覆寫的替代方式
使用倉名的交叉覆寫率
//覆寫點都有事先定義好的倉的情況
class Transaction;
rand bit a,b;
endclass
covergroup CrossBinNames;
a: coverpoint tr.a{
bins a0 = {0};
bins a1 = {1};
options.weight = 0;
}
b: coverpoint tr.b{
bins b0 = {0};
bins b1 = {1};
options.weight = 0;
}
ab: cross a,b{
bins a0b0 = binsof(a.a0) && binsof(b.b0);
bins a1b0 = binsof(a.a1) && binsof(b.b0);
bins b1 = binsof(b.b1);
}
endgroup
使用binsof的交叉覆寫率
//覆寫點沒有事先定義好的倉的情況
class Transaction;
rand bit a,b;
endclass
covergroup CrossBinofIntersect;
a: coverpoint tr.a{
options.weight = 0;
}
b: coverpoint tr.b{
options.weight = 0;
}
ab: cross a,b{
bins a0b0 = binsof(a) intersect {0} && binsof(b) intersect {0};
bins a1b0 = binsof(a) intersect {1} && binsof(b) intersect {0};
bins b1 = binsof(b) intersect {1};
}
endgroup
使用串聯值來替代交叉覆寫
//最簡潔的格式
covergroup CrossManual;
ab: coverpoint {tr.a, tr.b}
{
bins a0b0 = {2'b00};
bins a1b0 = {2'b10};
wildcard bins b1 = {2'b? 1};
}
endgroup
二、通用的覆寫組
1、通過數值傳遞覆寫組參數
bit[2:0] port;
covergroup CoverPort(int mid);
coverpoint port{
bins lo = {[0:mid-1]};
bins hi = {[mid:$]};
}
endgroup
CoverPort cp;
initial begin
cp = new(5);
...
end
2、通過引用傳遞覆寫組參數
bit[2:0] port_a, port_b;
covergroup CoverPort(ref bit[2:0] port, input int mid);
coverpoint port{
bins lo = {[0:mid-1]};
bins hi = {[mid:$]};
}
endgroup
CoverPort cpa, cpb;
initial begin
cpa = new(port_a,4);
cpb = new(port_b,2);
三、覆寫選項
1、單個執行個體的覆寫率
指定單個執行個體(per-instance)的覆寫率
covergroup CoverLength;
coverpoint tr.length;
option.per_instance = 1; //per_instance隻能放在覆寫組裡,不能用于覆寫點或交叉點
option.comment = $psprintf("%m"); //在注釋comment中使用階層化路徑
endgroup
2、覆寫組的注釋
為一個覆寫組指定注釋
covergroup CoverPort;
type_option.comment = "comment";
coverpoint port;
endgroup
為單個覆寫組執行個體指定注釋
covergroup CovPort(int lo,hi, string comment);
option.comment = comment;
option.per_instance = 1;
coverpoint port{
bins range = {[lo:hi]};
}
endgroup
...
CoverPort cp_lo = new(0,3,"low");
CoverPort cp_hi = new(4,7,"high");
3、覆寫門檻值
你的設計可能沒有足夠的可見度以至于不能收集到穩健的覆寫率資訊,隻有在确實無法直接測量覆寫率的情況下可以使用option.at_least。如果option.at_least定義在覆寫組裡,将會作用于所有的覆寫點,如果定義在一個點上,隻會對該點有效。
4、列印空倉
預設的情況下,覆寫率報告隻會給出帶有采樣值得倉。使用cross_num_print_missing選項可以給出所有的倉,尤其是那些沒有被命中的倉。
5、覆寫率目标
指定覆寫率目标
3、覆寫門檻值
你的設計可能沒有足夠的可見度以至于不能收集到穩健的覆寫率資訊,隻有在确實無法直接測量覆寫率的情況下可以使用option.at_least。如果option.at_least定義在覆寫組裡,将會作用于所有的覆寫點,如果定義在一個點上,隻會對該點有效。
4、列印空倉
預設的情況下,覆寫率報告隻會給出帶有采樣值得倉。使用cross_num_print_missing選項可以給出所有的倉,尤其是那些沒有被命中的倉。
5、覆寫率目标
指定覆寫率目标
covergroup CoverPort;
coverpoint port;
option.goal = 90;
endgroup
四、覆寫率資料的分析
事務長度的原始類
class Transaction;
rand bit[2:0] hdr_len;
rand bit[3:0] payload_len;
rand bit[4:0] len;
constraint length {
len == hdr_len + payload_len;
}
endclass
這個類len同時受到兩個長度之和的限制,len值得分布并不均勻。
可以使用solve…before限制
class Transaction;
rand bit[2:0] hdr_len;
rand bit[3:0] payload_len;
rand bit[4:0] len;
constraint length {
len == hdr_len + payload_len;
solve len before hdr_len,payload_len;
}
endclass
五、在仿真過程中進行覆寫率統計
使用$get_coverage可以得到所有覆寫組的總覆寫率。
使用get_coverage(),可以帶覆寫組名和執行個體,用于給出一個覆寫組所有執行個體的覆寫率。
使用get_inst_coverage(),可以傳回一個特定覆寫組執行個體的覆寫率。
這些函數最實際的用處是在一個長測試中監測覆寫率,如果覆寫率水準在給定數量的事務或周期之後 并無提高,那麼這個測試就應該停止,重新開機新的種子或測試可能有希望提高覆寫率。驗證團隊可以建立自己的SQL資料庫,用來收集從仿真中得到的覆寫率資料。有些形式驗證工具能夠提取設計狀态并建立輸入激勵去測試所有可能的狀态。
————————————————
版權聲明:本文為CSDN部落客「煎丶包」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/qq_39794062/article/details/113621744