前言:仿真的时候,需要观察某些程序运行的结果是否符合预期,这一需求一般是通过断言来实现。
断言的评估和执行包括一下三个阶段:
always_comb
begin
a_aia : assert (a&&b);//assert 断言
end
a_cc : assert property(@(posedge cik) not(a&&b)); //
有property的是并发断言,后边跟的时钟。
sequence name_of_sequence;
< test expression>;
endsequence
-多个序列可以逻辑组合生成更复杂的序列,使用属性property来表示 。例如序列1发生导致序列2发生。
property name_of_property;
<test expression>; or
<comples sequence expressions>;
endproperty
//rose 从0变为1
$rose(expression or signal)
//fell 从1变为0
$fell(expression or signal)
//stable值没发生变化
$stable(expression or signal)
sequence s2;
@(posedge clk) $rose(a);//从0变为1
endsequence
sequence s3_lib (a,b);
a||b;
endsequence
sequence s3_lib_inst1;
s3_lib(req1,req2);
endsequence //这两个序列完成了嵌套
## 表示时钟周期延迟。
sequence s4;
@(posedge clk ) a##2 b; //默认a为高 过两拍后 b是否为高
endsequence
在工作中的流程一般为:
断言执行块
SV语言被定义在断言检查失败时,仿真器会打印信息,对于成功的断言,仿真器不会打印信息 。
蕴含(implication)等效于if then。
交叠蕴含使用->表示
非交叠蕴含使用=>表示
property p12;
@(posedge clk) (a&&b) |-> ##[1:3] c;
endproperty
a12: assert property(p12);
a和b同时为高后的 1-3个周期内,c至少有一个周期为高。
$past构造
$past(signal_name, number of clock cycles)
连续重复运算符[ * n]
signal or sequence [*n]
a[ *1:5 ]表示a从某个时钟周期开始重复1-5次
[->]跟随重复运算符
非连续重复运算符[=m]
二者区别:
and
and可以用来逻辑地组合两个序列,当两个序列都成功时,属性才算成功。
两个序列必须具有相同的起始点,但是可以有不同的结束点。
检验的起始点是第一个序列的成功时的起始点,结束点是使得属性最终成功的另一个序列成功时的结束点。
sequence s27 a;
@(posedge clk) a##[1:2] b; //a为高过了1到2拍b为高
endsequence
sequence s27 b;
@(posedge clk) c##[2:3] d;
endsequence
property p27;
@(posedge clk) s27a and s27b;
endproperty
intersecct
or
first_match
throughout
within
seq1 within seq2
表示seq1在seq2的开始到结束范围内发生
其他
disable iff
expect
有两种方法可以将SVA检验器连接到设计中。
(1)在模块定义中内建或者内联检验器。
(2)将检验器与模块、模块的实例或者一个模块的多个实例绑定。
注意,定义检验器模块时,他是一个独立的实体。检验器用来检验一组通用的信号,检验器可以与设计中任何的模块或者实例绑定,绑定的语法如下所示。
bind<module_name or instance name>
<checker name> <checker instance name>
<design signals>;
<cover_name>: cover property (property name)\
cover_name是用户提供的名称,用来标明覆盖语句,property_name是用户想获得覆盖信息的属性名。
cover语句的结果包含下面的信息:
(1)属性被尝试检验的次数。
(2)属性成功的次数。
(3)属性失败的次数。
(4)属性空成功的次数。
检验器mutex_chx在一次模拟中的覆盖日志的实例如下所示:
c_mutex,12 attempts,12 match,0 vacuous match
就像断言(assert)语句一样,覆盖(cover)语句可以有执行块。在一个覆盖成功匹配时,可以调用一个函数(function)或者任务(task),或者更新一个局部变量。