网站建设项目开发书,连江网站建设,成都模板建站代理,网站 mysql数据库 字符文章目录 1.0 覆盖率前言1.1 覆盖率类型1.2 覆盖策略及覆盖组1.3 覆盖率数据采样1.3.1 bin的创建与使用1.3.2 条件覆盖率1.3.3 翻转覆盖率1.3.4 wildcard覆盖率1.3.5 忽略bin与非法bin 1.4 交叉覆盖率1.4.1 排除部分cross bin1.4.2 精细化交叉覆盖率1.4.3 单个实例的覆盖率1.4.… 文章目录 1.0 覆盖率前言1.1 覆盖率类型1.2 覆盖策略及覆盖组1.3 覆盖率数据采样1.3.1 bin的创建与使用1.3.2 条件覆盖率1.3.3 翻转覆盖率1.3.4 wildcard覆盖率1.3.5 忽略bin与非法bin 1.4 交叉覆盖率1.4.1 排除部分cross bin1.4.2 精细化交叉覆盖率1.4.3 单个实例的覆盖率1.4.4 注释1.4.5 覆盖率次数限定与目标1.4.6 covergroup方法总结1.4.7 案例  1.0 覆盖率前言 
覆盖率是用来衡量设计验证完备性。随着测试逐步覆盖各种合理的组合覆盖率用来衡量测试进行的程度。覆盖率工具会在仿真过程中收集信息然后进行后续处理并且得到覆盖率报告。通过报告找出覆盖盲区然后修改现有test或者创建新的test来填补这些盲区。 
覆盖率反馈环路 带约束的随机测试与定向测试这两种环路一直迭代直到达到要求 
收集覆盖率最简单的办法就是改变随机种子seed就可以反复运行同一个随机测试平台来产生新的激励。每一次仿真都会产生一个带有覆盖率信息的数据库将这些信息全部合并在一起就可以得到功能覆盖率。 1.1 覆盖率类型 代码覆盖率直接去检查RTL Code 代码覆盖率衡量的是测试对于硬件设计描述的“实现”究竟测试得有多彻底而非针对验证计划。 line coverage所有行是否都运行到paths coverage所有路径是否以cover到toggle coverage所有变量都有过0,1翻转FSM coverage状态机中所有状态都已运行到 很多的仿真工具都带有代码覆盖率工具而得到的最终结果就是检测对设计代码运行程度的衡量。代码覆盖率最终的结果用于衡量所有testcase执行了设计中的多少代码。 关注点在设计代码RTL的分析上而不是测试平台。 未经测试的设计代码里可能隐藏硬件漏洞也可能是冗余代码。 代码覆盖率达到了100%并不意味着验证的工作已经完成但代码覆盖率100%是验证工作完备性的必要条件  功能覆盖率 验证的目的: 确保设计在实际环境中的行为正确。功能描述文档详细说明了设计应该如何运行而验证计划则列出了相应的功能应该如何激 励、验证和测量。功能覆盖率是和功能设计紧密相连的而代码覆盖率则是衡量设计的实现情况。若某个功能在设计中被遗漏代码覆盖率不能发现这个错误但是功能覆盖率可以。  断言覆盖率 断言用于一次性地或在一段时间内核对两个或两个以上设计信号之间关系的声明性代码。断言覆盖率可以测量某断言被触发的频繁程度。断言可以跟随设计和测试平台一起仿真也可以被形式验证工具所证实。可以使用SV的程序性代码编写等效性检查但使用SVASV断言来表达会更容易。断言最常用于查找错误例如两个信号间的相位关系是否应该互斥或者请求与许可信号之间的时序等。 一旦检测到问题仿真就可以立即停止。 断言可以用于查找感兴趣的信号的值或者状态。 可以使用cover property来测量这些关心的信号的值或者状态是否发生。在仿真结束时仿真工具可以自动生成断言覆盖率数据。断言覆盖率数据以及其它覆盖率数据都会被集成在同一个覆盖率数据库中verifier可以对其展开分析。  
漏洞率以及漏洞曲线 
在一个项目实施期间应该保持追踪每周有多少个漏洞被发现。一开始当创建测试程序时通过观察可能就会发现很多漏洞。当设计逐渐稳定时需要利用自动化的检查方式来协助发现可能的漏洞。在设计临近流片时漏洞率会下降甚至有望为零。即便如此验证工作仍然不能结束。每次漏洞率下降时就应该寻找各种不同的办法去测试可能的边界情况corner case。 
漏洞率可能每周都有变化这跟很多因素都有关。不过漏洞率如果出现意外的变化可能预示着潜在的问题。 1.2 覆盖策略及覆盖组 覆盖策略只测量需要的内容例如初始化阶段不需要测试  只测试需要的内容验证工程师需要懂得在使能覆盖率收集时这一特性会降低很大的仿真性能。由于收集功能覆盖率数据的开销很大所以应该只测量你会用来分析并且改进测试的那部分数据。同时也需要设定合理的覆盖率采样的事件一方面提升采样效率一方面也可以降低收集覆盖率的开销。  验证的完备性完备的覆盖率测量结果和漏洞增长曲线可以帮助确认设计是否被完整地验证过。如果功能覆盖率高但代码覆盖率低这说明验证计划不完整测试没有执行设计的所有代码。如果代码覆盖率高但功能覆盖率低这说明即使测试平台很好地执行了设计的所有代码但是测试还是没有把设计定位到所有感兴趣的状态上。 你的目标是同时驱动高的代码覆盖率和功能覆盖率。  覆盖率比较    覆盖组covergroup  
覆盖组与类相似一次定义就可以多次实例化且全都在同一时间采集。一个覆盖组包含覆盖点选项形式参数和可触发(trigger)一个或多个数据点。 
covergroup可以定义在类中也可以定义在interface或者module中一个类里可以包含多个covergroupcovergroup可以采样任何可见的变量例如程序变量、接口信号或者设计端口。 
当你拥有多个独立的covergroup时每个covergroup可以根据需要自行使能或者禁止。每个covergroup可以定义单独的触发采样事件允许从多个源头收集数据。covergroup必须被例化才可以用来收集数据。 入门案例一个简单对象的功能覆盖率测试程序使用CovPort覆盖组对port字段的数值进行采样八种可能的数值32次随机。 interface busifc;logic clk;logic [31:0] data;logic [2:0] port;
endinterfaceclass Transaction;rand bit [31:0] data; rand bit [2:0] port; // 八种端口数据
endclass program automatic test(busifc.TB ifc);covergroup CovPortcoverpoint ifc.port; //测试覆盖率检测8个port是否都出现过endgroup initial begin Transaction tr; CovPort ck; ck  new(); // 实例化组tr  new(); repeat (32) begin 		  // 运行几个周期assert(tr.randomize); ifc.port  tr.port;  // 发送到接口上ifc.data  tr.data;  ck.sample(); 		  // 收集覆盖率ifc.clk; 		      // 等待一个周期end end 
endprogram8中可能32次随机该例的VCS的覆盖率报告(一部分)如下 Coverage:87.50..........
bin         #hit       at least
:::::::::::::::::::::::::::::::::::
auto[1]       7           1
auto[2]       7           1
auto[3]       1           1
auto[4]       5           1
auto[5]       4           1
auto[6]       2           1
auto[7]       6           1例在类里使用功能覆盖率 class Transaction;rand bit [31:0] data; rand bit [2:0] port;
endclass class Transactor;Transaction tr; mailbox mbx_in;virtual busifc ifc;covergroup CovPort;coverpoint tr.port;endgroup // 由于覆盖组实例化在new里面因此在program不需要实例化function new(mailbox mbx_in, virtual busifc ifc); CovPort  new(); this.mbx_in  mbx_in; this.ifc  ifc;endfunction task main; beginmbx_in.get(tr); ifc.port  tr.port;ifc.data  tr.data; CovPort.sample();end endtask 
endclassinterface busifc;logic clk;logic [31:0] data;logic [2:0] port;
endinterfaceprogram automatic test(busifc ifc);Transaction tr;Transactor tr_c;mailbox mbx_in;initial begintr  new();mbx_in  new();tr_c  new(mbx_in,ifc);repeat (32) begin assert(tr.randomize); mbx_in.put(tr);tr_c.main();(posedge ifc.clk);endend
endprogrammodule top;busifc ifc();initial beginifc.clk0;forever #10 ifc.clk~ifc.clk;endtest test_u(ifc);
endmodule触发 covergroup由采样的数据和数据被采样的事件构成。当这两个条件都准备好以后测试平台便会触发covergroup。这个过程可以通过直接使用sample()函数完成也可以在covergroup中采样阻塞表达式或者使用wait或实现在信号或事件上的阻塞。如果想在代码中显式地触发covergroup采样或者不存在采样时刻的信号或事件又或者一个covergroup被例化为多个实例需要单独触发那么可以使用sample()方法。如果你想借助已有的事件或者信号触发covergroup可以在covergroup声明中使用阻塞语句。 使用事件触发 event trans_ready;
covergroup CovPort (trans_ready);coverpoint ifc.cb.port;
endgroup与直接调用sample()相比使用事件触发的好处在于你能够借助已有的事件,来决定何时开始收集数据。  
1.3 覆盖率数据采样 
当在覆盖点上指定一个变量或者表达式时SV便会创建很多的仓bin来记录每个数值被捕捉到的次数。这些bin是衡量覆盖率的基本单位。为了计算出一个点上的覆盖率首先要了解域的概念域是所有可能值的的个数。覆盖率就是采样值的数目除以域中bin的数目。 
covergroup中可以定义多个coverpointcoverpoint中可以自定义多个cover bin或者SV帮助自动定义多个cover bin每次covergroup采样SV都会在一个或者多个cover bin中留下标记用来记录采样时变量的数值和匹配的cover bin。 
例如一个3bit变量的域为0:7正常情况下会除以8个bin如果在仿真的过程中只有7个值被采样到那么报告就会给出这个coverpoint点的覆盖率是7/8也即87.5%。所有这些coverpoint点组合在一起就是covergroup组的覆盖率所有covergroup组组合在一起就是整个的仿真覆盖率。而这也仅仅是单个仿真的情况在实际中需要追踪覆盖率随时间的变化情况分析趋势。 
1.3.1 bin的创建与使用 
SV会默认为某个coverpoint创建bin用户也可以自己定义bin的采样域。如果采样变量的域范围过大而又没有指定bin那么系统会默认分配64个bin将值域范围平均分配给这64个bin。用户可以通过covergroup的选项auto_bin_max来指定自动创建bin的最大数目。 
实际操作中自动创建bin的方法不实用建议用户自行定义bin整体的去定义或定义单独的点或者减小auto_bin_max的数值。 
covergroup covport;// 所有coverpoint auto_bin数量8option.auto_bin_max  8; // 特定coverpoint auto_bin数量2coverpoint tr.port {option.auto_bin_max  2;} 
endgroup延用本章的入门案例port位宽为3值域是0个可能的值因此第一个仓保存的是值域范围的前半段0-3第二个仓保存的是后半段4-7VCS给出的覆盖率报告部分如下 
bin         #hit     at least
:::::::::::::::::::::::::::::::::::
auto[0-3]    15        1
auto[4-7]    17        1除此之外还可以单独命名覆盖点的仓例如下面对一个4bit的变量kind进行采样有16种可能对其进行单独的覆盖采样 第一个仓命名为zero对kind0的情况进行计数 第二个仓命名为lo对1~35这四个值进行计数 第三个仓命名为hi将8~15保存到单独的仓里分别为hi_8hi_9hi_ahi-b … hi_f 第四个仓命名为misc对前面没有出现过的值进行采样也即467 covergroup CovKind;coverpoint tr.kind {bins zero  {0}; // 1个仓代表kind**0bins lo  {[1:3], 5}; // 1个仓代表1:3和5bins hi[]  {[8:$]}; // 8个独立的仓代表8:15bins misc  default; // 1个仓代表剩余的所有值} // 没有分号
endgroup注意coverpoint定义使用{}而不是begin…end大括号的结尾没有带分号;VCS的部分报告如下 
Bin       #hits     at least
:::::::::::::::::::::::::::::::::::
hi_8        0          1
hi_9        5          1
hi_a        3          1
hi_b        4          1
hi_c        2          1
hi_d        2          1
hi_e        9          1
hi_f        4          1
lo          16         1
misc        15         1
zero        1          11.3.2 条件覆盖率 
可以使用关键词iff给coverpoint添加条件。这种做法常用于在复位期间关闭覆盖以忽略不合理的条件触发。 
例仅收集reset0(高电平有效)时port的值。 
covergroup CoverPort;coverpoint port iff(!bus_if.reset);
endgroup同样的也可以使用start和stop函数来控制 covergroup各个独立实例。 
initial begincovport ck  new();// 复位期间停止收集覆盖率#1nsck.stop();bus_if.reset  1;#100ns bus_if.reset  0;// 复位结束ck.start();... 
end1.3.3 翻转覆盖率 
coverpoint也可以用来记录变量从A值到B值的跳转情况。还可以确定任何长度的翻转次数。 
例查询port有没有从0变为1,2,3。 
covergroup CoverPort;coverpoint port {bins t1  {(0  1), (0  2), (0  3)};}
endgroup1.3.4 wildcard覆盖率 
可以使用关键字wildcard来创建多个状态或者翻转。在表达式中任何X,Z或者?都会被当成0或1的通配符。 
例如采样偶数与奇数两个仓分别代表奇数偶数。 
bit [2:0] port;
covergroup CoverPort;coverpoint port {wildcard bins even  {3b??0};wildcard bins odd  {3b??1};}
endgroup1.3.5 忽略bin与非法bin 忽略bin排除那些不用来计算覆盖率的数值 在某些coverpoint可能始终无法得到全部的域值。对于那些不计算功能的域值可以使用ignore_bins来排除最终它们并不会计入coverpoint的覆盖率。 例1使用ignore_bins的覆盖点 bit [2:0] low_ports_0_5; // 只使用数值0-5
covergroup CoverPort;coverpoint low_ports_0_5 {ignore_bins hi  {[6,7]}; // 忽略数值6-7}
endgroup由于忽略了数值6-7因此总仓数是6 例2使用ignore_bins和auto_bin_max的覆盖点 bit [2:0] low_ports_0_5; // 只使用数值0-5
covergroup CoverPort;coverpoint low_ports_0_5 {options.auto_bin_max4;   // 0:1 2:3 4:5 6:7ignore_bins hi  {[6,7]}; // 忽略数值6-7}
endgroup创建了四个仓但由于最后一个仓被ignore_bins所忽略所以只有三个仓被创建因此覆盖率只有四种可能值分别为0%33%,66%和100%。  非法bin有些采样值不仅应该被忽略如果出现了还应该报错。 这种情况可以在测试平台中监测也可以使用illegal_bins对特定的bin进行标示。 bit [2:0] low_ports_0_5; // 只是用数值0-5
covergroup CoverPort;coverpoint low_ports_0_5 {illegal_bins hi  {[6,7]}; // 如果出现6-7便报错}
endgroup1.4 交叉覆盖率 
coverpoint是记录单个变量或者表达式的观测值。如果像记录在某一时刻多个变量之间值的组合情况需要使用交叉cross 覆盖率。cross语句只允许带coverpoint或者简单的变量名。 
class Transaction;rand bit [3:0] kind;rand bit [2:0] port;
endclassTransaction tr;
covergroup CovPort;kind: coverpoint tr.kind;port: coverpoint tr.port;cross kind, port;
endgroup关心kind与port的组合情况的覆盖率。 
1.4.1 排除部分cross bin 
通过使用ignore_bins、binsof和intersect分别指定coverpoint和值域 这样可以清除很多不关心的cross bin 
covergroup Covport;port: coverpoint tr.port{bins port[]  {[0:$]};}kind: coverpoint tr.kind {bins zero  {0};bins lo  {[1:3]};bins hi[]  {[8:$]};bins misc  default;}cross kind, port {ignore_bins hi  binsof(port) intersect {7};ignore_bins md  binsof(port) intersect {0}binsof(kind) intersect {[9:11]};ignore_bins lo  binsof(kind.lo);}
endgroup1.4.2 精细化交叉覆盖率 
随着cross覆盖率越来越精细需要花费不少的时间来指定哪些bin应该被使用或者被忽略。更适合的方式是不使用自动分配的cross bin自己声明感兴趣的cross bin。假如有两个随机变量a和b只关心下面三种状态{a**0,b**0}、 {a**1,b**0}和{b**1}。 
class Transaction;rand bit a, b;
endclass
covergroup CrossBinNames;a: coverpoint tr.a{ bins a0  {0};bins a1  {1};// 不计算覆盖率type_option.weight0;}b: coverpoint tr.b{ bins b0  {0};bins b1  {1};// 不计算覆盖率type_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上述的代码等效于 
class Transaction;rand bit a, b;
endclass
covergroup CrossBinsofIntersect;a: coverpoint tr.a{ // 不计算覆盖率type_option.weight0; }b: coverpoint tr.b{// 不计算覆盖率type_option.weight0; }ab: cross a,b{ bins a0b0  binsof(a) intersect {0}  binsof(b) intersect {0};bins a1b0  binsof(a) intersect {1}  binsof(b) intersect {0};bins b1  binsof(b) intersect {1}; }
endgroup1.4.3 单个实例的覆盖率 
如果对一个covergroup例化多次那么默认情况下SV会将所有实例的覆盖率合并到一起。如果需要单独列出每个covergroup实例的覆盖率则需要设置覆盖选项。 
covergroup CoverLength;coverpoint tr.length;// 设置单个实例覆盖率option.per_instance  1;
endgroup1.4.4 注释 
如果有多个covergroup实例可以通过参数来对每一个实例传入单独的注释。这些注释最终会显示在覆盖率数据的总结报告中。 
covergroup CoverPort(int lo,hi, string comment);option.comment  comment;option.per_instance  1;coverpoint port{bins range  {[lo:hi]};}
endgroup
... 
CoverPort cp_lo  new(0,3,Low port numbers);
CoverPort cp_hi  new(4,7,High port numbers);1.4.5 覆盖率次数限定与目标 覆盖率次数限定 默认情况下数值采样了1次就可以计入有效的bin。可以通过修改at_least来修改每个bin的数值最少的采样次数如果低于at_least数值则不会被计入bin中。 option.at_least可以在covergroup中声明来影响所有的coverpoint也可以在coverpoint中声明来只影响该coverpoint下所有的bin。 一般不会更改。  覆盖率目标 一个covergroup或者一个coverpoint的目标是100%覆盖率。 不过你也可以将其设置为低于100%的目标。这个选项只会影响覆盖率报告。 covergroup CoverPort;coverpoint port;option.goal  90;
endgroup添加上之后如果达到了90%报告就会显示100%一般也不会更改  
1.4.6 covergroup方法总结 
sample()采样。 
get_coverage()/get_inst_coverage()获取覆盖率返回0-100的real数值。 
set_inst_name(string)设置covergroup的名称。 
start()/stop()使能或者关闭覆盖率的收集。 
覆盖率分析 使用$get_coverage()可以得到总体的覆盖率。也可以使用covergroup_inst.get_inst_coverage()来获取单个covergroup实例的覆盖 。这些函数最实际的用处是在一个测试当中监测覆盖率的变化。如果覆盖率水平在一段时间之后没有提高那么这个测试就应该停止。重启新的随机种子或者测试可能有望提高覆盖率。如果测试可以基于功能覆盖率采取一些深入的行动例如重新限定随机的约束那是一件非常好的事情但这种测试很难编写。  
现在很少去用命令行分析了都是采用图形化界面的方式去分析 
1.4.7 案例 
添加bins并收集coverage信息查看 bins的收集情况 
TIPS makefile elab的时候要添加覆盖率选项 -cm tglbranch run中也要添加 -cm tglbranch -cov_dir top_cov 
查看报告: dve -full64 -cov -dir top_cov/top.simv.vdb 
生成报告urg -dir top_cov/top.simv.vbd -format both -report report -dirvbd文件 -format生成的格式txt或htmlboth是两者都要生成 -report报告文件目录 class Transaction;rand bit [4:0] data; rand bit [2:0] port;
endclass class Transactor;Transaction tr; mailbox mbx_in;virtual busifc ifc;covergroup CovPort;port: coverpoint tr.port {bins port[]  {[0:$]};}data: coverpoint tr.data{bins zero  {0}; bins lo  {[1:3]};bins hi[]  {[8:$]};bins misc  default;}cross port,data;endgroup // 由于覆盖组实例化在new里面因此在program不需要实例化function new(mailbox mbx_in, virtual busifc ifc); CovPort  new(); this.mbx_in  mbx_in; this.ifc  ifc;endfunction task main; beginmbx_in.get(tr); ifc.port  tr.port;ifc.data  tr.data; CovPort.sample();end endtask 
endclassinterface busifc;logic clk;logic [31:0] data;logic [2:0] port;
endinterfaceprogram automatic test(busifc ifc);Transaction tr;Transactor tr_c;mailbox mbx_in;initial begintr  new();mbx_in  new();tr_c  new(mbx_in,ifc);repeat (32) begin assert(tr.randomize); mbx_in.put(tr);tr_c.main();ifc.clk;endend
endprogrammodule top;busifc ifc();initial beginifc.clk0;forever #10 ifc.clk~ifc.clk;endtest test_u(ifc);
endmodule