验证分为动态仿真静态/形式检查两种方式

动态仿真通过测试序列和激励驱动DUT,然后判断输出是否符合预期。需要仿真器的配合

静态检查不需要仿真,它分为多个种类:

  • 语法检查
  • 语义检查
  • 跨时钟域检查
  • 形式验证:形式验证分为等价性检查(EC)和属性检查(PC)。EC用来保证两个电路等价,PC

覆盖率用于衡量设计完整性。覆盖率工具会收集信息,然后生成覆盖率报告,通过修改或创建新的测试来填补盲区,然后将这些测试结果合并。

覆盖率类型:代码覆盖率,断言覆盖率、功能覆盖率

代码覆盖率具体分类:

  1. 行覆盖率: 哪些行代码被执行过
  2. 路径覆盖率: 具体哪些代码和表达式被执行过
  3. 翻转覆盖率: 触发器的值为0或1
  4. 状态机覆盖率

功能覆盖率是用户定义的,功能覆盖率达到100%可以说明某些令人关注的情况已经被覆盖,但是测试点不一定被完全覆盖,

覆盖率具体表现为代码中的一个个覆盖点,覆盖点定义于覆盖组(covergroup)中,而覆盖组可以定义于class、interface、module中

module cov;
logic clk;
logic [7:0] addr;
logic [7: 0] waddr;
logic wr_rd;
logic [3: 0] a, b;
covergroup cg @(posedge clk);
c1: coverpoint addr;
c2: coverpoint wr_rd;
c3: coverpoint waddr {
bins b1 = {0, 2, 7};
bins b2 = {[30: 40], [50: 60], 77};
bins b3 = {200:$};
bins b4 = {10=>20=>30}; // 必须要连续的三个写地址为10,20,30这个点才被覆盖
bins b5 = {1,5 => 6, 7}; // 1=>6 || 1=>7 || 5=>6 || 5=>7
bins b6 = {0=>2[->2]=>1]}; // 首先为0,然后两次2(不要求连续),然后一次1
illegal_bins b7 = {255}; // 碰到便会停止
ignore_bins b8 = {254}; // 忽略一些取值
};
axb: cross a, b; // 交叉积,会产生16x16=256个bin
c4: coverpoint port iff(!rst); // 当rst为1时不收集覆盖率
endgroup : cg
cg cover_inst = new();
...
endmodule

对于覆盖点addr,会有c1.auto[0],c1.auto[1]等256个bin被自动创建
对于覆盖点waddr,通过手动控制创建测试点

测试:

module tb;

// Declare some variables that can be "sampled" in the covergroup
bit [1:0] mode;
bit [2:0] cfg;

// Declare a clock to act as an event that can be used to sample
// coverage points within the covergroup
bit clk;
always #20 clk = ~clk;

// "cg" is a covergroup that is sampled at every posedge clk
covergroup cg @ (posedge clk);//覆盖组中只有mode,取值范围为0~3,而且没有创建bin,这样系统自动创建4个bin
coverpoint mode;
endgroup

// Create an instance of the covergroup
cg cg_inst;

initial begin
// Instantiate the covergroup object similar to a class object
cg_inst= new();

// Stimulus : Simply assign random values to the coverage variables
// so that different values can be sampled by the covergroup object
for (int i = 0; i < 5; i++) begin
@(negedge clk);
mode = $random;
cfg = $random;
$display ("[%0t] mode=0x%0h cfg=0x%0h", $time, mode, cfg);
end
end

// At the end of 500ns, terminate test and print collected coverage
initial begin
#500 $display ("Coverage = %0.2f %%", cg_inst.get_inst_coverage());
$finish;
end
endmodule

covergroup的方法:

  • sample(): 采样
  • get_coverage() / get_inst_coverage(): 获得覆盖率
  • set_inst_name(string): 设置covergroup的名称
  • start() / stop()
  • $get_coverage(): 获得总体覆盖率