我的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循环来覆盖我想看到的上述序列吗?
答案 0 :(得分:3)
我不清楚你要覆盖哪些过渡。我想你想要涵盖每个值都改为其他每个值。您需要记住的是,您可以在=>
运算符的任意一侧写入多个值。例如:
cover_point_y : coverpoint y {
bins transitions = ( 0, 1 => 0, 1 );
}
这会为0 => 0
,0 => 1
,1 => 0
,1 => 1
创建容器。如果我正确解释了BNF,根据LRM,您放在=>
运算符任一侧的值都是covergroup_value_range
类型,这意味着应该接受覆盖点的任何值范围语法。这意味着以下内容也应该是合法的:
cover_point_y : coverpoint y {
bins transitions = ( [0 : 2^N - 1] => [0 : 2^N - 1] );
}
这应该从每个值到每个其他值创建转换箱。你在这里受到工具支持的支配。例如,这在我的模拟器中不起作用,但它可能在其他模拟器中有效。
如果你想排除某些转换(例如,0 => 0
,1 => 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
两次,只会导致从0
到1
的一次“转换”(即十字架被填满了。
如果你想开始排除垃圾箱的“过渡”,你可以使用很多不同的方法来做到这一点。例如,要排除相同的转换,您可以执行以下操作:
cross prev, val {
ignore_bins ignore =
(binsof (val) && binsof (prev)) with (prev == val);
}
这会忽略0 => 0
,1 => 1
,2 => 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));