断言操作符介绍

目录

1.延时操作符(##)

1.1 ##m

1.2 ##[m:n]

2.蕴含操作符(|=>,|->)

2.1 |=>操作符

2.2 |->操作符 

3 重复操作符 ([*m][->m][=m])

3.1 连续重复操作符([*m][*m:n])

3.2 跟随重复操作符([->m][->m:n])

3.3 非连续重复操作符([=m])

3.4 小结

4 SVA关键字

4.1 与或非

4.2 动态控制函数

4.3 SVA内嵌函数

4.4 SVA 序列表达式操作符

 4.5 SVA 周期表达式操作符


1.延时操作符(##)

1.1 ##m

带时序关系的sequence :在SVA中时钟延时用符号"##"来表示,如"##2"表示延时两个时钟周期;
示例:
sequence seq2;
        @(posedge clk) a ##2 b ;
endsequence
//在断言的property中调用sequence
check_a_and_b: assert property(seq2);
提示:##0  表示 sig1 sig2 必须同时发生才算成功 ,可见,在具体使用过程中,可以使用 ##0 表示两个事件在同一采样时刻同时发生

波形展示:

 sequence只有在时钟上升沿到来后检查a是否为1才会继续检查后面连续x个时钟后的b的值

1.2 ##[m:n]

##[m:n] 其中m和n都是非负数,m可以为0,n可以为$,n必须大于m,当n为$时,比 较耗费仿真资源,一般不建议使用.
示例:
sequence seq2;
        @(posedge clk) a ##[2:4] b ;
endsequence
//在断言的property中调用sequence
check_a_and_b: assert property(seq2);
波形展示:

 ##[m:n]”采取的是“就近匹配”原则,在第一个序列匹配后将不会在进行后续序列的匹配。

2.蕴含操作符(|=>,|->)

2.1 |=>操作符

示例:
property p1;
        @(posedge clk) sig1 |=> sig2;
endproperty // p1

波形展示:

 表示sig1在时钟上升沿时为高,在当前时钟上升沿的下一个时钟上升沿时sig2也必须为高

2.2 |->操作符 

示例:
property p1;
        @(posedge clk) sig1 |-> sig2;
endproperty // p1
波形展示:

sig1在时钟上升沿时为高,在当前时钟上升沿sig2也必须为高 

NOTE:在编写断言时尽量使用“|->”而不是“|=>”,因为你可以通过“|->”后增加时钟数实现“|=>”的功能, 但是不能通过“|=>”实现“|->”的功能。

断言操作符介绍_第1张图片

 断言时序判断note:例如(cat ##1 dog)|=> mouse

1. 首先判断cat是否为真,只有在cat为真的情况下才会进行后续判断,才会开启以上断言;

2. 遇到如果第二个clk如果依旧为cat,则将其作为初始cat进行判断(上图条件3);

3 重复操作符 ([*m][->m][=m])

当需要检查某个信号保持一种状态多个采样周期时,虽然在SVA中可以使用连续 ##1逐个指定该信号,如下例,sig1要在sig0为上升沿之后保持4个时钟周期的高电平。
示例:
……
@(posedge clk) $rose(sig0) |-> ##1 sig1 ##1 sig1 ##1 sig1##1 sig1;
……
虽然实现了特定的要求,但是这种实现方式明显很繁琐,为此,在 SVA 中提供了重复运算符,从而可以缩减繁琐的表达式。

3.1 连续重复操作符([*m][*m:n])

[*m]使用时表达式或者序列每次匹配间隔为一个采样周期,表达式或者序列必须连续重复匹配m次,m不能为$。
[*m:n]使用时表达式或者序列每次匹配间隔为一个采样周期,表达式或者序列重复m到n次,
当m次匹配后,即认为[*m:n]匹配成功,不会再对表达式进行后续的匹配判断,即其本身匹配
采取的是“就近匹配”原则。当然n的存在也是有一定意义的,如果[*m:n]后还存在其他表达
式或者序列,那么其他表达式或者序列的匹配检查点将不能超过第n次匹配。

断言操作符介绍_第2张图片

断言操作符介绍_第3张图片

 示例:

property p;
        @(posedge clk) $rose(a) |-> ##1 b[*2];
endproperty // p
波形展示:

提示:

在仿真中$rose并不是单纯的判断信号的跳边沿,而是判断时钟采样信号前后是否存在0->1/x->1/z->1的变化。

在仿真中$fell并不是单纯的判断信号的跳边沿,而是判断时钟采样信号前后是否存在1->/x->0/z->0的变化。

3.2 跟随重复操作符([->m][->m:n])

[->m]使用时表示表达式重复或者连续出现m次,但是整个重复表达式的最后一次匹配必须发生在其后续表达式匹配前的一个采样周期.
断言操作符介绍_第4张图片

 示例:

property p;
        @(posedge clk) a |-> ##1 b[->3] ##1 a;
endproperty // p

波形展示:

[->m]也有对应的[->m:n]方式,其差别与[*m][*m:n]差别类似,不再赘述 .

3.3 非连续重复操作符([=m])

[=m] [->m] 工作情况类似,唯一的区别是 [->m] 要求整个重复表达式的最后一次匹配必须发
生在其后续表达式匹配的前一个相邻采样周期,而 [=m] 并没有要求整个重复表达式的最后一
次匹配必须发生在一定的条件下.
断言操作符介绍_第5张图片

跟随重复的最后一次重复必须和下一个信号紧挨,例如上边的第一种情况,非连续重复则不需要。

示例:
property p1;
@(posedge clk) a |-> ##1 b[=3] ##1 a;
endproperty // p1
波形展示:

3.4 小结

重复运算符
说明
格式
连续重复
表达式或者序列在指定数量的采样
周期内连续的匹配,表达式或者序
列的每次匹配之间都有一个采样周
期的延迟
expror
sequence_name[*n]expror
sequence_name[*m:n]
跟随重复
表达式匹配达到指定的次数,而且
每次匹配不一定在连续的采样周期
上,被检验的重复表达式的最后一
个匹配应该发生在整个序列匹配结
束之前
expr[->n]expr[->m:n]
非连续重复
与跟随重复类似,除了它并不要求
信号的最后一次匹配发生在整个序
列匹配前的那个采样周期
expr[=n]expr[=m:n]

4 SVA关键字

4.1 与或非

1.and

and”可以按照逻辑与的方式组合两个序列,当两个序列都匹配时,整个属性成功。使用方式如下:
property p;
        sequence_1 and sequence_2;
endproperty //p
【注意】 sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点以两个sequence中最后一个成功的sequence的匹配点为属性的成功点。

断言操作符介绍_第6张图片

2. or 

“or”可以按照逻辑或的方式组合两个序列,当两个序列有一个匹配时,整个属性成功。使用方式如下:
property p;
        sequence_1 or sequence_2;
endproperty //p
【注意】 sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点取决于最早匹配成功的sequence,只要两个序列有一个匹配成功,整个属性就认为匹配。

断言操作符介绍_第7张图片

 3 not

“not” 虽然只是对序列结果取反,但是在 SVA 中,理解 not 时必须注意反向思维,否则可能混乱。因为not操作的对象为一个序列,所以 not 操作的起始和结束点与其操作的对象一致。使用方式如下:
property p;
        not (sequence);
endproperty //p

断言操作符介绍_第8张图片

4.2 动态控制函数

$ assert_task [(level[,list_of_modules_or_assertions])];
其中
assert_task 可以是 assertion assertoff assertkill 中的任何一个;
level 用于指定层以下哪几层设计受到函数的影响,如果 level 0 ,函数将影响指定层以下所有的设计;
list_of_modules_or_assertions 指定该函数作用于哪些模块或者断言(不能指向序列,但是可以指向属性);
这几个函数的具体意义如下:
$assertoff 暂时关闭所有断言的执行,如果该函数执行时断言正在执行,正在执行的断言不会被终止;
$asserton 重新启动断言执行;
$assertkill 将会终止设计中所有的断言,包括已经执行的断言。当遇到下一个断言需要开始执行时,该断言不会启动,除非使用 $asserton 启动;

4.3 SVA内嵌函数

常用的内嵌函数 :
$onehot(expression) : 该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位且仅有一位为高时,该函数即返回真。
$onehot0(expression) : 该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位为高或者没有任何位为高时,该函数即返回真。
$isunknown(expression) : 该函数用于检验表达式最终结果中的各位中是否有 x 或者z
$countones(expression) : 该函数主要用于获得信号中电平为高的位的个数。

4.4 SVA 序列表达式操作符

1 intersect

intersect两侧的表达式都是sequence,不能是property,使用intersect时需要 确保其两侧的sequence必须同时开始,且当两个sequence最终同时匹配时才认为两个序列的intersect匹配,即两个sequence匹配的长度必须相同 ,intersect操作符和and操作符很相似,但是and没有要求两个序列最终匹配时同时匹配。

断言操作符介绍_第9张图片

2 within 

within右侧sequence的起止点必须位于左侧sequence的起止点之外,当然within左右两侧sequence的起止点可以一样,整个“sequence_1 within sequence_2”匹配成功的结束点与右侧sequence的结束点一致。

断言操作符介绍_第10张图片

3 throughout 

在SVA中有时需要某些信号在一个序列的检查过程中一直保持一个状态,此时就可以使用throughout操作符,当这些信号的状态发生不期望的变化时,序列的检查即认为失败。

断言操作符介绍_第11张图片

 4.5 SVA 周期表达式操作符

1 $rose

在仿真中$rose并不是单纯的判断信号的跳边沿,而是判断时钟 采样信号前后 是否存在0->1/x->1/z->1的变化。其格式如下:
$rose(expression);
2 $fell
在仿真中$fell并不是单纯的判断信号的跳边沿,而是判断时钟 采样信号前后 是否存在1->/x->0/z->0的变化。其格式如下:
$fell(expression);
3 $stable
当表达式在连续两个采样时钟周期保持不变时返回真。其格式如下:
$stable(expression);
4 $past
$past主要用于检查当前表达式前一个时钟周期(如果不指定number_of_ticks,默认指向前一个时钟周期)值是否为真,如果位真则$past返回为真。其格式如下: $past(expression[,number_of_ticks]);
其中number_of_ticks可以指定检查当前时刻之前number_of_ticks个周期的采样值.
5 $changed
格式:
$changed(expression);
当表达式在前一个周期发生变化(不管是高低变化还是低高变化)时返回真,返回值类型为布尔类型。

你可能感兴趣的:(SV,System,Verilog,验证,uvm)