new*_*bie 4 verilog system-verilog
我的 RTL 设计中有一个 N 位寄存器,我想检查测试平台是否涵盖以下特定情况:
000..0 -> 000..001 -> 000....011 -> 00...111 -> ...... -> 111....111
Run Code Online (Sandbox Code Playgroud)
我不知道如何covergroup
为上面的内容写一个。我可以看到过渡覆盖是如何有用的。举个例子:
covergroup cg;
cover_point_y : coverpoint y {
bins tran_34 = (3=>4);
bins tran_56 = (5=>6);
}
Run Code Online (Sandbox Code Playgroud)
然而,就我而言,我的寄存器是参数化的(N 位:)reg[(N-1):0]
,并且它太大而无法手动写入完整序列。我可以写一个generate
orfor
循环来覆盖上面的序列吗?
我不太清楚你想要涵盖哪些过渡。我想您想涵盖每个值都更改为其他值。您需要记住的是,您可以在=>
运算符的任一侧写入多个值。例如:
cover_point_y : coverpoint y {
bins transitions = ( 0, 1 => 0, 1 );
}
Run Code Online (Sandbox Code Playgroud)
这将为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] );
}
Run Code Online (Sandbox Code Playgroud)
这应该创建从每个值到每个其他值的转换箱。您在这里受到工具支持的支配。例如,这在我的模拟器中不起作用,但在其他模拟器中可能有效。
如果您想排除某些转换(例如,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
Run Code Online (Sandbox Code Playgroud)
该类将跟踪先前的值以及是否收集了先前的值(即我们尝试对第二个值进行采样):
class cg_wrapper #(int unsigned WIDTH = 3);
protected bit has_prev;
protected bit [WIDTH-1 : 0] prev;
// ...
endclass
Run Code Online (Sandbox Code Playgroud)
为了确保在适当的点对覆盖率进行采样,该类将公开一个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
Run Code Online (Sandbox Code Playgroud)
这将确保您获得有意义的传球。例如,使用sample(...)
值0
和调用两次1
,将仅导致从0
到的单个“转换” 1
(即,交叉中的一个容器被填充)。
如果您想开始排除垃圾箱的“转换”,您可以使用很多不同的方法来做到这一点。例如,要排除相同的转换,您可以执行以下操作:
cross prev, val {
ignore_bins ignore =
(binsof (val) && binsof (prev)) with (prev == val);
}
Run Code Online (Sandbox Code Playgroud)
这会忽略0 => 0
、1 => 1
、2 => 2
等类型的转换。
AMIQ Consulting 还发表了一篇不错的文章,展示了一些指定交叉垃圾箱的很酷的方法。
归档时间: |
|
查看次数: |
13086 次 |
最近记录: |