赞
踩
SystemVerilog断言(SVA)主要是用于验证设计的行为,其主要功能有两点:
立即断言执行时如同过程语句,她在程序执行到这个程序块使立即执行,并且可以结合$fatal,$error,$warning和$info函数给出不同级别的消息提示。
断言比if语句更加紧凑,且断言里面的逻辑跟if语句是相反的。设计者应该期望括号内的表达式为真,否则输出一个错误。
- //使用if语句检查一个信号
- bus.cb.request<=1;
- repeat(2) @bus.cb;
- if(bus.cb.grant!=2'b01)
- $display("Error,grant!=1");
- //简单的立即断言
- bus.cb.request<=1;
- repeat(2) @bus.cb;
- al:assert (bus.cb==2'b01);
-
- //定制断言行为
- bus.cb.request<=1;
- repeat(2) @bus.cb;
- al:assert (bus.cb==2'b01)
- else $error("Grant not asserted");
并发断言可以认为时一个连续运行的模块,他为整个仿真过程检查信号的值,需要在断言内指定一个采样时钟。
例中是一个检查仲裁器request信号的断言,request信号除了在复位期间,其他任何时候都不能是X或Z。
- //检查X/Z的并发断言
- interface arb_if(input bit clk);
- logic[1:0] grant,request;
- logic rst;
-
- property request_2state;
- @(posedge clk) disable iff(rst);
- $isunknown(request)==0; //确保没有z或者x值存在
- endproperty
- assert_request_2state:assert property(requset_2state);
- endinterface
可以在过程块,module,interface和program内定义并发断言,区别并发断言和立即断言的关键字是property。
SVA从单元的角度来说可以分为3个层次,分别是:
布尔表达式是组成断言的最小单元,常用的操作符:&&,||,!,^等。
- //简单的布尔表达式断言
- example_assert: assert property(@(posedge clk) a&&b==1);
在任何设计中,功能总是由多个逻辑事件的组合来表示,这些事件可以是简单的同一个时钟沿被求值得布尔表达式,也可以是经过几个时钟周期的求值事件,SVA用关键字 sequence来表示这些事件,sequence可以让断言易读,复用性高;sequence是布尔表达式更高一层的单元。
sequence具有以下特性:
- //简单的Sequence
- sequence seq_1;
- @(posedge clk) a==1;
- endsequence
-
- //调用sequence
- a_1: assert property(seq_1);
带逻辑关系的sequence:
- //带逻辑关系的Sequence
- sequence seq_1;
- @(posedge clk) a||b; //如果a和b都为0,则断言失败
- endsequence
带参数的sequence:
- //带参数的sequence
- sequence seq_1 (a, b)
- a || b ;
- endsequence
-
- sequence seq_2
- seq_1(a,b); //在当前sequence调用seq_1
- endsequence
带时序关系的sequence:
- //带时序关系的sequence
- sequence seq;
- @(posedge clk) a ##2 b; //在时钟上升沿到来检查a是否为1,若不为1则断言失败
- //若a为1,则检查两个周期之后b是否为1,若不为1,断言失败
- endsequence
property是比sequence更高一层的单元,也是构成断言最常用的模块。其中最重要的性质是可以在property中使用蕴含操作符(|-> |=>)。
propert可以调用sequence:
- //property调用sequence
- sequence seq_1;
- @(posedge clk) a||b;
- endsequece
-
- property p;
- seq_1; //调用seq_1
- endproperty
-
- a_1: assert property(p);
property与sequence的相同和不同之处:
断言常用的操作符如下:
##n | 表示延时了n和时钟周期; |
##[m:n] | 表示后续事件在n-m周期内出现都可以判定为真 |
$ | 表示无穷大的周期(在仿真结束前),不建议使用 |
[*n] | 表示事件重复n次 |
[*m:n] | 表示一定范围内重复的事件 |
[=m] | 表示一个事件的连续性,需要重复m次,但并不需要在连续周期内发生 |
[=m:n] | 表示一个事件的连续性,需要重复n-m次,但并不需要在连续周期内发生 |
|-> | 交叠蕴含,涵的左边叫做”先行算子“(antecedent),右边叫做”后续算子“(consequent)。如果先行算子匹配,在同一个时钟周期计算后续算子表达式。 |
|=> | 非交叠蕴含,如果先行算子匹配,在下一个时钟周期计算后续算子表达式。 |
常见的系统函数如下:
$rose | $rose(boolean expression or signalname); 信号/表达式的值从0变为1时返回真 |
$fell | $fell( boolean expression or signalname); 信号/表达式的值从1变为0时返回真 |
$stable | $stable(boolean expression or signalname) ; 信号/表达式的值不发生变化时返回真 |
$past | $past(signal_name, number of clock cycles); 访问在过去若干采样周期的值 |
and | 断定两个事件同时发生 |
intersect | 断定两个事件同时发生或结束 |
or | 断定两个事件至少一个发生 |
first_match | 从多次满足的序列中选择第一次满足的时刻,从而放弃其他满足时刻 |
throughout | a throughout b 断定在b事件成立的过程中,a事件“一直”成立 |
within | a within b 断定b事件发生的时间段里包含a事件发生的时间段 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。