2. 覆盖点与仓:coverpoint 声明与 bins 定义

好,咱们今天聊聊覆盖组里最核心的两个东西——覆盖点(coverpoint)和仓(bins)。

说白了,覆盖点就是你想观察的那个信号。仓呢,就是把这个信号的值域切成若干段,每一段就是一个仓。你想想看,没有仓,你怎么知道信号具体覆盖了哪些值?

2.1 覆盖点的声明

覆盖点的声明其实很简单。在 covergroup 里面,直接用 coverpoint 关键字加上信号名就行。

covergroup my_cg;
    coverpoint addr;  // 最简单的声明
    coverpoint data;
    coverpoint ctrl;
endgroup

我个人习惯,会把所有要观察的信号都列出来。但要注意,不是所有信号都适合做覆盖点。比如时钟信号,你覆盖它干嘛?

嗯,这里有个小细节。覆盖点默认会对信号的所有可能取值进行采样。但实际项目中,我们往往只关心某些特定值。这时候就需要手动定义仓了。

2.2 自动定义的仓

如果你不手动定义仓,工具会自动帮你生成。对于 2 位信号,自动生成 4 个仓(00, 01, 10, 11)。对于 8 位信号,那就是 256 个仓。

注意:自动仓虽然省事,但会带来两个问题:

  • 仓太多,仿真速度变慢
  • 很多仓可能永远覆盖不到,造成覆盖率假象

我曾经在一个项目中,同事用了自动仓,结果 8 位地址信号生成了 256 个仓。仿真跑了一整天,覆盖率才 30%。后来我改成手动定义,只关心关键的 10 个地址,覆盖率一下子就上去了。

2.3 手动定义仓

手动定义仓,用 bins 关键字。语法其实很灵活,我给大家列几种常见用法。

2.3.1 单个值仓

coverpoint addr {
    bins zero = {0};      // 只关心地址为0的情况
    bins max  = {255};    // 只关心地址为255的情况
}

2.3.2 范围仓

coverpoint data {
    bins low    = {[0:63]};    // 低64个值
    bins mid    = {[64:191]};  // 中间128个值
    bins high   = {[192:255]}; // 高64个值
}

你看,这样就把 256 个值压缩成了 3 个仓。覆盖率报告看起来清爽多了。

2.3.3 交叉仓

有时候我们需要看两个信号的组合。比如读写操作和地址的组合。

coverpoint rw {
    bins read  = {0};
    bins write = {1};
}

coverpoint addr {
    bins low  = {[0:127]};
    bins high = {[128:255]};
}

cross rw, addr;  // 自动生成 2x2=4 个交叉仓

小技巧:交叉覆盖很容易产生大量仓。两个 8 位信号交叉,就是 65536 个仓。我建议先手动分仓,再交叉,这样仓的数量可控。

2.4 特殊仓:ignore_bins 和 illegal_bins

这两个东西很实用。ignore_bins 用来排除你不关心的值,illegal_bins 用来标记不应该出现的值。

coverpoint status {
    bins good[] = {[0:5]};       // 正常状态
    ignore_bins reserved = {6, 7}; // 保留位,不关心
    illegal_bins error = {8'hFF};  // 这个值不应该出现
}

我记得有一次,芯片规格书里写某个寄存器的 bit[3:0] 只有 0-7 是合法的。结果仿真时发现覆盖率一直上不去。后来一查,原来是设计里误写了 8。用 illegal_bins 一抓就抓出来了。

2.5 自动仓与手动仓的选择

场景 推荐方式 原因
信号位宽小(≤4位) 自动仓 仓数量少,不影响性能
信号位宽大(≥8位) 手动仓 避免仓爆炸
只关心特定值 手动仓 精准覆盖,节省时间
需要交叉覆盖 先手动再交叉 控制交叉仓数量

2.6 本章知识体系

下面这张图,是我自己画的覆盖点与仓的知识结构。你看一眼就能明白它们之间的关系。

覆盖点 (coverpoint) 自动仓 (auto_bins) 位宽小用 位宽大慎用 手动仓 (user_bins) 单个值仓 范围仓 交叉仓 特殊仓 ignore_bins illegal_bins 核心原则:仓要少而精,覆盖要准而全

核心要点:

  • 覆盖点声明用 coverpoint,简单直接
  • 自动仓适合小位宽信号,大位宽信号一定要手动分仓
  • 手动仓用 bins 关键字,支持单个值、范围、交叉
  • ignore_bins 排除不关心的值,illegal_bins 抓设计错误
  • 交叉覆盖前先手动分仓,避免仓爆炸

好了,覆盖点和仓的基本用法就这些。说白了就是一句话:你想看什么,就定义什么仓。别让工具替你瞎操心,自己动手,覆盖率才靠谱。

可可精品资料库