如何在systemverilog中编写过渡的覆盖点?

时间:2015-09-19 01:08:59

标签: verilog system-verilog

我的RTL设计中有一个N位寄存器,我想检查testbench是否覆盖了以下特定情况 -

000..0 - > 000..001 - > 000 .... 011 - > 00 ... 111 - > ...... - > 111 .... 111

我不确定如何为上面写封面组。我可以看到过渡覆盖如何有用。举个例子:

covergroup cg; 
cover_point_y : coverpoint y { 
bins tran_34 = (3=>4); 
bins tran_56 = (5=>6); 
} 

然而在我的情况下,我的寄存器是paraterized(N位:reg [(N-1):0])并且它太大而无法手动写入完整序列。我可以编写一个generate或for循环来覆盖我想看到的上述序列吗?

3 个答案:

答案 0 :(得分:3)

我不清楚你要覆盖哪些过渡。我想你想要涵盖每个值都改为其他每个值。您需要记住的是,您可以在=>运算符的任意一侧写入多个值。例如:

cover_point_y : coverpoint y { 
  bins transitions = ( 0, 1 => 0, 1 );
}

这会为0 => 00 => 11 => 01 => 1创建容器。如果我正确解释了BNF,根据LRM,您放在=>运算符任一侧的值都是covergroup_value_range类型,这意味着应该接受覆盖点的任何值范围语法。这意味着以下内容也应该是合法的:

cover_point_y : coverpoint y { 
  bins transitions = ( [0 : 2^N - 1] => [0 : 2^N - 1] );
}

这应该从每个值到每个其他值创建转换箱。你在这里受到工具支持的支配。例如,这在我的模拟器中不起作用,但它可能在其他模拟器中有效。

如果你想排除某些转换(例如,0 => 01 => 1等),这无论如何都无济于事,因为指定转换箱的语法不够表达...

不要担心,有办法做到这一点。回到基础,过渡覆盖基本上是当前值和过去值之间的交叉覆盖形式。交叉覆盖允许更多种方式来指定容器。您需要跟踪您所覆盖的变量的先前值。你需要注意的是,你应该只在采样至少2个值后开始收集覆盖率(这样你就有了之前的值)。通过过渡覆盖,该工具可以在幕后为您完成此任务。

我能想到的最好的方法是将covergroup包装在一个类中:

class cg_wrapper #(int unsigned WIDTH = 3);
  covergroup cg with function sample(bit [WIDTH-1 : 0] val,
    bit [WIDTH-1 : 0] prev
  );
    coverpoint val;
    coverpoint prev;

    cross prev, val;
  endgroup

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

  // ...
endclass

该类将跟踪先前的值以及是否收集了先前的值(即我们尝试采样第二个值):

class cg_wrapper #(int unsigned WIDTH = 3);
  protected bit has_prev;
  protected bit [WIDTH-1 : 0] prev;

  // ...
endclass

为了确保在适当的点对覆盖进行采样,该类将公开sample(...)函数(类似于封面组所具有的),该函数处理对实际封面组进行采样并存储先前的值:

class cg_wrapper #(int unsigned WIDTH = 3);
  // ...

  function void sample(bit [WIDTH-1 : 0] val);
    if (has_prev)
      cg.sample(val, prev);
    prev = val;
    has_prev = 1;
  endfunction
endclass

这将确保您获得有意义的十字架。例如,使用值sample(...)0调用1两次,只会导致从01的一次“转换”(即十字架被填满了。

如果你想开始排除垃圾箱的“过渡”,你可以使用很多不同的方法来做到这一点。例如,要排除相同的转换,您可以执行以下操作:

cross prev, val {
  ignore_bins ignore =
    (binsof (val) && binsof (prev)) with (prev == val);
}

这会忽略0 => 01 => 12 => 2等类型的转换。

AMIQ Consulting还有一篇很好的文章展示了specifying cross bins的一些很酷的方法。

答案 1 :(得分:0)

您的第一个解决方案几乎不需要修改。您必须在bin name之后使用[]才能使其成为自动bin。我认为这就是它不适合你的原因。

cover_point_y : coverpoint y { 
  bins transitions[] = ( 0, 1 => 0, 1 );
}

答案 2 :(得分:0)

假设你想覆盖连续的增量,封面属性可以解决这个问题:

bit [7:0] y;

property y_inc(int n); @(posedge clk) y == $past(y+1)[*n]; endproperty
y_inc_3: cover property (y_inc(3));
y_inc_full: cover property (y_inc((1<<$bits(y))-1));