Assertion

断言:用来与设计功能和时序作比较的属性描述。
立即断言:

assert (expression) [pass_statement] [else fail_statement]
always @(posedge clk) 
	if (state == REQ)
		assert(reg1 || reg2)
		else begin
			t=$time;
			#5 $error("assert failed at time %0t", t);
		end
		
assert (myfunc(a,b)) count1 count+1; else -> event1;

assert (y==0) else flag == 1;

always @(state)
	assert (state == $onehot) else $fatal;

并行断言

assert property (cont_prop(rst,in1,in2)) pass_stat else fail_stat;

property name;
...
endproperty

assert property name else ...;

sequence name;

endsequence

并行断言只会在时钟边沿激活,变量的值是采样到的值。

sequence、property和assertion

assertion可以直接包含一个property;
assertion可以独立声明property;
在property内部可以有条件地关闭: disable iff ()
property可以直接包含sequence,也可独立声明多个sequence。
sequence是用来表示一个或多个时钟周期内的时序描述;
sequence可以提供形式参数;

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

|-> :条件满足,在当前周期评估其后算子;
|=> :条件满足,在下一周期评估其后算子;
## :周期延迟,##0指当前周期
##[min:max] : 在一个范围内的时钟周期延迟,从min到max时间窗口中最早的时间来匹配。
$ : 表示无穷大的周期。a ## [1:$]b。
[*n] : 表示重复,重复连续的时钟周期。
[*m:n] : 在一定范围内重复的事件。
[=m] : 重复m次,不需要在连续周期内发生。
[=m:n] : 从最小到最大重复发生的非连续周期次数。
[*0] : 表示没有在任何正数时钟周期内有效。

and : 同一个起始点开始,seq1和seq2均满足,满足时刻发生在较晚序列的满足时刻。
intersect : 同一起点,同一结束点;
or: seq1 和 seq2在同一时刻被触发,结束时间以序列满足的最后一个序列时间为准。
first_match:选择第一次匹配的时刻。
throughout :检查一个信号或者表达式在贯穿一个序列时是否满足。sig1/exp2 throughout seq;在seq成立期间sig1/exp2成立,左边包含右边。
within:一个序列与另一个序列部分周期长度上的重叠。一个序列包含在另一个序列内。seq1 within seq2:seq2的起始点早于q1的起始点,seq2的结束点晚于等于seq1的结束点。
if...else:在sequence中使用if ..else
seq.end :检测序列的终点。
局部变量:

sequence t2;
	(a##[2:3] b) or (c ##[1:2] d);
endsequence
sequence ts2;
	first_match(t2);
endsequence
sequence checkBusIdle;
	(##[2:$] (frame && irdy));
endsequence
property first_match_idle
	@(posedge clk) first_match(checkBusIdle) |-> (state==busidle);
endproperty
//局部变量
sequence check_reg_wr_data;
	int local_data;
	(rd_cache_done, local_data=cache_rd_data) ##2 (reg_wr_data == (local_data+1)
endsequence

property checkreadidack;
	int loc_id;
	($rose(read),loc_id = readid) |=>
	not(($rose(read)&&readid==loc_id)[*1:$]) ##0
	($rose(readack)&&readackid ==loc_id);
endproperty

访问采样方法
访问当前周期采样值,访问上一周期采样值;检测采样值的变化。
$rose:
$fell:
$stabel(expression[,clocking_event]),连续两个周期内表达式的值保持不变,比如在某一信号为高时,寄存器的值保持不变。
$past(expr[,numble_cycles][,gating_expr][,clocking_event])访问在过去若干采样周期前的数值。

disble iff 给assertion做局部的条件控制。

property name
	@(posedge clk) disable iff (!rst)
	...
endproperty

时钟声明:一般对于sequence或者property,默认情况下,使用一个时钟对数据做采样,多个时钟采样时,使用##1结合第二个时钟沿采样

@(posedge clk0) sig0 ##1 @(posedge clk1) sig1

只能使用##1表示与第一个时钟(clk1)沿紧密相连的下一个时钟。
对于并行断言,其必须具备时钟,时钟由以下条件的优先级逐级判定:

  1. 显示声明的断言时钟
  2. 继承断言所嵌入环境的时钟
  3. 继承默认的时钟

assertion的控制

在assertion和property中,可以通过disable iff来给assertion做局部的条件控制。
在全局控制方面,使用系统函数对property模块或者实例做出控制。
$asserton(level, [list of module, instance or assertion_identifier]);

$assertoff(同上);

$assertkill();
level =0当前模块或层次下的所有assertion
assertion_identifier表示property的名字或者assertion的label

property的使用

结合sequence对时序和逻辑的描述,property可以描述设计的确切行为。property在验证中用来做assumption, checker或者coverage:

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

绑定

bind方法满足在设计外部定义断言,而将其绑定到设计内部或者接口上面,等价于将SVA例化到设计module中,即可满足对设计内部信号的可视性,又能满足断言模块的独立性。

interface range (input clk, enable, input int minval, expr);
  property crange_en;
  @(posedge clk) enable |-> (minval <= expr);
  endproperty
  range_chk: assert property(change_en);
endinterface
bind cr_unit range r1(c_clk, c_en,v_low,(in1&&in2));  cr_unit  设计模块名

expect:阻塞的property使用方式,expect的语法同assert一致,不过它会等待property执行通过,才会执行后续的语句

initial begin
  #200ms;
  expect(@(posedge clk) a##1b ##1 c) else $error("expect failed");
  ABC:...
end 

sva断言

posted @ 2023-09-17 15:55  yoy116  阅读(70)  评论(0)    收藏  举报