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)沿紧密相连的下一个时钟。
对于并行断言,其必须具备时钟,时钟由以下条件的优先级逐级判定:
- 显示声明的断言时钟
- 继承断言所嵌入环境的时钟
- 继承默认的时钟
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

浙公网安备 33010602011771号