持续更新一些有用的SVA语法/语句:
1. “intersect”构造
intersect构造和and构造相同,即:用来逻辑地组合两个系列,当两个序列都成功时整个属性才成功。intersect构造要求两个序列必须在相同时刻开始且在相同时刻结束,即:两个序列的起始点和结束点都要相同。用处:
使用intersect控制序列的长度
如,
property p62;
@(posedge clk) 1[*2:5] intersect
(a ##[1:$] b ##[1:$] c);
endproperty
a62:assert property(p62);
(1)表达式a ##[1:$ ] b #̲#[1:$] c表明,如果信号a为高,那么从下一个时钟周期开始信号b最终将为高,接着在下一个时钟周期开始信号c最终也会为高。也就是说这个序列每当信号a为高时就开始,并且可能一直到整个仿真结束时才成功
(2)使用1[*2:5] intersect来加以约束,1[*2:5]表示1持续2~5个周期
(3)最终属性P62的含义为:从序列的开始有效点(信号a为高)到序列成功的结束点(信号c为高),一共经过2~5个时钟周期
2. if else
property my_chk();
@(posedge clk) disable iff(~rst_n)
a|b |-> if(a) ($past(a, 2) === 1'b1)
else ($past(a, 1) === 1'b1);
endproperty
3.“throughout”构造
蕴含:允许定义前提条件的一项技术。如,要对一个指定的序列进行检验,必须某个前提条件为真(先行算子)。蕴含只在时钟边沿检验前提条件一次,然后就开始检验后续算子部分,因此它不检测先行算子是否一直保持为真。
“throughout”运算符:保证某些条件在整个序列的验证过程中一直为真。其基本语法是:
(expression) throughout (sequence definition)
例如:
property p9;
@(posedge clk) $fell(start) |->
(!start) throughout (##1 (!a && !b) ##1 (c[->3]) ##1 (a&&b));
endproperty
a9:assert property(p9);
属性p9检查以下内容:
(1)在信号start的下降沿开始检查(先行算子:$fell(start))
(2)start下降沿一个周期后,检查a和b是否均为0,如果为0则继续检查c[->3],如果匹配成功,则一个周期后检查a和b是否均为1,即:检查表达式(##1 (!a && !b) ##1 (c[->3]) ##1 (a&&b))
(3)序列检查在信号a和b下降沿(!a&&!b)与信号a和b上升沿(a&&b)之间,信号c应该连续或间断地出现3次高电平(c[->3])
(4)在整个检验过程中,信号start保持为低( (!start) throughout),如图所示
在第二个点,虽然表达式(##1 (!a && !b) ##1 (c[->3]) ##1 (a&&b))成立,但是start后面变为高电平,使整个序列失败。
4."within"构造
“within”构造允许在一个序列中定义另一个序列。基本语法:
seq1 within seq2
表示seq1在seq2的开始到结束的范围内发生,且序列seq2的开始匹配点必须在seq1的开始匹配点之前,序列seq2的结束匹配点必须在seq1的结束匹配点之后,即:seq2将seq1包在里面。例如:
property p10;
@(posedge clk) $fell(start) |->
((!a&&!b) ##1 (c[->3]) ##1 (a&&b)) within
($fell(start) ##[5:10] $rose(start))
endproperty
a10:assert property(p10)
5.局部变量
在序列或者属性的内部可以局部定义变量,而且可以对这种变量进行赋值。变量接着子序列放置,用逗号隔开。如果子序列匹配,那么变量赋值语句执行。每次序列被尝试匹配前,会产生变量的一个新的备份。
创建计数器
property check_counter;
int L_cnt;
@(posedge clk)
(
($rose(start),L_cnt = 0)##1
(1,L_cnt = L_cnt+1)[*0:$] ##1 (L_cnt == 30) |-> (irq ==1)
);
endproperty
可变的时钟延迟
property check_counter;
int L_cnt;
@(posedge clk)iff(!rst_n)
(
($fell(start),L_cnt = 30)##1
(1,L_cnt = L_cnt-1)[*0:$] ##1 (L_cnt == 0) |-> (irq == 1)
);
endproperty
参考文档: