covergroup: cross binsの記述方法

本記事はSystem Verilogのcovergroupの説明シリーズです。全体でかなりボリュームがあるため、以下に分割しています。上から順番に読んでいただくことをお勧めします。

1. [covergroupの記述方法](https://qiita.com/triggerfish/items/6053d93d99e084e8976f)
* [covergroup: coverpoint binsの記述方法](https://qiita.com/triggerfish/items/5766e890f1d108693a3f)
* [covergroup: cross binsの記述方法](https://qiita.com/triggerfish/items/d2feca30d05e51d3f93b)
* [covergroup: その他の機能とtips](https://qiita.com/triggerfish/items/39ee2ded512fa3df2974)

本記事ではSystem Verilogのcovergroupのcross binについて説明します。
本機能については、シミュレータがどこまでサポートしているかまちまちのため、主要なシミュレータがサポートしている基本的な機能のみについて説明します。

# cross binの作り方
crossの後に対象となる変数やbinを記述するだけで、cross binが生成されます。下記例ではそれぞれall\_dats, all\_bins, dat\_binsという名前で3つのcross binを生成しています。

```verilog
logic [1:0]  dat1;
logic [1:0]  dat2;


covergroup cg;
  bin1: coverpoint dat1 {
    bins s = {[0:1]};
    bins l = {[2:3]};
  }

  bin2: coverpoint dat2 {
    bins s = {[0:1]};
    bins l = {[2:3]};
  }

  all_dats: cross dat1, dat2; // All combinations of dat1 x dat2, that is 16 combinations.
  all_bins: cross bin1, bin2; // All combinations of bin1 x bin2, that is 4 combinations.
  dat_bin: cross dat1, bin2;  // variable x bin, 8 combinations.
endcovergroup
```
# binsof
cross binでは、binsofによりbinを集約して総数を減らすことができます。

## binsofの機能
binsofにbinを指定した場合、そのbinにマッチするものは全てを一つのbinとして扱います。下記例では、bin1.sにマッチする組み合わせは全てをbin\_sとしています。dat2の値にかかわらず、bin1.sにマッチするものが全て一つのbinになります。**この時cross binのbinsでカバーされない組み合わせについてはbinが自動生成されます**。この点はcoverpointと挙動が違いますので注意してください。coverpointではbinsで指定していない範囲はbinが自動生成されることはありません。

```verilog
logic [1:0]  dat1;
logic [1:0]  dat2;

covergroup cg;
  bin1: coverpoint dat1 {
    bins s = {[0:1]};
    bins l = {[2:3]};
  }

  cbins_v: cross bin1, dat2 {
    bins bin_s = binsof(bin1.s); // A bin covers all combinations below:
                                 // <s, 0>, <s, 1>, <s, 2>, <s, 3>
  // Bins will be automatically created for the combinations below
  // <l, 0>, <l, 1>, <l, 2>, <l, 3>
  }
endcovergroup
```

##binsof同士の論理演算

binsof同士で論理演算を取ったものをcross binとすることが可能です。&&, ||, !, ()が使用可能です。

```verilog
  logic [1:0]  dat1;
  logic [1:0]  dat2;

  covergroup cg;
    option.per_instance = 1;

    bin1: coverpoint dat1 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    bin2: coverpoint dat2 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    useOfBinsof: cross bin1, bin2 {
      bins bin1_is_s = binsof(bin1.s);                                         // <s, s>, <s.l>
      bins bin_s_and_s = binsof(bin1.s) && binsof(bin2.s);                     // <s, s>
      bins bin_s_or_s  = binsof(bin1.s) || binsof(bin2.s);                     // <s, s>, <s, l>, <l, s>
      bins bin_not_l   = !binsof(bin1.l);                                      // <s, s>, <s, l>
      bins bin_paren   = (binsof(bin1.s) || binsof(bin2.s)) && binsof(bin2.l); // <s, l>
      // Bins for the combinations that are not specified will be generated automatically.
      // <l, l>
    }
```

## intersect
上記の例はcoverpointのbinを対象にcross binを作成しましたが、値を直接指定してcross binを作ることも可能です。その機能がintersectです。

### intersectの対象がcoverpointのbinの場合
coverpointのbinでなく、値でcross binを定義することができます。以下の書式になります。
bins _bin\_name_ = binsof (_bin\_name_) intersect(_range_);
この場合まず_range_に対応するcoverpoint binが抽出され、それに対して集約されたcross binが生成されます。以下の例のcbin\_b\_0の場合、bin1ではintersectで0が指定されていますが、dat1が0となるcoverpoint bin名はsとなります。従ってbin1がsの時の全ての組み合わせが集約され、{s, s}と{s, l}の組み合わせが対象になります。cbin\_b\_1の場合でも対象となるbin1のbinはsのみなので同じ結果となります。一方cbin\_b\_2の場合は対象となるbin1のbinがs, l両方になるので全ての組み合わせが一つのbinに集約されます。

```verilog
  covergroup cg;
    bin1: coverpoint dat1 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    bin2: coverpoint dat2 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    cbins_b_0: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {0}; // <s, s>, <s, l>
      // <l, s>, <l, l>
    }

    cbins_b_1: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {[0:1]}; // <s, s>, <s, l>
      // <l, s>, <l, l>
    }

    cbins_b_2: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {[0:2]}; // <s, s>, <s, l>, <l, s>, <l, l>
      // No auto bin
    }
  endgroup
```

### intersectの対象が変数や信号、functionの戻り値の場合
bins _bin\_name_ = binsof (_variable_) intersect(_range_);
全組み合わせのうち、_variable_で指定した変数(または信号、functionの戻り値等)が_range_を一つのbinとして集約します。

```verilog
  logic [1:0]  dat1;
  logic [1:0]  dat2;

  covergroup cg;
    cbins_v: cross dat1, dat2 {
      bins bin1_0 = binsof(dat1) intersect {[0:2]}; // A bin covers all combinations below:
                                                    // <0, 0>, <0, 1>, <0, 2>, <0, 3>
                                                    // <1, 0>, <1, 1>, <1, 2>, <1, 3>
                                                    // <2, 0>, <2, 1>, <2, 2>, <2, 3>
      // Bins will be automatically created for the combinations below
      // <3, 0>, <3, 1>, <3, 2>, <3, 3>
    }
  endgroup
```

# ignore_bin
不必要なbinはignore\_binに指定することで、coverageのカウントから外すことができます。

```verilog

    useOfIgn: cross dat1, dat2 {
      ignore_bins ign = binsof (dat1) intersect {[0:2]} ||   //<0, 0>, <0, 1>, <0, 2>, <0, 3>,
                        binsof (dat2) intersect {[0:1]};     //<1, 0>, <1, 1>, <1, 2>, <1, 3>,
                                                             //<2, 0>, <2, 1>, <2, 2>, <2, 3>,
                                                             //<3, 0>, <3, 1>
      // Automatically Created cross bins
      // <3, 2>, <3, 3>
    }
```

# 条件に一致した時のみサンプリング
coverpointと同様にcross binでもiffを使用して、cross binまたはその中の個々のbinに対して、条件に一致した時のみカバレッジのサンプリングを行うように指定できます。

```verilog
    cond1: cross bin1, bin2 iff (face == front); // Collect coverage only when face == front

    cond2: cross bin1, bin2 {
      bins bin1s = binsof(bin1.s) iff (face == front); // Collect coverage only when face == front
      // Other bins are always collected
    }
```


以下の動作はスペックに記述が見つかりませんでしたが、crossの要素となるcoverpointにiffが使用されている場合、crossの要素となっているいずれかのcoverpointがサンプリングされない時はそのcrossカバレッジもサンプリングされないようです。調べた限りどのシミュレーターでも同じ動作でした。
cond3はbins\_cndのサンプリングが行われない時は (face != frontの時は)サンプリングが行われません。
cond4はbins\_cnd2のbin zeroのサンプリングが行われ無い時は (dat1 == 0 && face != front の時は)サンプリングが行われません。

```verilog
  logic [1:0] dat1;
  logic [1:0] dat2;
  rand face_t face;

  covergroup cg;
    bins_cnd1: coverpoint dat1 iff (face == front);

    bins_cnd2: coverpoint dat1 {
      bins zero = {0} iff (face == front);
      bins int_num[] = {[1:$]};
    }

    cond3: cross bins_cnd1, dat2;

    cond4: cross bins_cnd2, dat2;
  endgroup
```

# サンプルプログラム
以下が今までの説明をまとめたサンプルプログラムです。

```verilog
class MyTest;
  typedef enum logic {front, back} face_t;

  logic [1:0]  dat1;
  logic [1:0]  dat2;
  rand face_t face;

  covergroup cg;
    option.per_instance = 1;

    bin1: coverpoint dat1 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    bin2: coverpoint dat2 {
      bins s = {[0:1]};
      bins l = {[2:3]};
    }

    bins_cnd1: coverpoint dat1 iff (face == front);

    bins_cnd2: coverpoint dat1 {
      bins zero = {0} iff (face == front);
      bins int_num[] = {[1:$]};
    }

    all_dats: cross dat1, dat2;                 // All combinations of dat1 x dat2, that is 16 combinations.

    all_bins: cross bin1, bin2;                 // All combinations of bin1 x bin2, that is 4 combinations.

    dat_bin: cross dat1, bin2;                  // Combination of variable x bin

    useOfBinsof: cross bin1, bin2 {
      bins bin1_is_s = binsof(bin1.s);                                         // <s, s>, <s.l>
      bins bin_s_and_s = binsof(bin1.s) && binsof(bin2.s);                     // <s, s>
      bins bin_s_or_s  = binsof(bin1.s) || binsof(bin2.s);                     // <s, s>, <s, l>, <l, s>
      bins bin_not_l   = !binsof(bin1.l);                                      // <s, s>, <s, l>
      bins bin_paren   = (binsof(bin1.s) || binsof(bin2.s)) && binsof(bin2.l); // <s, l>
      // Bins for the combinations that are not specified will be generated automatically.
      // <l, l>
    }

    cbins_v: cross dat1, dat2 {
      bins bin1_0 = binsof(dat1) intersect {[0:2]}; // A bin covers all combinations below:
                                                    // <0, 0>, <0, 1>, <0, 2>, <0, 3>
                                                    // <1, 0>, <1, 1>, <1, 2>, <1, 3>
                                                    // <2, 0>, <2, 1>, <2, 2>, <2, 3>
    // Bins will be automatically created for the combinations below
    // <3, 0>, <3, 1>, <3, 2>, <3, 3>
    }

    cbins_b_0: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {0}; // Equivalent to binsof(bin1.s)
                                              // <s, s>, <s, l>
      // <l, s>, <l, l>
    }

    cbins_b_1: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {[0:1]}; // Equivalent to binsof(bin1.s)
                                                  // <s, s>, <s, l>
      // <l, s>, <l, l>
    }

    cbins_b_2: cross bin1, bin2 {
      bins bin0 = binsof(bin1) intersect {[0:2]}; // Equivalent to binsof(bin1.s) || binsof(bin1.l)
                                                  // <s, s>, <s, l>, <l, s>, <l, l>
      // No auto bin
    }

    useOfIgn: cross dat1, dat2 {
      ignore_bins ign = binsof (dat1) intersect {[0:2]} ||   //<0, 0>, <0, 1>, <0, 2>, <0, 3>,
                        binsof (dat2) intersect {[0:1]};     //<1, 0>, <1, 1>, <1, 2>, <1, 3>,
                                                             //<2, 0>, <2, 1>, <2, 2>, <2, 3>,
                                                             //<3, 0>, <3, 1>
      // Automatically Created cross bins
      // <3, 2>, <3, 3>
    }

    cond1: cross bin1, bin2 iff (face == front); // Collect coverage only when face == front

    cond2: cross bin1, bin2 {
      bins bin1s = binsof(bin1.s) iff (face == front); // Collect coverage only when face == front
      // Other bins are always collected
    }

    cond3: cross bins_cnd1, dat2; //bins_cnd1 has iff

    cond4: cross bins_cnd2, dat2; //bins_cnd2 has a bin with iff
  endgroup

  function new();
    cg = new;
  endfunction

  function void run();
    for (int i = 0; i < 2**$size(dat1); i++) begin
      for (int j = 0; j < 2**$size(dat2); j++) begin
        for (int k = 0; k < 2**$size(face); k++) begin
          dat1 = i;
          dat2 = j;
          face = face_t'(k);
          cg.sample();
        end
      end
    end
  endfunction
endclass

program top;
  initial begin
    MyTest myTest;

    myTest = new;
    myTest.run();
  end
endprogram
```

以下がカバレッジレポートの抜粋となります。

```plaintext

CLASS - /MyTest : work.MyTest


    SUMMARY
    =============================================
    |    Coverage Type    | Weight | Hits/Total |
    =============================================
    | Covergroup Coverage |      1 |   100.000% |
    |---------------------|--------|------------|
    | Types               |        |      1 / 1 |
    =============================================
    WEIGHTED AVERAGE LOCAL:  100.000%


    COVERGROUP COVERAGE
    =====================================================================
    |            Covergroup            |   Hits   |  Goal /  |  Status  |
    |                                  |          | At Least |          |
    =====================================================================
    | TYPE /MyTest/cg                  | 100.000% | 100.000% | Covered  |
    =====================================================================
    | INSTANCE <UNNAMED1>              | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::bin1      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin s                            |       16 |        1 | Covered  |
    | bin l                            |       16 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::bin2      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin s                            |       16 |        1 | Covered  |
    | bin l                            |       16 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::bins_cnd1 | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin auto[0]                      |        4 |        1 | Covered  |
    | bin auto[1]                      |        4 |        1 | Covered  |
    | bin auto[2]                      |        4 |        1 | Covered  |
    | bin auto[3]                      |        4 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::bins_cnd2 | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin zero                         |        4 |        1 | Covered  |
    | bin int_num[1]                   |        8 |        1 | Covered  |
    | bin int_num[2]                   |        8 |        1 | Covered  |
    | bin int_num[3]                   |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::dat1      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin auto[0]                      |        8 |        1 | Covered  |
    | bin auto[1]                      |        8 |        1 | Covered  |
    | bin auto[2]                      |        8 |        1 | Covered  |
    | bin auto[3]                      |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | COVERPOINT <UNNAMED1>::dat2      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin auto[0]                      |        8 |        1 | Covered  |
    | bin auto[1]                      |        8 |        1 | Covered  |
    | bin auto[2]                      |        8 |        1 | Covered  |
    | bin auto[3]                      |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::all_dats       | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <auto[0],auto[0]>            |        2 |        1 | Covered  |
    | bin <auto[0],auto[1]>            |        2 |        1 | Covered  |
    | bin <auto[0],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[0],auto[3]>            |        2 |        1 | Covered  |
    | bin <auto[1],auto[0]>            |        2 |        1 | Covered  |
    | bin <auto[1],auto[1]>            |        2 |        1 | Covered  |
    | bin <auto[1],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[1],auto[3]>            |        2 |        1 | Covered  |
    | bin <auto[2],auto[0]>            |        2 |        1 | Covered  |
    | bin <auto[2],auto[1]>            |        2 |        1 | Covered  |
    | bin <auto[2],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[2],auto[3]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[0]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[1]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[3]>            |        2 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::all_bins       | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <s,s>                        |        8 |        1 | Covered  |
    | bin <s,l>                        |        8 |        1 | Covered  |
    | bin <l,s>                        |        8 |        1 | Covered  |
    | bin <l,l>                        |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::dat_bin        | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <auto[0],s>                  |        4 |        1 | Covered  |
    | bin <auto[0],l>                  |        4 |        1 | Covered  |
    | bin <auto[1],s>                  |        4 |        1 | Covered  |
    | bin <auto[1],l>                  |        4 |        1 | Covered  |
    | bin <auto[2],s>                  |        4 |        1 | Covered  |
    | bin <auto[2],l>                  |        4 |        1 | Covered  |
    | bin <auto[3],s>                  |        4 |        1 | Covered  |
    | bin <auto[3],l>                  |        4 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::useOfBinsof    | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <l,l>                        |        8 |        1 | Covered  |
    | bin bin1_is_s                    |       16 |        1 | Covered  |
    | bin bin_s_and_s                  |        8 |        1 | Covered  |
    | bin bin_s_or_s                   |       24 |        1 | Covered  |
    | bin bin_not_l                    |       16 |        1 | Covered  |
    | bin bin_paren                    |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cbins_v        | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <auto[3],auto[0]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[1]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[3]>            |        2 |        1 | Covered  |
    | bin bin1_0                       |       24 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cbins_b_0      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <l,s>                        |        8 |        1 | Covered  |
    | bin <l,l>                        |        8 |        1 | Covered  |
    | bin bin0                         |       16 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cbins_b_1      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <l,s>                        |        8 |        1 | Covered  |
    | bin <l,l>                        |        8 |        1 | Covered  |
    | bin bin0                         |       16 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cbins_b_2      | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin bin0                         |       32 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::useOfIgn       | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <auto[3],auto[2]>            |        2 |        1 | Covered  |
    | bin <auto[3],auto[3]>            |        2 |        1 | Covered  |
    | ignore bin ign                   |       28 |    -     | Occurred |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cond1          | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <s,s>                        |        4 |        1 | Covered  |
    | bin <s,l>                        |        4 |        1 | Covered  |
    | bin <l,s>                        |        4 |        1 | Covered  |
    | bin <l,l>                        |        4 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cond2          | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <l,s>                        |        8 |        1 | Covered  |
    | bin <l,l>                        |        8 |        1 | Covered  |
    | bin bin1s                        |        8 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cond3          | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <auto[0],auto[0]>            |        1 |        1 | Covered  |
    | bin <auto[0],auto[1]>            |        1 |        1 | Covered  |
    | bin <auto[0],auto[2]>            |        1 |        1 | Covered  |
    | bin <auto[0],auto[3]>            |        1 |        1 | Covered  |
    | bin <auto[1],auto[0]>            |        1 |        1 | Covered  |
    | bin <auto[1],auto[1]>            |        1 |        1 | Covered  |
    | bin <auto[1],auto[2]>            |        1 |        1 | Covered  |
    | bin <auto[1],auto[3]>            |        1 |        1 | Covered  |
    | bin <auto[2],auto[0]>            |        1 |        1 | Covered  |
    | bin <auto[2],auto[1]>            |        1 |        1 | Covered  |
    | bin <auto[2],auto[2]>            |        1 |        1 | Covered  |
    | bin <auto[2],auto[3]>            |        1 |        1 | Covered  |
    | bin <auto[3],auto[0]>            |        1 |        1 | Covered  |
    | bin <auto[3],auto[1]>            |        1 |        1 | Covered  |
    | bin <auto[3],auto[2]>            |        1 |        1 | Covered  |
    | bin <auto[3],auto[3]>            |        1 |        1 | Covered  |
    |----------------------------------|----------|----------|----------|
    | CROSS <UNNAMED1>::cond4          | 100.000% | 100.000% | Covered  |
    |----------------------------------|----------|----------|----------|
    | bin <zero,auto[0]>               |        1 |        1 | Covered  |
    | bin <zero,auto[1]>               |        1 |        1 | Covered  |
    | bin <zero,auto[2]>               |        1 |        1 | Covered  |
    | bin <zero,auto[3]>               |        1 |        1 | Covered  |
    | bin <int_num[1],auto[0]>         |        2 |        1 | Covered  |
    | bin <int_num[1],auto[1]>         |        2 |        1 | Covered  |
    | bin <int_num[1],auto[2]>         |        2 |        1 | Covered  |
    | bin <int_num[1],auto[3]>         |        2 |        1 | Covered  |
    | bin <int_num[2],auto[0]>         |        2 |        1 | Covered  |
    | bin <int_num[2],auto[1]>         |        2 |        1 | Covered  |
    | bin <int_num[2],auto[2]>         |        2 |        1 | Covered  |
    | bin <int_num[2],auto[3]>         |        2 |        1 | Covered  |
    | bin <int_num[3],auto[0]>         |        2 |        1 | Covered  |
    | bin <int_num[3],auto[1]>         |        2 |        1 | Covered  |
    | bin <int_num[3],auto[2]>         |        2 |        1 | Covered  |
    | bin <int_num[3],auto[3]>         |        2 |        1 | Covered  |
    =====================================================================
```

EDA Playgroundにソースコードがありますので、WEB browserから各自実行して結果を確かめることができます。実行後にダウンロードされるファイルの中のcov.txtがカバレッジリポートになります。
[covergroup cross coverage samlpe] (https://www.edaplayground.com/x/2xD8)

# 参考文献
 "19 Functional coverage". [1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language](https://doi.org/10.1109/IEEESTD.2018.8299595). pp.553-590.