systemverilog学习 --- assertion建立

流程

在任何设计模型中,功能总是由多个逻辑事件的组合表示。这里的事件可以是简单的同一个时钟沿的布尔表达式,即即使断言。也可以是经过几个时钟周期后在求值的事件,即并发断言。在数字电路中,事件就是多个信号值的组合,我们可以使用布尔代数来表示。
我们可以把布尔表达式封装成序列sequence,序列是一个涉及一个或者多个周期的布尔表达式。其好处是可以提高重用性,就是我们在调用逻辑表达式时,我们可以使用sequence替代。sequence声明如下:

sequence name_of_sequence;
  ……
endsequence

多个序列可以组成一个更复杂的序列。systemverilog使用属性(property)来表示,语法形式如下:

property name_of_property;
  test expression or
  complex sequence expressions
endproperty

电路时序建立好了之后,为了可以让仿真工具检查,需要加入关键词assert,使仿真器可以检查属性。语法形式如下:

assertion_name:assert_property(property_name)

流程图如下,总的来说是一个往上封装的过程。
在这里插入图片描述

sequence

看下面的例子,seq_1在每个时钟的上升沿检查a是否为1。如果这个信号a在每个上升沿不是1的话,那么断言就会失败。

sequence seq_a;
	@(posedge clk) a = 1;
endsequence

在这里插入图片描述
下面的例子中,检查的是一个逻辑表达式,即在上升沿检查a||b的值是否为真。

sequence seq_2;
	@(posedge clk) a || b;
endsequence

为了提高序列的重用性,我们可以在序列定义中定义所需要的参数,可以被其它类似的行为调用。如下面例子所示:

sequence seq_lib(a,b);
	a || b;
endsequence

我们在调用的时候,可以在其它序列中传入参数:

sequence s_lib_inst;
	seq_lib(req1,req2);
endsequence

我们还可以检查多个周期的行为,即时序问题,为了表达不同周期的行为,采用“##”符号,比如说 ##2表示仿真事件后的两个周期,对于多个周期的约束,不同周期之间的逻辑表达式使用空格隔开。在下面这个例子中,首先判断是在每个时钟的上升沿,信号a是否为高电平,如果a时低电平,那么整个sequence失败。但是如果a时高电平在任意一个上升沿,而且检查在这之后的后两个周期b是否为高电平,若信号b不是高电平,那么此次断言失败。

sequence seq;
	@(posedge clk) a ##2 b;
endsequence

在这里插入图片描述
我们也可以把sequence和property分开,在下面例子中,在property中定义时钟,将序列和时钟互相隔离,可以增加基本序列定义的重用性。

sequence seq;
	a ##2 b;
endsequence

property p;
	@(posedge clk seq);
endproperty

a_1 : assert property (p);

此外我们也可以对断言条件取反,下面这个例子中,如果检测到a在一个给定的时钟上升沿为高电平,那么在过了两个时钟周期后,信号b不能为高电平。

sequence seq;
	@(posedge clk) a ##2 b;
endsequence

property p;
	not seq;
endproperty
a_1:assert property(p);

implication operator

有时候,我们期望和约束一样,满足一定条件才检查,同样使用蕴涵操作符实现。蕴涵操作符等价于if-then结构,操作符的坐标叫做前因(antecedent),操作符的右边称作后果(consequent)。如门控时钟一般,前因满足时,才会检查后果,前因不满足,则不会检查后果。需要注意的是,蕴涵操作符只能在property内部使用,无法再sequence内部使用。蕴涵操作符分为两类:

  1. 重叠蕴涵
  2. 非重叠蕴涵
    重叠蕴涵使用|->表示,如果前因得到匹配时,那么这个后果将会在同一个时钟周期中进行检查。如下面的例子所示,如果a是高电平的话,那么信号也应高在相同的时钟周期内也为高电平。
property p;
	@(posedge clk) a |-> b;
endproperty
a:assert property(p);

非重叠蕴涵使用|=>表示,如果前因得到匹配时,那么这个后果将会在下一个时钟周期内进行检测。如下面的例子所示,如果a在一个给定的时钟上升沿为高电平,那么在写一个时钟周期信号b也应该是高电平。

property p;
	@(posedge clk) a|=> b;
endproperty
a:assert property(p);

此外我们也可以在后果前加一个固定的延时语句。如下面的例子所示,如果信号a在一个给定的时钟上升沿为高电平,那么应该在两个时钟周期之后信号b也为高电平。

property p;
	@(posedge clk) a |-> ##2 b;
endproperty
a:assert property(p);ww

实质上,蕴涵操作符的前后都是序列,下面的例子体现了sequence到property的封装。

sequence seq_1;
 (a && b) ##1 c;
endsequence
 
sequence seq_2;
  ##2 !d;
endsequence
 
property p;
  @(posedge clk) seq_1 |-> seq_2;
endpeoperty
a: assert property(p);

当然,固定延时不能满足所有需求,还可能是一个范围。下例中,通过[1:4]表示在1-4个周期内,b=1就通过断言,是一个或的关系,即可以经过1个周期为1,也可以经过2个、3个、4个周期b=1。中括号内周期数目,可以设置为0,表示当前时钟沿,也可以写$表示无穷,即后果任意个周期。

property p;
	@(posedge clk) a |-> ##[0:4] b;
endproperty
a:assert property(p);
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值