功能覆盖率

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,可有效验证设计功能的完整性。

posted @ 2025-08-19 17:51  MKYC  阅读(86)  评论(0)    收藏  举报