断言(SVA)

1、assertion作用

assertion用于设计功能和时序做比较的属性描述。
断言(assertion)可以用来完成:

  • 检查设计的内容
  • 提高设计的可视度和调试能力
  • 检查设计特性在验证中是否被覆盖
  • 可读性好,因此也可以用来服务于设计文档

用来检查算法模型的断言在形式验证(formal verification)中可以穷尽计算,找出可能的违例(violation)

可以自由地打开或关闭

一小部分子集甚至可以用来综合或者移植到emulation中,用来完成跨平台的移植

2、断言覆盖率

仿真工具可以报告断言覆盖率,来指示哪些断言没有被触发?
帮助检查是否验证计划捕捉到了所有需要的覆盖率
断言覆盖率和功能覆盖率可以共同量化验证进度
断言语言
在verilog中不支持断言,因此需要写过程语句来做代替

一些支持断言的语言:

Sugar(IBM)进化为PSL(Property Specification Language)
OVA-Vera
Specman/e
ForSpec(intel)
上述语言的有点功能进化为SVA,因此SVA作为SV相对独立的语言分支,值得我们花足够的精力来学习掌握它。

3、断言类型划分

== 立即断言(immediate assertion)==

  • 非时许的
  • 执行时如同过程语句
  • 可以在initial/always过程块或者task/function中使用
    == 并行断言(concurrent assertion)==
  • 时序性的
  • 关键词property用来区分立即断言和并行断言
  • 之所以称之为并行,是因为他们与设计模块一同并行执行

3.1立即断言

[name: ] assert (expression) [pass_statement] [else fail_statement]

time t;
always@(posedge clk)
	if(state == REQ)
		assert (req || req2)
		else begin
			t = $time;
			#5 $error("assert failed at time %0t", t);
		end

立即断言可以结合$ fatal/$ error/$ warning/$info给出不同严重级别的消息提示。

assert (myfunc(a,b)) count1 = count + 1; else ->event1;
assert (y==0) else flag = 1;
always @ (state)
  assert (state == $onehot) else $fatal;

3.2并行断言

base_rule1: assert property (cont_prop (rst, in1, in2)) pass_stat else fail_state;

Request-Grant协议描述:request拉高,在2个周期后,grant拉高,在1个周期后,request拉低,在1个周期后,grant拉低。

property req_grant_prop
	@(posedge clk) req ##2 gnt ##1 !req !gnt;
endproperty
assert property req_grant_prop else $error("Req-Gnt Protocol violation");

并行断言只会在时钟边沿激活,变量的值是采样到的值。
在这里插入图片描述
并行断言的执行阶段
SV的仿真调度机制如下图,并行断言的执行如下:

在preponed阶段采样稳定的变量值
在observe阶段执行并行断言
在reactive区域执行pass/fail语句
通过这种当时保证并行断言执行会采样的稳定的设计信号变量。
在这里插入图片描述

4. assertion, property, sequence

  • assertion可以直接包含一个property
  • assertion也可以清晰地独立声明property
