UVM功能覆盖策略1. 主要内容概览覆盖率类型功能覆盖策略覆盖组covergroup数据采样覆盖选项数据分析2. 功能覆盖策略核心思想收集信息而非数据对于MCDF关心的是合法的寄存器地址和非法的寄存器地址可写的寄存器域和非法的寄存器域而不是具体的寄存器地址数值一旦关注的地方着眼于感兴趣的状态而不是具体数值那么对如何定义功能覆盖率会减轻很大负担设计信号如果数量范围太大应该拆分为多个小范围再加上边界情况只测量需要的内容Verifier需要懂得使能覆盖率收集时这一特性会降低很大的仿真性能由于收集功能覆盖率数据的开销很大所以应该只测量你会用来分析并且改进测试的那部分数据需要设定合理的覆盖率采样的事件一方面提升采样效率一方面降低收集覆盖率的开销验证的完备性完备的覆盖率测量结果和漏洞增长曲线可以帮助确认设计是否被完整地验证过代码覆盖率低但功能覆盖率高说明验证计划不完整测试没有执行设计的所有代码代码覆盖率高但功能覆盖率低说明即使测试平台很好地执行了设计的所有代码但是测试还是没有把设计定位到所有感兴趣的状态上目标同时驱动高的代码覆盖率和功能覆盖率功能覆盖率 \ 代码覆盖率LowHighHighNeed more FC points, including corner casesGood coverage: check bug rateLowStart of projectIs design complete? Perhaps try formal tools3. 覆盖组covergroup在类里定义covergroupclass Transactor; Transaction tr; mailbox mbx_in; covergroup CovPort; // 声明covergroup coverpoint tr.port; // 采样点 endgroup function new(mailbox mbx_in); CovPort new(); // 例化covergroup this.mbx_in mbx_in; endfunction endclasscovergroup在类中声明在new()函数中例化可以例化多次CovPort cg1 new(); CovPort cg2 new();数据采样概述在coverpoint指定采样一个变量或表达式时SV会创建很多的仓bin来记录每个数值被捕捉到的次数这些bin是衡量功能覆盖率的基本单位covergroup中可以定义多个coverpointcoverpoint中可以自定义多个cover bin或者SV帮助自动定义多个cover bin每次covergroup采样SV都会在一个或者多个cover bin中留下标记用来记录采样时变量的数值和匹配的cover bin在仿真之后可以使用分析工具读取这些数据库来生成覆盖率报告包含了各部分和总体的覆盖率条件覆盖率iffcovergroup CoverPort; coverpoint port iff (!bus_if.reset); // 复位期间不采样 endgroup // 也可以手动控制start/stop initial begin CovPort ck new(); #1ns; ck.stop(); // 暂停采样 bus_if.reset 1; #100ns bus_if.reset 0; ck.start(); // 恢复采样 ck.sample(); // 手动触发采样 end可以使用关键字iff给coverpoint添加条件常用于在复位期间关闭覆盖以忽略不合理的条件触发也可以使用start()和stop()函数来控制covergroup各个独立实例忽略的binignore_binsbit [2:0] low_ports_0_5; // 只使用数值0-5 covergroup CoverPort; coverpoint low_ports_0_5 { ignore_bins hi {[6,7]}; // 忽略数值6-7 } endgroup在某些coverpoint可能始终无法得到全部的域值对于那些不计算功能的域值可以使用ignore_bins来排除最终它们并不会计入coverpoint的覆盖率交叉覆盖率crossclass Transaction; rand bit a, b; endclass covergroup CrossBinNames; a: coverpoint tr.a { bins a0 {0}; bins a1 {1}; option.weight0; // 不计算覆盖率 } b: coverpoint tr.b { bins b0 {0}; bins b1 {1}; option.weight0; // 不计算覆盖率 } ab: cross a, b { bins a0b0 binsof(a.a0) binsof(b.b0); bins a1b0 binsof(a.a1) binsof(b.b0); bins b1 binsof(b.b1); } endgroup权重是0则不搜集或不关心此覆盖率同时cross不会生成任何的bin则可自己声明关心的组合情况coverpoint定义的时候有可能没有把所有的bin列出来但cross会全算上带中括号则要遍历所有枚举才能记录一条覆盖率4. 覆盖选项单个实例的覆盖率covergroup CoverLength; coverpoint tr.length; option.per_instance 1; // 单独列出每个covergroup实例的覆盖率 endgroup如果对一个covergroup例化多次默认情况下SV会将所有实例的覆盖率合并到一起如果需要单独列出每个covergroup实例的覆盖率需要设置option.per_instance 15. 数据分析$get_coverage(); // 得到总体的覆盖率 covergroup_inst.get_inst_coverage(); // 获取单个covergroup实例的覆盖率这些函数最实际的用处是在一个测试当中监测覆盖率的变化如果覆盖率水平在一段时间之后没有提高那么这个测试就应该停止重启新的随机种子或者测试可能有望提高覆盖率如果测试可以基于功能覆盖率采取一些深入的行动例如重新限定随机的约束那将是非常好的事情但是这种测试很难编写
UVM功能覆盖策略
UVM功能覆盖策略1. 主要内容概览覆盖率类型功能覆盖策略覆盖组covergroup数据采样覆盖选项数据分析2. 功能覆盖策略核心思想收集信息而非数据对于MCDF关心的是合法的寄存器地址和非法的寄存器地址可写的寄存器域和非法的寄存器域而不是具体的寄存器地址数值一旦关注的地方着眼于感兴趣的状态而不是具体数值那么对如何定义功能覆盖率会减轻很大负担设计信号如果数量范围太大应该拆分为多个小范围再加上边界情况只测量需要的内容Verifier需要懂得使能覆盖率收集时这一特性会降低很大的仿真性能由于收集功能覆盖率数据的开销很大所以应该只测量你会用来分析并且改进测试的那部分数据需要设定合理的覆盖率采样的事件一方面提升采样效率一方面降低收集覆盖率的开销验证的完备性完备的覆盖率测量结果和漏洞增长曲线可以帮助确认设计是否被完整地验证过代码覆盖率低但功能覆盖率高说明验证计划不完整测试没有执行设计的所有代码代码覆盖率高但功能覆盖率低说明即使测试平台很好地执行了设计的所有代码但是测试还是没有把设计定位到所有感兴趣的状态上目标同时驱动高的代码覆盖率和功能覆盖率功能覆盖率 \ 代码覆盖率LowHighHighNeed more FC points, including corner casesGood coverage: check bug rateLowStart of projectIs design complete? Perhaps try formal tools3. 覆盖组covergroup在类里定义covergroupclass Transactor; Transaction tr; mailbox mbx_in; covergroup CovPort; // 声明covergroup coverpoint tr.port; // 采样点 endgroup function new(mailbox mbx_in); CovPort new(); // 例化covergroup this.mbx_in mbx_in; endfunction endclasscovergroup在类中声明在new()函数中例化可以例化多次CovPort cg1 new(); CovPort cg2 new();数据采样概述在coverpoint指定采样一个变量或表达式时SV会创建很多的仓bin来记录每个数值被捕捉到的次数这些bin是衡量功能覆盖率的基本单位covergroup中可以定义多个coverpointcoverpoint中可以自定义多个cover bin或者SV帮助自动定义多个cover bin每次covergroup采样SV都会在一个或者多个cover bin中留下标记用来记录采样时变量的数值和匹配的cover bin在仿真之后可以使用分析工具读取这些数据库来生成覆盖率报告包含了各部分和总体的覆盖率条件覆盖率iffcovergroup CoverPort; coverpoint port iff (!bus_if.reset); // 复位期间不采样 endgroup // 也可以手动控制start/stop initial begin CovPort ck new(); #1ns; ck.stop(); // 暂停采样 bus_if.reset 1; #100ns bus_if.reset 0; ck.start(); // 恢复采样 ck.sample(); // 手动触发采样 end可以使用关键字iff给coverpoint添加条件常用于在复位期间关闭覆盖以忽略不合理的条件触发也可以使用start()和stop()函数来控制covergroup各个独立实例忽略的binignore_binsbit [2:0] low_ports_0_5; // 只使用数值0-5 covergroup CoverPort; coverpoint low_ports_0_5 { ignore_bins hi {[6,7]}; // 忽略数值6-7 } endgroup在某些coverpoint可能始终无法得到全部的域值对于那些不计算功能的域值可以使用ignore_bins来排除最终它们并不会计入coverpoint的覆盖率交叉覆盖率crossclass Transaction; rand bit a, b; endclass covergroup CrossBinNames; a: coverpoint tr.a { bins a0 {0}; bins a1 {1}; option.weight0; // 不计算覆盖率 } b: coverpoint tr.b { bins b0 {0}; bins b1 {1}; option.weight0; // 不计算覆盖率 } ab: cross a, b { bins a0b0 binsof(a.a0) binsof(b.b0); bins a1b0 binsof(a.a1) binsof(b.b0); bins b1 binsof(b.b1); } endgroup权重是0则不搜集或不关心此覆盖率同时cross不会生成任何的bin则可自己声明关心的组合情况coverpoint定义的时候有可能没有把所有的bin列出来但cross会全算上带中括号则要遍历所有枚举才能记录一条覆盖率4. 覆盖选项单个实例的覆盖率covergroup CoverLength; coverpoint tr.length; option.per_instance 1; // 单独列出每个covergroup实例的覆盖率 endgroup如果对一个covergroup例化多次默认情况下SV会将所有实例的覆盖率合并到一起如果需要单独列出每个covergroup实例的覆盖率需要设置option.per_instance 15. 数据分析$get_coverage(); // 得到总体的覆盖率 covergroup_inst.get_inst_coverage(); // 获取单个covergroup实例的覆盖率这些函数最实际的用处是在一个测试当中监测覆盖率的变化如果覆盖率水平在一段时间之后没有提高那么这个测试就应该停止重启新的随机种子或者测试可能有望提高覆盖率如果测试可以基于功能覆盖率采取一些深入的行动例如重新限定随机的约束那将是非常好的事情但是这种测试很难编写