目录
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 周期表达式操作符
示例:sequence seq2;@(posedge clk) a ##2 b ;endsequence//在断言的property中调用sequencecheck_a_and_b: assert property(seq2);提示:##0 表示 sig1 和 sig2 必须同时发生才算成功 ,可见,在具体使用过程中,可以使用 ##0 表示两个事件在同一采样时刻同时发生
波形展示:
sequence只有在时钟上升沿到来后检查a是否为1才会继续检查后面连续x个时钟后的b的值;
##[m:n] 其中m和n都是非负数,m可以为0,n可以为$,n必须大于m,当n为$时,比 较耗费仿真资源,一般不建议使用.示例:sequence seq2;@(posedge clk) a ##[2:4] b ;endsequence//在断言的property中调用sequencecheck_a_and_b: assert property(seq2);
##[m:n]”采取的是“就近匹配”原则,在第一个序列匹配后将不会在进行后续序列的匹配。
示例:property p1;@(posedge clk) sig1 |=> sig2;endproperty // p1
波形展示:
表示sig1在时钟上升沿时为高,在当前时钟上升沿的下一个时钟上升沿时sig2也必须为高
示例:property p1;@(posedge clk) sig1 |-> sig2;endproperty // p1
sig1在时钟上升沿时为高,在当前时钟上升沿sig2也必须为高
NOTE:在编写断言时尽量使用“|->”而不是“|=>”,因为你可以通过“|->”后增加时钟数实现“|=>”的功能, 但是不能通过“|=>”实现“|->”的功能。
断言时序判断note:例如(cat ##1 dog)|=> mouse
1. 首先判断cat是否为真,只有在cat为真的情况下才会进行后续判断,才会开启以上断言;
2. 遇到如果第二个clk如果依旧为cat,则将其作为初始cat进行判断(上图条件3);
示例:……@(posedge clk) $rose(sig0) |-> ##1 sig1 ##1 sig1 ##1 sig1##1 sig1;……
[*m]使用时表达式或者序列每次匹配间隔为一个采样周期,表达式或者序列必须连续重复匹配m次,m不能为$。[*m:n]使用时表达式或者序列每次匹配间隔为一个采样周期,表达式或者序列重复m到n次,当m次匹配后,即认为[*m:n]匹配成功,不会再对表达式进行后续的匹配判断,即其本身匹配采取的是“就近匹配”原则。当然n的存在也是有一定意义的,如果[*m:n]后还存在其他表达式或者序列,那么其他表达式或者序列的匹配检查点将不能超过第n次匹配。
示例:
property p;@(posedge clk) $rose(a) |-> ##1 b[*2];endproperty // p
提示:
在仿真中$rose并不是单纯的判断信号的跳边沿,而是判断时钟采样信号前后是否存在0->1/x->1/z->1的变化。
在仿真中$fell并不是单纯的判断信号的跳边沿,而是判断时钟采样信号前后是否存在1->/x->0/z->0的变化。
示例:
property p;@(posedge clk) a |-> ##1 b[->3] ##1 a;endproperty // p
波形展示:
[->m]也有对应的[->m:n]方式,其差别与[*m]和[*m:n]差别类似,不再赘述 .
跟随重复的最后一次重复必须和下一个信号紧挨,例如上边的第一种情况,非连续重复则不需要。
示例:property p1;@(posedge clk) a |-> ##1 b[=3] ##1 a;endproperty // p1
重复运算符
|
说明
|
格式
|
连续重复
|
表达式或者序列在指定数量的采样
周期内连续的匹配,表达式或者序
列的每次匹配之间都有一个采样周
期的延迟
|
expror
sequence_name[*n]expror
sequence_name[*m:n]
|
跟随重复
|
表达式匹配达到指定的次数,而且
每次匹配不一定在连续的采样周期
上,被检验的重复表达式的最后一
个匹配应该发生在整个序列匹配结
束之前
|
expr[->n]expr[->m:n]
|
非连续重复
|
与跟随重复类似,除了它并不要求
信号的最后一次匹配发生在整个序
列匹配前的那个采样周期
|
expr[=n]expr[=m:n]
|
1.and
and”可以按照逻辑与的方式组合两个序列,当两个序列都匹配时,整个属性成功。使用方式如下:property p;sequence_1 and sequence_2;endproperty //p【注意】 sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点以两个sequence中最后一个成功的sequence的匹配点为属性的成功点。
2. or
“or”可以按照逻辑或的方式组合两个序列,当两个序列有一个匹配时,整个属性成功。使用方式如下:property p;sequence_1 or sequence_2;endproperty //p【注意】 sequence_1和sequence_2的检查起始点必须一样,但是两者结束的结束点可以不一样,整个属性的成功点取决于最早匹配成功的sequence,只要两个序列有一个匹配成功,整个属性就认为匹配。
3 not
“not” 虽然只是对序列结果取反,但是在 SVA 中,理解 not 时必须注意反向思维,否则可能混乱。因为not操作的对象为一个序列,所以 not 操作的起始和结束点与其操作的对象一致。使用方式如下:property p;not (sequence);endproperty //p
$ 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 启动;
常用的内嵌函数 :$onehot(expression) : 该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位且仅有一位为高时,该函数即返回真。$onehot0(expression) : 该函数主要用于在任意给定的采样事件,表达式最终结果中不管其他位为不定态还是高阻态,只要有一位为高或者没有任何位为高时,该函数即返回真。$isunknown(expression) : 该函数用于检验表达式最终结果中的各位中是否有 x 或者z 。$countones(expression) : 该函数主要用于获得信号中电平为高的位的个数。
1 intersect
intersect两侧的表达式都是sequence,不能是property,使用intersect时需要 确保其两侧的sequence必须同时开始,且当两个sequence最终同时匹配时才认为两个序列的intersect匹配,即两个sequence匹配的长度必须相同 ,intersect操作符和and操作符很相似,但是and没有要求两个序列最终匹配时同时匹配。
2 within
within右侧sequence的起止点必须位于左侧sequence的起止点之外,当然within左右两侧sequence的起止点可以一样,整个“sequence_1 within sequence_2”匹配成功的结束点与右侧sequence的结束点一致。
3 throughout
在SVA中有时需要某些信号在一个序列的检查过程中一直保持一个状态,此时就可以使用throughout操作符,当这些信号的状态发生不期望的变化时,序列的检查即认为失败。
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);当表达式在前一个周期发生变化(不管是高低变化还是低高变化)时返回真,返回值类型为布尔类型。