本記事はSystem Verilogのcovergroupの説明シリーズです。全体でかなりボリュームがあるため、以下に分割しています。上から順番に読んでいただくことをお勧めします。
今回はcoverpoint binsの書き方についてです。
autobin
カバレッジを収集したい変数、信号等をcoverpointで指定して、何もbinを指定しない場合は自動的にbinが生成されます。coverpointの対象が取りうる全ての値について一つ一つbinが生成されます。ただしデフォルトの最大値は64で、これを超えた場合はなるべく均等になるように64のbinに割り当てます。この数はoption.auto_bin_maxにより変更できます。coverpointの対象としては、信号や変数以外に演算の結果やfunctionの戻り値を指定することができます。またignore_binsを使用することで、その値に対するbinの生成を抑制することができます。
例ではそれぞれのcoverpointの末尾に;がついていたりついていなかったりでややこしいですが、個々のbinを指定しない場合は;をつける、binsを指定する場合は{bins = xxx}で終わらせ、;をつけないという法則になっています。
ignore_binsは特別なbinで、指定された範囲の値はcoverpointから除外されます。
rand logic [3:0] dat1;
rand logic [3:0] dat2;
rand enum logic [1:0] {red, yellow, green} flower;
function logic [2:0] fn();
return $urandom_range(7,0);
endfunction
...
abin_1: coverpoint dat1; // Automatic bins auto[0], ..., auto[15]
// Note that max number of bins is 64 by default.
// It can be changed by option.auto_bin_max property.
abin_2: coverpoint flower; // Automatic bins for enum.
// auto[red], auto[yellow], auto[green]
abin_3: coverpoint {1'b0, dat1} + {1'b0, dat2}; // Expressions can be coverpoint as well.
// Bins will be auto[0], ..., auto[31]
abin_4: coverpoint fn(); // Function return value can be a coverpoint.
// Type of return value of the function is logic [2:0] thus
// auto[0], ..., auto[7] will be created.
ign: coverpoint dat1 {
ignore_bins ign = {[0:7]}; // Value of 0 to 7 will be ignored. Thus bins of auto[8], ..., auto[15] will be generated
}
binを指定する
単独のbin
autobinに頼らず、対象coverpointの値毎にbinを定義することも可能です。この場合binの自動生成は行われず、指定したbinのみが生成されます。そのcoverpoint内のbinに指定されていない値は無視されます。また、一つのcoverpoint内でbinのカバー範囲は重なっていても構いません。その値がヒットした場合はどちらのbinもカウントされます。
- defaultをbinsの右辺に書くと、そのbinはそのcoverpoint内で他のbinでカバーされていないもの全てになります。ただしdefaultを使用したbinはカバレッジの母数に含まれなくなってしまいます。cross coverageの対象にもなりません。この制限のため、defaultにはあまり使い道が無いです。
- $は特別な文字で、[$:3]のように[]内の左側に書くと対象のcoverpointの変域の最小値を示します。同様に[4:$]のように[]内の右側に書くと対象のcoverpointの変域の最大値を示します。
- illegal_binsは特別なbin名で、そのbinに値がヒットした場合はエラーとなります
logic [3:0] dat1;
...
sbin_2: coverpoint dat1 {
// Bins can be defined in several styles. Note that bins can overlap
bins s = {1, 2, 3, 4}; // Bin s that covers 1, 2, 3, and 4
bins m = {[4:7]}; // Bin m that covers 4 to 7
bins l = {9, [10:$]}; // Bin l that covers 9 and 10 to maximum value
bins misc = default; // Values not covered in other bins, 0 and 8 in this case.
// However this bin will not be taken into account for the basement of total coverage
}
illegal: coverpoint dat1 {
illegal_bins ign = {[0:7]}; // Value of 0 to 7 is illegal
}
Array of bins
bin名に[]を付けるとarrayになります。対象となるcoverpointの変域に応じたbinが自動生成されます。この時のbin数の最大値はスペックには記述が見つかりませんでした。シミュレータ依存となっているようです。
[]の中に数字が入ると、その数だけbinが生成されます。値はなるべく均等になるように割り当てられます。
sbin_auto: coverpoint dat1 {
bins a[] = {[3:5]}; // Bins of a[3], a[4] and a[5] that cover the value of 3, 4 and 5 individually
bins b[] = {[1:3], 8}; // Bins of b[1], b[2], b[3], and b[8]
bins c[2] = {[3:5], 7}; // Bins of c[0] that covers 3, 4 and c[1] that covers 5, 7
}
ワイルドカード
wildcard binsではワイルドカードを使用することができます。?がワイルドカードの文字となります。
wbin: coverpoint dat1 {
wildcard bins even = {4'b???0}; // Wildcard is used. dat1 == {0, 2, 4, 6, 8, 10, 12, 14}
wildcard bins odd = {4'b???1}; // dat1 == {1, 3, 5, 7, 9, 11, 13, 15}
}
条件を満たしたときのみcoverageの取得を行う
iffで条件を満たしたときのみcoverageの取得を行うようにすることができます。coverpointとbins双方に付与することができます。iffの条件は信号や変数、functionの戻り値などが使用できます。
iffbin_1: coverpoint dat1 iff (cov_enable); // Conditional coverage collection. Collect coverage only when cov_enable = 1
iffbin_2: coverpoint dat1 iff (is_cov_enable()) { // Enable condition can be either a function or an expression
bins s = {[$:7]};
bins l = {[8:$]};
}
iffbin_3: coverpoint dat1 {
// Conditional coverage collection in bin basis
bins a = {[0:7]} iff (cov_enable); // Collect coverage for this bin of "a" only when cov_enable is true
bins b = {[8:15]}; // This bin will be always sampled
}
条件を満たしたときのみbinを生成する
binsの配列にwithを付与することで、with内の条件を満たしたときのみbinを生成するようにできます。 SV-2012からの機能なので、シミュレータによっては未サポートかもしれません。
cbin_1: coverpoint dat1 {
// Supported after SV-2012
// Conditionally generating bins.
// "item" is a reserved word that represents for coverage variable.
bins fizz[] = {[0:15]} with (item % 3 == 0); // fizz[0], fizz[3], ..., fizz[15]
bins buzz[] = cbin_1 with (item % 5 == 0); // Use coverpoint name (Here it is "cbin_1") to express the whole value space of this coverpoint.
// buzz[0], buzz[5], ..., buzz[15]
bins fizzBuzz[] = cbin_1 with (item % 3 == 0 && item % 5 == 0); // Bin fizzBuzz that covers the value of 0 and 15
}
#サンプルプログラム。
以上をまとめた、動作するプログラムが以下の通りです。
class MyTest;
rand logic [3:0] dat1;
rand logic [3:0] dat2;
rand logic cov_enable;
rand enum logic [1:0] {red, yellow, green} flower;
covergroup cg;
option.per_instance = 1;
abin_1: coverpoint dat1; // Automatic bins auto[0], ..., auto[15]
// Note that max number of bins is 64 by default.
// It can be changed by option.auto_bin_max property.
abin_2: coverpoint flower; // Automatic bins for enum.
// auto[red], auto[yellow], auto[green]
abin_3: coverpoint {1'b0, dat1} + {1'b0, dat2}; // Expressions can be coverpoint as well.
// Bins will be auto[0], ..., auto[31]
abin_4: coverpoint fn(); // Function return value can be a coverpoint.
// Type of return value of the function is logic [2:0] thus
// auto[0], ..., auto[7] will be created.
ign: coverpoint dat1 {
ignore_bins ign = {[0:7]}; // Value of 0 to 7 will be ignored. Thus bins of auto[8], ..., auto[15] will be generated
}
sbin_1: coverpoint dat1 {
// If bins are declared explicitly, automatic bin will not be generated
// In this example, only two bins that cover the value of 3 and 5 each are generated
bins three = {3};
bins five = {5};
}
sbin_2: coverpoint dat1 {
// Bins can be defined in several styles. Note that bins can overlap
bins s = {1, 2, 3, 4}; // Bin s that covers 1, 2, 3, and 4
bins m = {[4:7]}; // Bin m that covers 4 to 7
bins l = {9, [10:$]}; // Bin l that covers 9 and 10 to maximum value
bins misc = default; // Values not covered in other bins, 0 and 8 in this case.
// However this bin will not be taken into account for the basement of total coverage
}
sbin_auto: coverpoint dat1 {
bins a[] = {[3:5]}; // Bins of a[3], a[4] and a[5] that cover the value of 3, 4 and 5 individually
bins b[] = {[1:3], 8}; // Bins of b[1], b[2], b[3], and b[8]
bins c[2] = {[3:5], 7}; // Bins of c[0] that covers 3, 4 and c[1] that covers 5, 7
}
wbin: coverpoint dat1 {
wildcard bins even = {4'b???0}; // Wildcard is used dat1 == {0, 2, 4, 6, 8, 10, 12, 14}
wildcard bins odd = {4'b???1}; // dat1 == {1, 3, 5, 7, 9, 11, 13, 15}
}
iffbin_1: coverpoint dat1 iff (cov_enable); // Conditional coverage collection. Collect coverage only when cov_enable = 1
iffbin_2: coverpoint dat1 iff (is_cov_enable()) { // Enable condition can be either a function or an expression
bins s = {[$:7]};
bins l = {[8:$]};
}
iffbin_3: coverpoint dat1 {
// Conditional coverage collection in bin basis
bins a = {[0:7]} iff (cov_enable); // Collect coverage for this bin of "a" only when cov_enable is true
bins b = {[8:15]}; // This bin will be always sampled
}
cbin_1: coverpoint dat1 {
// Supported after SV-2012
// Conditionally generating bins.
// "item" is a reserved word that represents for coverage variable.
bins fizz[] = {[0:15]} with (item % 3 == 0); // fizz[0], fizz[3], ..., fizz[15]
bins buzz[] = cbin_1 with (item % 5 == 0); // Use coverpoint name (Here it is "cbin_1") to express the whole value space of this coverpoint.
// buzz[0], buzz[5], ..., buzz[15]
bins fizzBuzz[] = cbin_1 with (item % 3 == 0 && item % 5 == 0); // Bin fizzBuzz[0] and fizzBuss[15] that covers the value of 0 and 15
}
endgroup
function logic is_cov_enable();
return cov_enable;
endfunction
function logic [2:0] fn;
return $urandom_range(7, 0);
endfunction
function new();
cg = new;
endfunction
function void run();
for (int i = 0; i < 10; i++) begin
randomize();
cg.sample();
$display("cov_enable = %b, dat1 = %h, dat2 = %h", cov_enable, dat1, dat2);
end
endfunction
endclass
program top;
initial begin
MyTest myTest;
myTest = new;
myTest.run();
end
endprogram
実行結果のcoverageリポートを抜粋します。
+++++++++++++++++++++++++++++++++++++++++++++
++++++++++ DESIGN UNITS ++++++++++
+++++++++++++++++++++++++++++++++++++++++++++
CUMULATIVE SUMMARY
=============================================
| Coverage Type | Weight | Hits/Total |
=============================================
| Covergroup Coverage | 1 | 66.800% |
|---------------------|--------|------------|
| Types | | 0 / 1 |
=============================================
CUMULATIVE DESIGN-BASED COVERAGE: 66.800%
COVERED DESIGN UNITS: 0 / 1
FILES: 1
CLASS - work.MyTest
SUMMARY
=============================================
| Coverage Type | Weight | Hits/Total |
=============================================
| Covergroup Coverage | 1 | 66.800% |
|---------------------|--------|------------|
| Types | | 0 / 1 |
=============================================
WEIGHTED AVERAGE: 66.800%
COVERGROUP COVERAGE
======================================================================
| Covergroup | Hits | Goal / | Status |
| | | At Least | |
======================================================================
| TYPE /MyTest/cg | 66.800% | 100.000% | Uncovered |
======================================================================
| INSTANCE <UNNAMED1> | 66.800% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::abin_1 | 56.250% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin auto[0] | 0 | 1 | Zero |
| bin auto[1] | 1 | 1 | Covered |
| bin auto[2] | 1 | 1 | Covered |
| bin auto[3] | 1 | 1 | Covered |
| bin auto[4] | 0 | 1 | Zero |
| bin auto[5] | 0 | 1 | Zero |
| bin auto[6] | 1 | 1 | Covered |
| bin auto[7] | 1 | 1 | Covered |
| bin auto[8] | 1 | 1 | Covered |
| bin auto[9] | 0 | 1 | Zero |
| bin auto[10] | 0 | 1 | Zero |
| bin auto[11] | 0 | 1 | Zero |
| bin auto[12] | 2 | 1 | Covered |
| bin auto[13] | 1 | 1 | Covered |
| bin auto[14] | 1 | 1 | Covered |
| bin auto[15] | 0 | 1 | Zero |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::abin_2 | 100.000% | 100.000% | Covered |
|----------------------------------|----------|----------|-----------|
| bin auto[red] | 4 | 1 | Covered |
| bin auto[yellow] | 2 | 1 | Covered |
| bin auto[green] | 4 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::abin_3 | 28.125% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin auto[0] | 0 | 1 | Zero |
| bin auto[1] | 0 | 1 | Zero |
| bin auto[2] | 0 | 1 | Zero |
| bin auto[3] | 2 | 1 | Covered |
| bin auto[4] | 0 | 1 | Zero |
| bin auto[5] | 0 | 1 | Zero |
| bin auto[6] | 0 | 1 | Zero |
| bin auto[7] | 0 | 1 | Zero |
| bin auto[8] | 0 | 1 | Zero |
| bin auto[9] | 0 | 1 | Zero |
| bin auto[10] | 1 | 1 | Covered |
| bin auto[11] | 1 | 1 | Covered |
| bin auto[12] | 0 | 1 | Zero |
| bin auto[13] | 0 | 1 | Zero |
| bin auto[14] | 1 | 1 | Covered |
| bin auto[15] | 1 | 1 | Covered |
| bin auto[16] | 0 | 1 | Zero |
| bin auto[17] | 0 | 1 | Zero |
| bin auto[18] | 0 | 1 | Zero |
| bin auto[19] | 0 | 1 | Zero |
| bin auto[20] | 1 | 1 | Covered |
| bin auto[21] | 0 | 1 | Zero |
| bin auto[22] | 1 | 1 | Covered |
| bin auto[23] | 1 | 1 | Covered |
| bin auto[24] | 0 | 1 | Zero |
| bin auto[25] | 1 | 1 | Covered |
| bin auto[26] | 0 | 1 | Zero |
| bin auto[27] | 0 | 1 | Zero |
| bin auto[28] | 0 | 1 | Zero |
| bin auto[29] | 0 | 1 | Zero |
| bin auto[30] | 0 | 1 | Zero |
| bin auto[31] | 0 | 1 | Zero |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::abin_4 | 50.000% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin auto[0] | 0 | 1 | Zero |
| bin auto[1] | 0 | 1 | Zero |
| bin auto[2] | 1 | 1 | Covered |
| bin auto[3] | 5 | 1 | Covered |
| bin auto[4] | 0 | 1 | Zero |
| bin auto[5] | 1 | 1 | Covered |
| bin auto[6] | 0 | 1 | Zero |
| bin auto[7] | 3 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::ign | 50.000% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin auto[8] | 1 | 1 | Covered |
| bin auto[9] | 0 | 1 | Zero |
| bin auto[10] | 0 | 1 | Zero |
| bin auto[11] | 0 | 1 | Zero |
| bin auto[12] | 2 | 1 | Covered |
| bin auto[13] | 1 | 1 | Covered |
| bin auto[14] | 1 | 1 | Covered |
| bin auto[15] | 0 | 1 | Zero |
| ignore bin ign | 5 | - | Occurred |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::sbin_1 | 50.000% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin three | 1 | 1 | Covered |
| bin five | 0 | 1 | Zero |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::sbin_2 | 100.000% | 100.000% | Covered |
|----------------------------------|----------|----------|-----------|
| bin s | 3 | 1 | Covered |
| bin m | 2 | 1 | Covered |
| bin l | 4 | 1 | Covered |
| default bin misc | 1 | - | Occurred |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::sbin_auto | 77.777% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin a[3] | 1 | 1 | Covered |
| bin a[4] | 0 | 1 | Zero |
| bin a[5] | 0 | 1 | Zero |
| bin b[1] | 1 | 1 | Covered |
| bin b[2] | 1 | 1 | Covered |
| bin b[3] | 1 | 1 | Covered |
| bin b[8] | 1 | 1 | Covered |
| bin c[0] | 1 | 1 | Covered |
| bin c[1] | 1 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::wbin | 100.000% | 100.000% | Covered |
|----------------------------------|----------|----------|-----------|
| bin even | 6 | 1 | Covered |
| bin odd | 4 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::iffbin_1 | 31.250% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin auto[0] | 0 | 1 | Zero |
| bin auto[1] | 1 | 1 | Covered |
| bin auto[2] | 0 | 1 | Zero |
| bin auto[3] | 1 | 1 | Covered |
| bin auto[4] | 0 | 1 | Zero |
| bin auto[5] | 0 | 1 | Zero |
| bin auto[6] | 1 | 1 | Covered |
| bin auto[7] | 1 | 1 | Covered |
| bin auto[8] | 1 | 1 | Covered |
| bin auto[9] | 0 | 1 | Zero |
| bin auto[10] | 0 | 1 | Zero |
| bin auto[11] | 0 | 1 | Zero |
| bin auto[12] | 0 | 1 | Zero |
| bin auto[13] | 0 | 1 | Zero |
| bin auto[14] | 0 | 1 | Zero |
| bin auto[15] | 0 | 1 | Zero |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::iffbin_2 | 100.000% | 100.000% | Covered |
|----------------------------------|----------|----------|-----------|
| bin s | 4 | 1 | Covered |
| bin l | 1 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::iffbin_3 | 100.000% | 100.000% | Covered |
|----------------------------------|----------|----------|-----------|
| bin a | 4 | 1 | Covered |
| bin b | 5 | 1 | Covered |
|----------------------------------|----------|----------|-----------|
| COVERPOINT <UNNAMED1>::cbin_1 | 25.000% | 100.000% | Uncovered |
|----------------------------------|----------|----------|-----------|
| bin fizz[0] | 0 | 1 | Zero |
| bin fizz[3] | 1 | 1 | Covered |
| bin fizz[6] | 1 | 1 | Covered |
| bin fizz[9] | 0 | 1 | Zero |
| bin fizz[12] | 2 | 1 | Covered |
| bin fizz[15] | 0 | 1 | Zero |
| bin buzz[0] | 0 | 1 | Zero |
| bin buzz[5] | 0 | 1 | Zero |
| bin buzz[10] | 0 | 1 | Zero |
| bin buzz[15] | 0 | 1 | Zero |
| bin fizzBuzz[0] | 0 | 1 | Zero |
| bin fizzBuzz[15] | 0 | 1 | Zero |
======================================================================
EDA playgroundにプログラム一式があるので、実際に動作させることもできます。
covergroup bins
実行後にダウンロードされるファイルの中にあるcov.txtがカバレッジのリポートとなります。
参考文献
"19 Functional coverage". 1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language. pp.553-590.