既然你可以
提供地址
并从寄存器中读取,您可以使用
有源监视器
或一些其他组件来采样这些值。
每当监视器对接口上的某些事务进行采样时,它就会转换
引脚级事务
到
高级抽象类对象
。这将发送到
覆盖等级
通过一些邮箱、端口等。
class monitor;
// first get coverage handle from agent/env class
overall_coverage cvr;
task run();
// sample interface signals
tr.addr = intf.addr; // provided by driver
tr.data = intf.data; // provided by DUT
// send to coverage class
cov.write(tr);
endtask
endclass
覆盖范围类别
可选地
克隆
对象和
解码
寄存器地址。基于寄存器地址,对寄存器覆盖点进行采样。
// overall coverage class
class overall_coverage;
// dedicated class for register coverage (optional)
reg_coverage reg_cvr;
function void write(transaction tr_ip);
tr.clone(tr_ip); // optional cloning
reg_cvr.addr = tr.addr;
reg_cvr.data = tr.data;
reg_cvr.addr_cg.sample(); // sample whether address itself is covered or not
case(tr.addr)
addr1 : reg_cvr.addr1_data_cg.sample();
addr2 : reg_cvr.addr2_data_cg.sample();
// ...
endcase
// some other stuff...
endfunction
endclass
可能有
专用寄存器覆盖类
其仅用于寄存器覆盖。可以有一个封面组
覆盖地址
和其他覆盖组
每个地址中的数据
.
每个覆盖组可以具有数据值上的覆盖点。因为每个寄存器可能具有不同的保留位和只读/仅写位。这可以按如下方式完成:
class reg_coverage;
covergroup addr_cg();
covwerpoint addr
{
bins my_addr1 = {addr1}; // various addresses bins
bins my_addr2 = {addr2};
// ...
}
endgroup
现在将每个寄存器上的数据写入covergroup,如下所示:
covergroup addr1_data_cg();
coverpoint data
{
bins must_bits = {3'b111,3'b110}; // bins on data sampled from particular register
bins reserved_value = {3'b011,3'b001};
// ...
}
covergroup addr2_data_cg();
coverpoint data
{
bins exercised_bits = {'b101,'b110}; // bins on data sampled from particular register
bins reserved_value = {'b000,'b010};
// ...
}
endgroup
endclass
也可以有其他选择,比如使用单个覆盖类
define
用于减少代码重复等的宏,但这是这里描述的基本方法。
提到
bitwise coverage
,
Wildcard bins
,
Functional coverage
,
SV-CDV
和
SystemVerilog LRM
第19章了解更多信息。