assert property(@(posedge clk)
	disable iff(!reset)
	a |=>b ##1 c);

assert property(my_prop);
property my_prop;
	@(posedge clk)
		disable iff (!reset)
		a |=>b ##1 c;
endproperty

  • 在property内部可以有条件地关闭

  • property块可以直接包含sequence

  • 复杂的property也可以独立声明多个sequence

sequence s1;
	@(posedge clk) a ##1 b ##1 c;
endsequence
sequence s2;
	@(posedge clk) a ##1 c;
endsequence
property p1;
	@(posedge clk) disable iff(!reset)
	s1 |=> s2;
endproperty

4.1sequence

  • sequence是用来表示在一个或者多个时钟内的时序描述。

  • sequence是property的基本构建模块,并经过组合来描述复杂的功能属性。

sequence s1;
	@(posedge clk) a ##1 b ##1 c;
endsequence
sequence t1;
	(a ##[2:3] b) or (c ##[1:2] d);
endsequence

  • sequence用来提供下列场景描述:

    (1) 第一个时钟周期,第一个表达式成立的。
    (2) 接下来在若干个时钟周期后,第二个表达式也成立。
    (3) 以此类推,在接下来的若干个时钟周期,后续表达式也成立。

  • sequence可以在module、interface、program、clocking块和package中声明,一般在interface中声明。

  • sequence也可以提供形式参数,用来提高复用性

sequence s20_1(data, en);
  (!frame && (data==data_bus)) ##1 (c_be[0:3]==en);
endsequence

  • 蕴含(implication)操作符用来表示,如果property中左边的先行算子(antecedent)成立,那么property右边的后续算子(consequent)才会被计算。

  • 如果线性算子不成功,那么整个属性就默认地被认为成功,这叫做“空成功”(vacuous success)。

  • 蕴含结构只能用在属性定义中,不能再序列中使用。

  • 蕴含可以分为两类:交叠蕴含(overlapped implication)和非交叠蕴含(non-overlapped implication)。

    (1)|->交叠操作符

  • 如果条件满足,则评估其后续算子序列。

  • 如果条件不满足,则表现为空成功,不执行后续算子。
    在这里插入图片描述
    (2) |=>非交叠操作符

  • 如果条件满足,则在下一个周期评估其后续算子序列。

  • 如果条件不满足,则表现为空成功,不执行后续算子。
    在这里插入图片描述

4.1.1 基本操作符

1.##用来表示周期延迟符号,例如##n表示在n个时钟周期后,##0表示在当前周期,即交叠周期。

sequence a_b;
	@(posedge clk) a ##1 b;
endsequence

2.##[min : max]表示在一个范围内的时钟周期延迟。min、max必须是非负数,序列会在min到max时间窗口中最早的时间来匹配。

sequence a_b;
	@(posedge clk) a ##[1:5] b;
endsequence

3.$ 用来表示无穷大的周期(在仿真结束前),但是一般我们不建议这么做,因为他会增大仿真评估序列的负担。
时间也可以通过[*n]操作符来表示重复。n必须为非负数,其不能为$。

sequence a_b;
	@(posedge clk) a ##[1:$] b;
endsequence

4.时间也可以通过[*n]操作符来表示重复。n必须为非负数,其不能为$。

sequence a_b;
	@(posedge clk) a ##1 b[*2];
endsequence

5.类似的,也可以使用[*m:n]来标识一定范围内的重复事件。

sequence a_b;
	@(posedge clk) a ##1 b[*2:5];
endsequence

在这里插入图片描述
6.[=m]用来表示一个事件的连续新,需要重复发生m次,但是并不需要在连续周期内发生。

b[=3]表示b必须在3个周期内为1,但是并不需要是连续的3个周期。

sequence a_b;
	@(posedge clk) a ##1 b[=3];
endsequence

7.例如,执行了一次burst read操作,期望读的数据和ack信号在接下来的四个周期内返回,但是不需要连续的四个周期,即可以用[=4]来表示。

8.类似的,[=m:n]用来表示从最小m到最大n的重复发生的非连续周期次数。

9.a[*0]用来表示没有任何正数时钟周期内有效。

10.例如a[*0:3] ##1 b ##1 c与哪些情形匹配?

  • (b ##1 c)
  • (a ##1 b ##1 c)
  • (a ##1 a ##1 b ##1 c)
  • (a ##1 a ##1 a ##1 b ##1 c)
    11.and用来表示两个序列需要保持匹配

用法:seq1 and seq2

下列情形满足此操作符:

  • 在从两个起始点开始后,seq1和seq2均满足。
  • 满足的时刻发生在两个序列都满足的周期,即稍晚序列的满足时刻。
  • 两个序列的满足事件可以不同。
    如果操作符两边的序列都是用来衡量采样信号而非事件时序,那么- 则要在相同周期内,and左右两边的时序都应该满足条件。

12.intersect操作符

用法:seq1 intersect seq2

  • 需要两边的序列在同意时钟周期内匹配

  • 需要在同一时钟周期结束

13.or操作符

用来表示两个序列至少需要有一个满足

用法:seq1 or seq2

下列情形满足此操作符:

  • seq1和seq2都从同一个时刻被触发。
  • 最终满足seq1或者满足seq2。
  • 每一个序列的结束事件可以不同,结束时间以序列满足的最后一个序列时间为准。
    14.and/or应用
    如果burst write长度为4,那么写的长度可以为1,2,4。
property BurstLengthValid
	@(posedge clk) disable iff (!rst)
	((burstLen==4) |-> 
		(wrlen==1) or (wrlen==2) or (wrlen==4));
endproperty
assert property(BurstLengthValid)

15.first_match操作符

first_match用来从多次满足的序列中选择第一次满足时刻,从而放弃其他满足的时刻。

sequence t1;
	te1 ##[2:5] te2;
endsequence

t1序列可以用来匹配te1 ##2 te2,te1 ##3 te2,te1 ##4 te2,te1 ##5 te2。

sequence t1;
	first_match(te1 ##[2:5] te2);
endsequence

此序列用来选择第一次匹配的时刻。

16.throughout操作符

可以用来检查一个信号或者一个表达式在贯穿(throughout)一个序列时是否满足要求。

用法:sig1/exp1 throughout seq

例如,在burst模式信号拉低以后的2个周期时,irdy/trdy也应该在连续7个周期内保持为低,同时burst模式信号也应该在这一连续周期内保持为低。

sequence burst_rule1;
	@(posedge mclk)
	$fell(burst_mode) ##0
	(!burst_mode) throughout (##2 ((trdy==0) && (irdy==0)) [*7]);
endsequence

17.within操作符

可以用来检查一个序列与另一个序列在部分周期长度上的重叠

用法:seq1 within seq2

如果当seq1满足在seq2的一部分连续时钟周期内成立,seq1 within seq2成立。

例如,trdy需要在irdy下拉的一个周期后保持7个周期为低,同时irdy也将保持8个周期为低,一下序列会在第11个周期满足。

!trdy[*7] within (($fell irdy) ##1 !irdy[*8])

在这里插入图片描述

18.if操作符

可以在sequence中使用if…else

例如当master_req为高时,下一个周期,req1或者req2应该为高,如果req1为高,则下一个周期ack1为高,如果req2为高,则下一个周期ack2为高。

property master_child_regs;
	@(posedge clk) master_req ##1 (req1 || req2)
	if(req1)
	  (##1 ack1)
	else
	  (##1 ack2);
endproperty

19.检测序列的终点

用法:seq.ended

在某一时刻,序列如果及时抵达终点,那么条件满足。

例如,在inst为高的下一个周期,序列e1应该结束或者已经结束。

seqence e1;
	@(posedge sysclk) $rose(ready) ##1 proc1 ##1 proc2;
endsequence
seqence rule;
	@(posedge sysclk) reset ##1 inst ##1 e1.ended ##1 branch_back;
endsequence

20.局部变量

局部变量可以在sequence或者property中使用

这些变量会伴随这sequence、property动态创建

每一个sequence实例都会有自己的变量拷贝

例如在cache rdDone拉高后,读出的rdData会在2个周期后,在其基础上加1,并作为wrData写入。

sequence rd_cache_done;
	##[1:5] rdDone;
endsequence
sequence check_reg_wr_data;
	int local_data;
	(rd_cache_done, local_data=cache_rd_data) ##2 (reg_wr_data==(local_data+1));
endsequence

21.调用方法

在序列匹配时,可以调用task、void function和系统函数

例如,可以在s1序列末尾,分别打印出e和f变量被采样的数值。

sequence s1;
	logic v,w;
	(a,v=e) ##1
	(b[->1],w=f, $display("b after a with v = %h, w=%h\n",v,w))
endsequence

22.访问采样方法

  • 一些系统函数可以用来访问指定类型的采样变量

(1)用来访问当前周期采样值
(2)用来访问上一个采样周期
(3)用来检测采样变量的变化
$ rose(expression[,clocking_event])和$fell(expression[,clocking_event])用来表示与上一个采样周期相比,变量最低位是否跳变位1或者0,满足条件返回1,否则返会0,clocking_event在sequence中不需要单独提供,因为sequence中一般会指定采样时钟。

$stable(expression[,clocking_event]),用来表示两个采样周期内,表达式值保持不变,如果满足,返回1,否则,返回0。

$past(expr[, num_cycles][, gating_expr][, clocking_event])用来访问在过去若干采样周期前的数值。

在默认情况下,num_cycles=1,及采样1个周期前的数值。

例如,在ack拉高时的前两个周期,req信号应该为高。

property ReqCausedAck;
	@(posedge clk) $rose(ack) |-> $past(req,2);
endproperty

$rose, $fell, $stable也可以在过程怪语句和连续赋值中使用

always @(posedge clk)
	TestDone <= stimulus_over & $rose(unit_done);
always@(posedge clk)beign
	if($stable(my_sig))begin
		$display($time, "my_sig is stable from previous clk");
	end
end
assign intr_clear = $fell(intr, @(posedge clk));
assign intr_set = $rose(intr,@(posedge clk));

23.系统函数和方法

类似于之前的访问采样方法,我们还可以使用其他一些系统函数和方法,在sequence/property/assertion中使用:

  • $countbits
  • $onehot
  • $isunknow
  • $countones
    这些系统函数也可以用在一般的过程语句块和幅值语句中。

在assertion或者property中,可以通过“disable iff”来给assertion做局部的条件控制。

在全局控制仿麦呢,我们也可以通过系统函数对property模块或者实例做出控制:

  • $asserton,默认控制,用来打开所有的assertion。
  • $assertoff,暂停assertion运行。
  • $assertkill,终止所有执行的assertion。
    在这里插入图片描述
    在这里插入图片描述

4.2Property

结合sequence(序列)对时序和逻辑的描述,property(属性)可以用来描述设计的确切行为。

Property可以在验证中用来做assumption,checker或者coverage:

  • 当使用assert关键词时,可以用作checker拉检查设计是否遵循property的描述。
  • 当使用assume关键词时,可以作为环境的假设条件,对于仿真环境和形式验证均起到对激励进行假设的作用。
  • 当使用cover关键词时,可以将property是否真正通过作为断言覆盖率来衡量。
    Property可以在module、interface、clocking块或者package中声明。

Property也可以同sequence一样具备形式参数。

共有七种property:

  • sequence
  • negation
  • disjunction
  • conjunction
  • if…else
  • implication
  • instantiation
    1.sequence类型

对于sequence类型的property,只有出现满足该sequence条件时,property才可以通过

2.negation类型

对于negation类型,即not property_expr。如果property_expr不满足,那么negation类型的property即通过。

property rule;
	@(clkev) disable iff(foo) a |-> not (b ##1 c ##1 d);
endproeprty

3.disjunction(or)

用法:property_expr1 or property_expr2,当至少一个property_expr满足条件时,property即通过。

property rule;
	@(posedge clk) a[*2] |-> ((##[1:3] c) or (d |-> e));
endproperty

4.conjunction(and)

用法:property_expr1 and property_expr2,当至少一个property_expr满足条件时,property即通过。

property rule;
	@(posedge clk) a[*2] |-> ((##[1:3] c) and (d |-> e));
endproperty

5.if(expression) property_expr1 else property_expr2

6.implication蕴含,同sequence中用法一致,sequence_expr{|->,|=>} property_expr

7.instantiation用法即一个命名后的property可以在另一个property_expr中所使用。

property rule1(x,y);
	##! |-> y;
endproperty
property rule2;
	@(posedge clk)
	a ##1 (b || c)[->1] |->
		if(b)
			rule1(d,e)
		else
			f;
endproperty

————————————————
版权声明:本文为CSDN博主「Nodal Analysis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44381276/article/details/121618400

回答: SVA (SystemVerilog Assertions)是一种用于验证硬件设计的语言扩展,其中包括属性(property)的定义和使用。属性是一种描述设计行为的语句,可以用于检查设计是否满足特定的规范或约束。 在SVA中,属性可以使用蕴含(implication)结构来定义。蕴含结构由先行算子(antecedent)和后续算子(consequent)组成,先行算子是约束条件,只有约束条件成功时,后续算子才会被计算。蕴含结构可以分为交叠蕴含和非交叠蕴含两种形式。 交叠蕴含使用符号"|->"表示,表示如果先行算子匹配,在固定个时钟周期后计算后续算子表达式。例如,在每个时钟上升沿,检查信号a是否为高电平,如果a为高,那么b在接下来两个时钟沿后也必须为高。\[2\] 非交叠蕴含使用符号"|=>"表示,表示如果先行算子匹配,在下一个时钟周期计算后续算子表达式。例如,在每个时钟上升沿,检查信号a是否为高电平,如果a为高,那么b在下一个时钟沿也必须为高。\[3\] 通过使用蕴含结构,我们可以在属性定义中指定约束条件和期望的行为,以便进行设计验证。 #### 引用[.reference_title] - *1* *2* *3* [SVA介绍----蕴含操作符](https://blog.csdn.net/qq_39556143/article/details/94591578)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值