功能覆盖率
SystemVerilog(SV)的功能覆盖率(Functional Coverage)用于验证设计的功能是否被充分测试,通过定义需要覆盖的场景,跟踪测试用例对这些场景的覆盖程度。以下是核心语法和组件介绍:
基本结构:covergroup
covergroup 是功能覆盖率的基本单元,用于定义需要覆盖的信号和场景,可包含 coverpoint(覆盖率点)、cross(交叉覆盖率)等。
声明语法:
// 不带参数的covergroup
covergroup 覆盖率组名 (输入信号列表);
// 定义coverpoint、cross等
option.per_instance = 1; // 可选:每个实例单独计算覆盖率
endgroup
// 带参数的covergroup(提高复用性)
covergroup 覆盖率组名 #(参数列表) (输入信号列表);
// 定义coverpoint、cross等
endgroup
实例化:
covergroup cg_example (int a, bit [1:0] b);
// ... 内部定义 ...
endgroup
// 在模块/程序中实例化
cg_example cg_inst = new(a_signal, b_signal); // 绑定实际信号
覆盖率点:coverpoint
coverpoint 用于定义对单个信号或表达式的覆盖率,通过 bins 划分需要覆盖的值域。
基本语法:
coverpoint 信号名 [可选标签] {
// 定义bins(需要覆盖的值/范围)
bins 名称1 = {值1, 值2, ...}; // 离散值
bins 名称2 = {[起始值:结束值]}; // 连续范围
bins 名称3[] = {[起始值:结束值]}; // 范围中每个值单独作为一个bin
bins 名称4 = default; // 未被其他bins覆盖的剩余值
// 可选属性
ignore_bins 忽略名称 = {值}; // 忽略不需要覆盖的值
illegal_bins 非法名称 = {值}; // 标记为非法值(出现时报错)
}
示例:
coverpoint cmd { // cmd是输入信号(假设为3位)
bins read = {3'b001}; // 单个值
bins write = {3'b010};
bins idle[] = {3'b000, 3'b111}; // 两个值各占一个bin
bins others = default; // 覆盖其他未定义的值
ignore_bins reserved = {3'b100}; // 忽略预留值
}
交叉覆盖率:cross
cross 用于定义多个 coverpoint 或变量之间的组合覆盖率,验证信号间的关联场景。
语法:
cross 覆盖率点1, 覆盖率点2 [, 覆盖率点3...][可选标签] {
// 可选:进一步筛选交叉组合
bins 交叉名称 = binsof(覆盖率点1.某个bin) && binsof(覆盖率点2.某个bin);
ignore_bins 忽略名称 = ...;
}
示例:
coverpoint addr {
bins low = {[0:100]};
bins high = {[101:200]};
}
coverpoint cmd {
bins read = {1};
bins write = {2};
}
// 交叉覆盖:地址范围与命令的组合
cross addr, cmd {
bins read_low = binsof(addr.low) && binsof(cmd.read);
bins write_high = binsof(addr.high) && binsof(cmd.write);
// 未定义的交叉组合会自动生成bins
}
触发覆盖率收集:sample()
covergroup 实例需要通过 sample() 方法触发覆盖率收集,通常在时钟边沿或关键事件发生时调用。
示例:
always @(posedge clk) begin
if (enable) begin
cg_inst.sample(); // 在时钟上升沿且enable有效时收集覆盖率
end
end
覆盖率选项:option
covergroup、coverpoint 或 cross 可通过 option 配置属性,常用选项:
- option.per_instance = 1
每个 covergroup 实例单独计算覆盖率(默认:0,所有实例合并) - option.weight = N
设置权重(影响整体覆盖率计算,默认 1) - option.auto_bin_max = N
自动生成 bins 时的最大数量(超过则合并) - option.comment = "描述"
添加注释(用于覆盖率报告)
示例:
covergroup cg_with_options;
option.per_instance = 1; // 每个实例独立统计
option.comment = "测试命令与地址的覆盖率";
cp_cmd: coverpoint cmd {
option.auto_bin_max = 8; // 自动生成bins不超过8个
}
endgroup
其他关键语法
- bins 中的通配符:? 表示任意位(如 3'b1?0 匹配 100、110)。
- 动态范围:$ 表示信号的最大值(如 [0:$] 覆盖所有可能值)。
- 条件覆盖率:通过 iff(条件) 限制覆盖率收集的条件:
coverpoint data iff (valid) { // 仅当valid为真时才收集data的覆盖率
// ...
}
总结
功能覆盖率的核心流程是:
- 定义 covergroup 并绑定信号;
- 通过 coverpoint 定义单信号覆盖率,cross 定义多信号组合覆盖率;
- 在关键事件点调用 sample() 收集数据;
- 生成覆盖率报告,分析未覆盖的 bins 以补充测试用例。
通过合理设计 covergroup 和 bins,可有效验证设计功能的完整性。