目录
1.何为断言
断言主要用来检查仿真过程中存在的时序问题,如果存在异常情况,断言会报警。一般在数字电路设计中都要加入断言,断言占整个设计的比例应不少于30%。
2.断言的作用:
- 使用断言可以缩短研制周期;
- 使用断言可以使设计中存在的各种问题更容易被动态监测观察;
- 使用断言内嵌的覆盖率统计功能(cover)可以更加容易的获得对于功能的覆盖性;
- 断言的可读性较一般描述语言更容易理解;
- 通过全局控制实现设计中断言的开关;
- 断言可以加速形式验证,提高形式验证的效率;
3.断言的种类
断言分为立即断言和并行断言;
3.1立即断言
立即断言主要用来检查当前仿真时间的条件,可以理解为if...else,放在过程块中使用。
语法:
labels:assert(expression)action_block;
- action_block 操作块在断言表达式的求值之后立即执行
- 操作块指定在断言成功或失败时采取什么操作
- action_block: pass_statement; else fail_statement;
例子:assert(expression) $display("expression evaluates to true");else $fatal("expression evaluates to false");断言失败默认严重程度为error,error达到一定数量仿真会退出;
立即断言构建思路:
3.2并发断言
- 并发断言仅在有时钟周期的情况下出现
- 测试表达式是基于所涉及变量的采样值在时钟边缘进行计算的
- 可以在过程块、module、interface和program块内定义并发断言
- 区别并发断言和立即断言的关键字是property
格式:断言名: assert property (判断条件)例子:check_a_and_b:assert property (@(posedge clk) (a&&b))$display("a&&b is true");else$error ("a&&b is false");
4.断言层次结构
4.1 sequence 序列
sequence具有如下特性:• 可带参数;• 可以在 property 中调用;• 可以使用局部变量;• 可以定义时钟周期;sequence的定义格式如下:sequence name_of_sequence(参数);……endsequence
以下代码分别通过property,sequence+property实现对a&&b仿真时间的判断:
//1.使用property实现对a&&b时序的判断
check_a_and_b:assert property(@(posedge clk) (a&&b))
$display("a&&b is true");
else
$error("a&&b is false");
//2.使用sequence+property实现对a&&b时序的判断
sequence seq_a_and_b;
@(posedge clk) a&&b;
endsequence
//在断言的property中调用sequence
check_a_and_b: assert property(seq_a_and_b)
$display("a&&b is true");
else
$error("a&&b is false");
sequence 序列可以带参数:
格式:sequence seq1(signal1,signal2);@(posedge clk) signal1&&signal2;endsequence
用法:
sequence seq1(signal1,signal2);
@(posedge clk) signal1&&signal2;
endsequence
//在断言的property中调用sequence
check_a_and_b: assert property(seq1(a,b))
$display("a&&b is true");
else
$error("a&&b is false");
sequence 序列可以有时序
sequence seq2;
@(posedge clk) a ##2 b ;
endsequence
//在断言的property中调用sequence
check_a_and_b: assert property(seq2);
格式sequence seq1;@(posedge clk) a&&b;endsequencesequence seq2;seq1;endsequence
4.2 property 序列
property的定义格式如下:property name_of_property(参数列表);测试表达式或复杂的sequence;endpropertyproperty就是SVA中需要用来判定的部分,用来模拟过程中被验证的单元,它必须在模拟过程中被断言来 发挥作用,SVA提供了关键字 assert 来检查属性,assert的基本语法是:assertion_name: assert property(property_name)else$display("SVA error");
并行断言构建思路:
5.sequence和property的异同
- 任何在sequence中的表达式都可以放到property中;
- 任何在property中的表达式也可以搬到sequence中,但是只有在property中才能使用蕴含操作符;
- property中可以例化其他property和sequence,sequence中也可以调用其他sequence,但是不能例化property;
- property需要用cover /assert/assume 等关键字进行实例化,而sequence直接调用即可;
除了以上的区别外,立即断言和并发断言的采样时间是否相同也是验证过程中需要注意的问题,以下的代码进行演示:
//SVA
module inline(
input clk,
input a,
input b,
input [7:0] d1,
input [7:0] d2,
output[7:0] d3,
output[7:0] d4
);
reg [7:0] d3=8'h0;
reg [7:0] d=48'h0;
always@(posedge clk) begin
if(a) begin
d3<=d1;
end
if(b) begin
d4<=d2;
end
end
endmodule
module top;
reg clk;
reg a;
reg b;
reg [7:0] d1;
reg [7:0] d2;
wire [7:0] d3;
wire [7:0] d4;
initial begin
$fsdbDumpfile("wave/top.fsdb");
$fsdbDumpvars();
$fsdbDumpSVA();
end
initial begin
#0 clk=0;
forever begin
#5 clk=~clk;
end
end
always begin
a<=$random()%2;
b<=$random()%2;
d1<=$random()%256;
d2<=$random()%256;
end
// immesiate assertions
always@(posedge clk) begin
check_a_and_b:assert(a&&b) $display("a&&b is turn");
else $error("a&&b is false");
end
// concurrent assertions
property p_mutex;
@(posedge clk) not(a&&b);
endproperty
a_mutex: assert property(p_mutex)$display("a&&b is success");
else $error("a&&b is fail");
initial begin
#300;
$finish;
end
inline inline_1(clk,a,b,d1,d2,d);
endmodule
波形展示:
以上代码对a&&b分别进行了immediate和concurrent assertions,波形显示两种断言结果完全相同,都在时钟上升沿前进行采样。
6.补充知识点(assert/cover/assume)
assert:
- 动态仿真中,如果仿真工具运行测试用例时发现断言失败,就会打印出相应的信息。
- 形式化验证中,assertion就是Formal验证工具(例如cadence的jasperGold)的证明目标。Formal验证工具会遍历所有的合法场景,在数学上证明这个断言永远不会失败。还是那句话,仿真只能“证伪” ,而Formal验证具有可以“证明”的能力。
cover:
- 动态仿真中,覆盖率是一个非常关键的数据,表明验证人员关注的场景是否真的在用例测试时被覆盖到。通常,需要确保每个测试点都至少被覆盖过一次,不然就说明我们的测试存在潜在的风险。
- 形式化验证中,cover也起着重要的作用。尽管理论上Formal覆盖DUT所有的场景,但是如果我们对设计过约了,可能还是会遗漏关键的场景测试。这时候,我们仍然需要使用cover来证明,我们确实对这个场景进行了有效的验证和覆盖。
assume:
- 动态仿真中,对于assume和assert的处理是完全相同的。EDA仿真器会在执行测试用例的时候检查assume是否失败,如果失败就会打印相应的信息。但是在概念上,assume和assert还是有些区别的:assume失败意味着验证环境或者周边设计可能出现了问题,即所测设计激励的行为不符合预期;而assert失败意味着DUT设计的行为不符合预期。
- 形式化验证中,assume和assert有着很明显的区别。就和字面意思一样,assume是作为设计的约束,会引导Formal工具产生的合法输入空间。如果没有assume,Formal工具会尽可能地遍历所有的空间,像空气一样到达他能够触及的空间。大多数情况,设计都会使用assume降低FPV的复杂度。
7.写在后边
关于property中的蕴含操作符部分,博主将在下一篇文章中进行总结;
博客地址:博客地址https://blog.youkuaiyun.com/weixin_45680021/article/details/131264689?spm=1001.2014.3001.5501