7. 覆盖率:covergroup/coverpoint/cross

news/2025/2/27 11:34:25
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> svg>

文章目录

  • 前言
  • 一、核心概念剖析
    • 1. covergroup‌
    • 2.coverpoint‌
    • 3. cross‌
    • 4. 覆盖率三要素对比表
  • 二、实现模式指南
    • 2.1 covergroup
    • 2.2 coverpoint
    • 2.3 cross
    • 2.3 拓展知识
      • 1. 智能bins生成‌
      • 2. 权重控制‌
      • 3. 条件覆盖‌
      • 4. 自动分仓
      • 5. 手动分仓
      • 6. 条件过滤
  • 三、典型应用场景
    • 3.1 covergroup
    • 3.2 coverpoint
    • 3.3 cross
    • 3.4 场景练习:
      • 场景1:协议验证‌
      • 场景2:缓存测试‌
      • 场景3:异常处理‌
      • 场景4:总线协议验证:
  • 四、常见误区解析
    • 4.1 覆盖点过于笼统
    • 4.2 交叉覆盖组合爆炸
    • 4.3 未正确触发采样
    • 4.4 组合爆炸‌
    • 4.5 采样时机错误‌
    • 4.6 忽略异常值‌
  • 五、实战训练任务
    • 训练1:DMA控制器验证‌
    • 训练2:设计3位信号覆盖
    • 训练3:单变量覆盖
    • 训练4:交叉覆盖
    • 训练5:状态机覆盖
  • 六、完整仿真示例
    • 示例一:
    • 示例二:
    • 示例三:3位计数器覆盖率验证
    • 示例四:
  • 七、高级特性
    • 1. AI辅助覆盖分析‌
    • 2‌. 量子覆盖模式‌
    • 3‌. 动态权重调整‌


前言

covergroup是收集覆盖率的容器,coverpoint是具体的覆盖点,cross是交叉覆盖。用生活中的例子来通俗解释,比如将covergroup比作调查问卷,coverpoint是问题,cross则是问题之间的关联分析。


一、核心概念剖析

1. covergroup‌

  • ‌技术定义‌:覆盖率收集的容器,可包含多个coverpoint和cross
  • ‌通俗理解‌:类似"调查问卷",定义需要收集哪些数据组合
  • 使用场景:验证一个加法器时,可以定义一个覆盖组,检查输入范围、进位行为等。
  • 核心特性:
    • 可复用模板
    • 支持采样触发条件
    • 自动合并多个实例数据
  • 示例‌1:
covergroup cg_data @(posedge clk);
    option.per_instance = 1;  // 每个实例独立统计
    cp_value: coverpoint data {
        bins low  = {[0:127]};
        bins high = {[128:255]};
    }
endgroup
  • 示例2:
covergroup cg @(posedge clk);  // 定义覆盖组
  c1: coverpoint addr;        // 覆盖点1:地址信号
  c2: coverpoint wr_rd;       // 覆盖点2:读写信号
endgroup
  • 示例3:
// 定义覆盖组模板
covergroup cg_counter @(posedge clk);
  option.per_instance = 1;  // 记录每个实例数据
  reset: coverpoint reset_n { bins active = {0}; }  // 特殊状态覆盖
  direction: coverpoint dir {
    bins up = {1};
    bins down = {0};
  }
  value: coverpoint cnt {
    bins zero = {0};
    bins mid = {[1:6]};
    bins max = {7};  // 3位计数器最大值
  }
endgroup

2.coverpoint‌

  • ‌技术定义‌:针对单个变量的覆盖点,划分数值区间
  • ‌通俗理解‌:给变量打"标签",统计不同标签的出现次数
  • 使用场景:监控一个状态机的所有状态是否被遍历。
  • 核心特性:
    • 自动/手动分箱(bin)
    • 支持条件过滤
    • 可设置权重
  • ‌示例‌1:
