LoginSignup
2
2

More than 5 years have passed since last update.

covergroup: その他の機能とtips

Last updated at Posted at 2018-08-16

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

  1. covergroupの記述方法
  2. covergroup: coverpoint binsの記述方法
  3. covergroup: cross binsの記述方法
  4. covergroup: その他の機能とtips

本記事ではSystem Verilogのcovergroupについて、他の一連の記事で触れることのできなかった項目について説明します。

配列に対するカバレッジ

ここでは配列に対するカバレッジの取り方を説明します。

以下の3 bitのlogicの配列であるdatのカバレッジを考えます。配列であるdatのそれぞれの要素のカバレッジを見ます。配列なのでcoverpointの対象として直接指定することはできません。

  localparam DAT_WIDTH = 3;
  rand logic [DAT_WIDTH - 1:0] dat [$];

対応するには、まずsample functionをオーバーライドして、datの一つの要素についてのcoverpointを作成します。sample functionはcovergroupが初めから持っているfunctionです。オーバーライドすることでサンプル時の動作を変更することができます。

  covergroup cg with function sample(logic [DAT_WIDTH - 1:0] v);
    option.per_instance = 1;
    cp: coverpoint v; // Automatic bins auto[0] ... auto[7]
  endgroup

そして、sampleメソッドを呼ぶときは、配列の要素方向にループさせます。

    foreach (dat[i]) begin
      cg.sample(dat[i]);
    end

これで配列の要素に対してのカバレッジを取ることができます。全体のプログラム例は以下の通りです。

class MyTest;
  localparam DAT_WIDTH = 3;

  rand logic [DAT_WIDTH - 1:0] dat [$];

  covergroup cg with function sample(logic [DAT_WIDTH - 1:0] v);
    option.per_instance = 1;
    cp: coverpoint v; // Automatic bins auto[0] ... auto[7]
  endgroup

  function new();
    cg = new;
  endfunction

  function void run();
    randomize() with {dat.size() inside {[10:20]};};

    foreach (dat[i]) begin
      $display("i = %d, dat = 0x%h", i, dat[i]);
      cg.sample(dat[i]);
    end
  endfunction
endclass

program top;
  initial begin
    MyTest myTest;

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

EDA Playgroundにソースコードがありますので、WEB browserから各自実行して結果を確かめることができます。実行後にダウンロードされるファイルの中のcov.txtがカバレッジリポートになります。
covergroup to array

functionの戻り値へのcoverpoint

functionの戻り値はlogicのベクタだけど、coverageはenumとして取りたい場合があります。特に困るのがenumの要素数とlogicベクタの要素数が一致していない場合です。以下の例だとenumでは3通りの値しかとらないのに、logic [1:0]では4通りの値になります。coverpointをlogicとして扱うと、使用しない値はignore_binでいちいち指定しないと絶対にカバーされないbinが生成されてしまいます(本例では3が絶対にカバーされない値)。

typedef enum logic [1:0] {ZERO, ONE, TWO} reg_t;

class RegClass;
  reg_t v;

  function logic [1:0] get;
    return v;
  endfunction
endclass

対応は簡単で、coverpointで指定する時に対象の型にキャスティングするだけです。

  covergroup cg;
    cp: coverpoint reg_t'(regClass.get());
  endgroup

UVMのRAL(Register Abstraction Layer)はget()での戻り値はデフォルトでは64ビットになっています。例えenable/disableのような1ビットのフィールドに対しても64ビット幅でデータが返ってきてしまいます。このようなモードビットのために、汎用のtypedefを定義しておくとcoverpointの定義が少し楽になります。

 typedef enum logic {FALSE, TRUE} boolean_t;

 covergroup cg;
    cp1: coverpoint uvm_reg_field_class.get(); // This coverpoint will generate bins for 64 bit space
    cp2: coverpoint boolean_t'(uvm_reg_field_class.get()); // Bin will be just FALSE and TRUE
 endgroup

以下がサンプルプログラム全体です。

typedef enum logic [1:0] {ZERO, ONE, TWO} reg_t;

class RegClass;
  rand reg_t v;

  function logic [1:0] get;
    return v;
  endfunction
endclass


class MyTest;
  RegClass regClass;

  covergroup cg;
    option.per_instance = 1;
    cp1: coverpoint regClass.get();
    cp2: coverpoint reg_t'(regClass.get());
  endgroup

  function new();
    cg = new;
    regClass = new;
  endfunction

  function void run();
    regClass.randomize();
    cg.sample();
  endfunction
endclass

program top;
  initial begin
    MyTest myTest;

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

以下がカバレッジレポートです。logic [1:0]をそのままcoverpointにしたcpではbinが4通りできていますが、reg_tにキャスティングした結果をcoverpointにしたcp2では、bin数は3になっています。

    COVERGROUP COVERAGE
    ===============================================================
    |         Covergroup         |  Hits   |  Goal /  |  Status   |
    |                            |         | At Least |           |
    ===============================================================
    | TYPE /MyTest/cg            | 29.166% | 100.000% | Uncovered |
    ===============================================================
    | INSTANCE <UNNAMED1>        | 29.166% | 100.000% | Uncovered |
    |----------------------------|---------|----------|-----------|
    | COVERPOINT <UNNAMED1>::cp1 | 25.000% | 100.000% | Uncovered |
    |----------------------------|---------|----------|-----------|
    | bin auto[0]                |       1 |        1 | Covered   |
    | bin auto[1]                |       0 |        1 | Zero      |
    | bin auto[2]                |       0 |        1 | Zero      |
    | bin auto[3]                |       0 |        1 | Zero      |
    |----------------------------|---------|----------|-----------|
    | COVERPOINT <UNNAMED1>::cp2 | 33.333% | 100.000% | Uncovered |
    |----------------------------|---------|----------|-----------|
    | bin auto[ZERO]             |       1 |        1 | Covered   |
    | bin auto[ONE]              |       0 |        1 | Zero      |
    | bin auto[TWO]              |       0 |        1 | Zero      |
    ===============================================================

EDA Playgroundにソースコードがありますので、WEB browserから各自実行して結果を確かめることができます。実行後にダウンロードされるファイルの中のcov.txtがカバレッジリポートになります。
covergroup type cast

参考文献

"19 Functional coverage". 1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language. pp.553-590.

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2