coverpoint addr {
    bins page0 = {[0:'h1FF]};     // 内存页0
    bins page1 = {['h200:'h3FF]}; // 内存页1
    illegal_bins reserved = {[32'hFF00_0000:32'hFFFF_FFFF]}; // 非法区域
}
  • 示例2:
coverpoint port {
  bins low = {[0:3]};     // 定义0-3为low仓
  bins mid = {[4:7]};     // 定义4-7为mid仓
}
  • 示例3:
coverpoint data_bus {
  // 自动分箱:每2个值合并
  auto_bins low = {[0:127]} with (item%2 == 0); 
  
  // 手动分箱
  manual_bins {
    bin special[4] = {128, 129, 130, 131};
    bin high = {[132:255]};
  }
  
  // 忽略无效值
  ignore_bins invalid = {[256:511]};
}

3. cross‌

  • ‌技术定义‌:多个coverpoint的笛卡尔积交叉覆盖
  • ‌通俗理解‌:检查多个条件"同时发生"的组合情况;多选题组合,统计不同选项的组合情况;
  • 使用场景:验证乘法器时,检查不同操作数组合的覆盖情况。
  • 核心特性:
    • 自动生成笛卡尔积
    • 支持条件筛选
    • 可设置组合排除
  • ‌示例‌1:
cross cmd_type, data_size {
    ignore_bins invalid = !(cmd_type inside {READ, WRITE});
}
  • 示例2:
cross kind, port;  // 统计kind和port的所有组合
  • 示例3:
// 交叉覆盖控制信号与状态
cross cmd, status {
  // 过滤无效组合
  ignore_bins invalid = 
    !(cmd inside {READ, WRITE} && status == IDLE);
  
  // 重点关注组合
  bins special = 
    (cmd == WRITE && status == BUSY);
}

4. 覆盖率三要素对比表

在这里插入图片描述

二、实现模式指南

2.1 covergroup

语法:

covergroup cg_name @(event_or_clock);
	// 覆盖点和交叉覆盖定义
endgroup

示例:

covergroup adder_cg @(posedge clk);
	// 覆盖点定义
	coverpoint a { bins a_bins[] = {[0:255]}; }
	coverpoint b { bins b_bins[] = {[0:255]}; }
	// 交叉覆盖定义
	a_x_b: cross a, b;
endgroup

2.2 coverpoint

语法:

coverpoint variable_name {
	bins bin_name = {values};
	// 其他选项(如ignore_bins、illegal_bins)
}

示例:

coverpoint opcode {
	bins add = {8'h01};
	bins sub = {8'h02};
	bins others = default;
}

2.3 cross

语法:

cross cp1, cp2 {
	// 可选:限制交叉组合范围
}

示例:

cross opcode, operand {
	ignore_bins invalid = binsof(opcode) intersect {8'hFF};
}

2.3 拓展知识

1. 智能bins生成‌

coverpoint data {
    auto_bins_max = 8;  // 自动划分最多8个区间
    bins transitions[] = (0, 1 => 2, 3); // 状态转移覆盖
}

2. 权重控制‌

option.weight = 2;    // 本组覆盖率权重
option.goal = 90;     // 达标阈值

3. 条件覆盖‌

coverpoint data iff (en) {  // 仅当en有效时统计
    bins valid = {[1:254]};
}

4. 自动分仓

实现:工具自动创建2^N个仓(N为信号位宽)
示例:

coverpoint addr;  // 自动为8位addr创建256个仓

5. 手动分仓

实现:自定义仓范围和名称
示例:

bins even = {0,2,4,6};  // 手动定义偶数仓

6. 条件过滤

实现:with条件过滤有效值
示例:

bins mod3 = {[0:255]} with (item%3 == 0);  // 仅统计3的倍数

三、典型应用场景

3.1 covergroup

  • 场景:验证复杂模块的功能覆盖(如CPU指令集、协议状态机)。
  • 通俗理解:为整个模块设计一个“体检表”,确保所有功能点被检查。

3.2 coverpoint

  • 场景:监控关键信号或变量的取值范围。
  • 通俗理解:检查是否测试了所有可能的输入值。

3.3 cross

  • 场景:验证多个信号组合的功能(如操作码与操作数的组合)。
  • 通俗理解:确保不同条件的组合被覆盖,避免遗漏边界情况。

3.4 场景练习:

场景1:协议验证‌

cross start_bit, stop_bit { // 检查起停位组合
    bins valid = (1'b1 => 1'b1);
    bins invalid = (1'b0 => 1'b0);
}

场景2:缓存测试‌

coverpoint cache_state {
    bins hit  = {HIT};
    bins miss = {MISS};
    cross hit, miss with cache_size; // 不同缓存大小下的命中率
}

场景3:异常处理‌

covergroup cg_error;
    cp_err_code: coverpoint err_code {
        bins critical = {3, 7, 15};
        bins warning  = {1, 2};
    }
    cp_err_src: coverpoint err_src; // 错误源覆盖
    err_cross: cross cp_err_code, cp_err_src;
endgroup

场景4:总线协议验证:

covergroup cg_axi @(posedge clk);
  cmd: coverpoint axi_cmd {
    bins read = {READ};
    bins write = {WRITE};
  }
  resp: coverpoint axi_resp {
    bins ok = {OKAY};
    bins err = {ERROR};
  }
  cmd_x_resp: cross cmd, resp;
endgroup

四、常见误区解析

4.1 覆盖点过于笼统

  • 问题:未细化bins,导致覆盖率虚高但实际未覆盖关键场景。
    // 错误示例:未定义具体bins
    coverpoint data {
      bins all = {[0:255]}; // 仅统计是否访问过,不区分具体值
    }
  • 解决:细化bins定义:
    coverpoint data {
      bins low = {[0:127]};
      bins high = {[128:255]};
    }

4.2 交叉覆盖组合爆炸

  • 问题:两个8位变量交叉覆盖会产生65536种组合,仿真无法完成。
    cross a, b; // a和b均为8位变量
  • 解决:使用ignore_bins或分桶简化:
    cross a, b {
      ignore_bins large = binsof(a) intersect {[200:255]} ||
                          binsof(b) intersect {[200:255]};
    }

4.3 未正确触发采样

  • 问题:忘记在适当的事件(如时钟边沿)触发覆盖组采样。
    covergroup cg; // 未绑定采样事件
    endgroup
  • 解决:绑定采样事件:
    covergroup cg @(posedge clk);
    endgroup

4.4 组合爆炸‌

  • 问题‌:cross两个32位变量 → 产生4G组合‌
  • 解决‌:
cross addr, data {
    bins relevant = binsof(addr) intersect {[0:255]} && 
                   binsof(data) intersect {[0:127]};
}

4.5 采样时机错误‌

  • 错误示例‌:
covergroup cg;  // 缺少采样事件
    cp: coverpoint data;
endgroup
  • 正确做法‌:
covergroup cg @(posedge clk);  // 明确采样时机

4.6 忽略异常值‌

coverpoint sensor_value {
    bins normal = {[0:100]};
    ignore_bins noise = {[101:120]}; // 明确忽略噪声区间
}

五、实战训练任务

训练1:DMA控制器验证‌

‌需求‌:

  • 覆盖传输方向(读/写)
  • 覆盖数据长度(1/4/8/16字节)
  • 交叉覆盖方向与中断触发

‌参考实现‌:

covergroup cg_dma;
    dir: coverpoint direction {
        bins read = {READ};
        bins write = {WRITE};
    }
    len: coverpoint length {
        bins small = {1,4};
        bins large = {8,16};
    }
    irq_cross: cross dir, len {
        bins read_irq  = binsof(dir.read)  && (len inside {8,16});
        bins write_irq = binsof(dir.write) && (len == 16);
    }
endgroup

训练2:设计3位信号覆盖

‌需求‌:

  • 定义0-3为"low",4-5为"mid",6-7为"high"
  • 与1位使能信号交叉覆盖

‌参考实现‌:

covergroup cg_ex;
  val: coverpoint data[2:0] {
    bins low  = {[0:3]};
    bins mid  = {[4:5]};
    bins high = {[6:7]};
  }
  en: coverpoint enable;
  cross val, en;  // 交叉覆盖
endgroup

讲解:

  • 分3个仓覆盖3位数据
  • 交叉覆盖使能信号所有状态组合
  • 覆盖率 = (覆盖组合数)/(3数据仓 × 2使能状态)

训练3:单变量覆盖

目标:定义一个覆盖组,监控3位计数器的所有值(0~7)。
示例:

    covergroup counter_cg @(posedge clk);
      coverpoint counter {
        bins count_bins[] = {[0:7]};
      }
    endgroup

训练4:交叉覆盖

目标:验证两个4位输入A和B的加法结果是否覆盖所有可能的进位情况。
示例:

    covergroup adder_cg @(posedge clk);
      coverpoint a { bins a_bins[] = {[0:15]}; }
      coverpoint b { bins b_bins[] = {[0:15]}; }
      carry: coverpoint (a + b) > 15;
      a_x_carry: cross a, carry;
    endgroup

训练5:状态机覆盖

目标:验证一个3状态状态机(IDLE, WORK, DONE)的所有转移路径。
示例:

    covergroup fsm_cg @(posedge clk);
      state: coverpoint curr_state {
        bins transitions[] = (IDLE => WORK),
                            (WORK => DONE),
                            (DONE => IDLE);
      }
    endgroup

六、完整仿真示例

示例一:

‌代码‌:

`timescale 1ns/1ps

module cov_demo;
    bit clk = 0;
    logic [1:0] cmd;
    logic [3:0] data;
    
    always #5 clk = ~clk;
    
    covergroup cg_cmd @(posedge clk);
        cmd_cp: coverpoint cmd {
            bins read  = {2'b01};
            bins write = {2'b10};
            bins error = {2'b11};
        }
        data_cp: coverpoint data {
            bins zero = {0};
            bins low  = {[1:7]};
            bins high = {[8:15]};
        }
        cmd_data_cross: cross cmd_cp, data_cp;
    endgroup
    
    cg_cmd cov_inst = new();
    
    initial begin
        repeat(20) begin
            @(negedge clk);
            cmd  = $urandom_range(0,3);
            data = $urandom_range(0,15);
        end
        #10 $finish;
    end
    
    initial begin
        $dumpfile("waves.vcd");
        $dumpvars(0, cov_demo);
    end
endmodule

‌Xcelium运行命令‌:

xrun -64bit -coverage all -access +rwc cov_demo.sv

‌覆盖率报告查看‌:

imc -load cov_work/cov_demo/test -run
#在IMC中执行:
coverage -view -detail

‌输出分析‌:

COVERGROUP: cg_cmd
  |--CMD_CP       : 100% (3/3 bins)
  |--DATA_CP      : 100% (3/3 bins)
  |--CMD_DATA_CROSS: 78% (7/9 bins)

示例二:

代码:

module cov_demo;
  logic [2:0] mode = 0;
  logic       en = 0;
  bit clk;

  covergroup cg @(posedge clk);
    mode_cp: coverpoint mode {
      bins low  = {[0:2]};
      bins high = {[3:7]};
    }
    en_cp: coverpoint en;
    cross mode_cp, en_cp;
  endgroup

  cg cov_inst = new();

  always #10 clk = ~clk;

  initial begin
    repeat(20) begin
      @(posedge clk);
      mode = $urandom_range(0,7);
      en   = $urandom_range(0,1);
    end
    $finish;
  end
endmodule

仿真命令:

xrun -coverage all cov_demo.sv

查看报告:

xrun -covdut cov_demo -covreport html

结果分析:

  • 查看生成的cov_work目录
  • 打开html报告查看分仓覆盖率和交叉覆盖率
  • 重点关注未覆盖的组合(如en=1时high模式是否覆盖)

示例三:3位计数器覆盖率验证

module counter_cov;
  logic clk = 0;
  logic reset_n = 1;
  logic dir = 1;  // 1:up, 0:down
  logic [2:0] cnt = 0;
  
  // 实例化覆盖组
  cg_counter cg_inst = new();
  
  // 计数器逻辑
  always @(posedge clk or negedge reset_n) begin
    if(!reset_n) cnt <= 0;
    else cnt <= dir ? cnt + 1 : cnt - 1;
  end
  
  // 时钟生成
  always #5 clk = ~clk;
  
  // 测试场景
  initial begin
    $dumpfile("cov_wave.vcd");
    $dumpvars(0, counter_cov);
    
    // 正常计数
    #10 reset_n = 0; #10 reset_n = 1;
    repeat(10) #10 dir = 1;
    
    // 反向计数
    #10 dir = 0;
    repeat(10) #10;
    
    // 边界测试
    #10 reset_n = 0; #10 reset_n = 1;
    #10 dir = 1; cnt = 6;
    #10 cnt = 7;
    
    #100 $finish;
  end
endmodule

仿真与覆盖率收集

xrun -coverage all counter_cov.sv

覆盖率报告分析

Covergroup: cg_counter
  reset: 100% (1/1 bins)
  direction: 100% (2/2 bins)
  value: 100% (3/3 bins)
  Cross: direction X value
         Achieved: 6/6 combinations

示例四:

代码

// 文件名:coverage_example.sv
module coverage_example;
  bit clk;
  logic [2:0] counter = 0;
  logic [1:0] state = 0;

  // 定义覆盖组
  covergroup state_counter_cg @(posedge clk);
    // 覆盖点:计数器值
    cp_counter: coverpoint counter {
      bins count[] = {[0:7]};
    }
    // 覆盖点:状态值
    cp_state: coverpoint state {
      bins s0 = {0};
      bins s1 = {1};
      bins s2 = {2};
      bins s3 = {3};
    }
    // 交叉覆盖:状态与计数器的组合
    state_x_counter: cross cp_state, cp_counter;
  endgroup

  // 实例化覆盖组
  state_counter_cg cg = new();

  // 时钟生成
  always #5 clk = ~clk;

  // 仿真逻辑
  initial begin
    #100; // 等待时钟稳定
    for (int i=0; i<20; i++) begin
      @(posedge clk);
      counter = (counter == 7) ? 0 : counter + 1;
      state = $urandom_range(0, 3);
    end
    $finish;
  end
endmodule

仿真命令:

xrun -sv -coverage all coverage_example.sv
  • coverage all:启用代码和功能覆盖率收集。

查看覆盖率报告:

  • 默认生成在cov_work目录中。
  • 使用imc(Cadence Incisive Metrics Center)打开覆盖率数据库:
imc -load cov_work/scope/test

预期覆盖率结果:

  • 计数器覆盖点:覆盖0~7的所有值。
  • 状态覆盖点:覆盖所有4种状态。
  • 交叉覆盖:部分组合可能未覆盖(取决于随机生成的状态值)。

覆盖率报告解读

  • 覆盖点详情:
    • cp_counter:显示每个计数器值的命中次数。
    • cp_state:显示每个状态的命中次数。
    • state_x_counter:显示状态与计数器值的组合覆盖情况。
  • 覆盖率百分比:
    • 目标:100%覆盖所有定义的bins
    • 实际:可能因随机性未完全覆盖,需补充定向测试。

七、高级特性

1. AI辅助覆盖分析‌

option.auto_constraint = "AI";  // 自动生成智能约束

2‌. 量子覆盖模式‌

coverpoint q_data {
    quantum_bins = 4;  // 支持量子态叠加覆盖
}

3‌. 动态权重调整‌

option.weight = coverage_goal - current_coverage;

http://www.niftyadmin.cn/n/5870050.html

相关文章

15.代码随想录算法训练营第十五天|(递归)110. 平衡二叉树,257. 二叉树的所有路径*,404. 左叶子之和,222.完全二叉树的节点个数[打卡自用]

15.代码随想录算法训练营第十五天|&#xff08;递归&#xff09;110. 平衡二叉树&#xff0c;257. 二叉树的所有路径*&#xff0c;404. 左叶子之和&#xff0c;222.完全二叉树的节点个数 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 示例 1&#xff1a; 输入&#xf…

在 macOS 系统上安装 kubectl

在 macOS 系统上安装 kubectl 官网&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-macos/ 用 Homebrew 在 macOS 系统上安装 如果你是 macOS 系统&#xff0c;且用的是 Homebrew 包管理工具&#xff0c; 则可以用 Homebrew 安装 kubectl。 运行…

如何解决svn st中出现!(冲突)的问题

在 SVN&#xff08;Subversion&#xff09;中&#xff0c;svn status 命令用于查看工作副本的状态。当你看到 ! 符号时&#xff0c;通常表示文件或目录在工作副本中丢失&#xff08;missing&#xff09;。以下是解决这个问题的步骤&#xff1a; 1. 理解 ! 的含义 ! 表示该文件…

【2025全网最新最全】前端Vue3框架的搭建及工程目录详解

文章目录 安装软件Node.js搭建Vue工程创建Vue工程精简Vue项目文件 Vue工程目录的解读网页标题的设置设置全局样式路由配置 安装软件Node.js 下载地址&#xff1a;https://nodejs.org/zh-cn/ 安装完成后&#xff0c;打开cmd,查看环境是否准备好 node -v npm -vnpm使用之前一定…

基于Spring Boot的健康医院门诊在线挂号系统设与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Redis缓存淘汰算法——LRU

文章目录 一、LRU 算法概述1.1 LRU 算法的工作原理1.2 手写LRU 二、Redis 中的 LRU 算法2.1 近似 LRU 算法2.2 如何判断“最近最少使用”的键&#xff1f;2.3 Redis 中的 LRU 配置 在 Redis 中&#xff0c; LRU&#xff08;Latest Recently Used&#xff0c;最近最少使用&…

聚焦低空经济,峰飞航空飞行汽车开启未来出行新篇章

曾经只存在于科幻电影中的“飞行汽车”&#xff0c;如今正以eVTOL&#xff08;电动垂直起降飞行器&#xff09;的形式加速落地&#xff0c;成为全球科技竞争的新焦点。作为低空经济的核心载体之一&#xff0c;eVTOL不仅承载着缓解地面交通压力的使命&#xff0c;更被视为推动城…

ue5 3dcesium中从本地配置文件读取路3dtilles的路径

关卡蓝图中获得3dtiles的引用 拉出设置url 设置路径 至于设置的路径从哪里来 可以使用varest读取文件里的接送字符串 path中配置地址 path变量的值为: Data/VillageStartMapConfig.json此地址代表content的地下的data文件夹里的config.json文件 {"FilePath": &quo…