[英]SystemVerilog: implies operator vs. |->
最近出现的问题是通常的蕴涵算子( |->
)和SystemVerilog中的implies
运算符之间的区别。 不幸的是我还没找到一个明确的答案。 但是,我收集了以下信息:
从SystemVerilog LRM 1800-2012 :
§16.12.7 隐含和iff属性 :
property_expr1 implies property_expr2
当且仅当property_expr1的计算结果为false或property_expr2的计算结果为true时,此表单的属性才会计算为true。
§F.3.4.3.2 派生的布尔运算符 :
p1 implies p2 ≡ (not p1 or p2)
§F.3.4.3.4 派生的条件运算符 :
(if(b) P) ≡ (b |-> P)
但是,LRM并没有真正指出实际差异是什么。 我假设他们在错误的前因(成功与空洞的成功)的情况下评价不同,但我找不到任何这种假设的来源或证据。 此外,我知道, implies
运算符与OneSpin等形式验证工具相结合非常常见。
任何人都可以帮我吗?
PS:在下面的书中似乎有这个问题的答案: SystemVerilog Assertions Handbook,3rd Edition 。 但是155美元对我来说有点太多了,只是为了得到这个问题的答案:)
我认为甚至有更显着的差异。 假设我们有以下示例:
property p1;
@ (posedge clk)
a ##1 b |-> c;
endproperty
property p2;
@ (posedge clk)
a ##1 b implies c;
endproperty
assert property (p1);
assert property (p2);
两个蕴涵算子都具有不同的证明行为。 属性p1
将通过a ##1 b
的匹配触发,并将在与b
相同的时钟周期内查找匹配的c
。 然而,属性p2
通过触发a ##1 b
,将检查匹配的c
的时钟周期期间a
。 这意味着属性将通过以下方案:
属性p1通过,p2失败: 属性p2通过,p1失败:
可以在SystemVerilog LRM中找到有关此行为的提示。 定义的替换是:
(if(b) P) = (b |-> P)
p1 implies p2 = (not p1 or p2)
总而言之,如果使用含义运算符,则定义多周期运算变得更容易,因为先行和后果具有相同的评估起点。
我试了一下,显然不允许|->
属性(仅用于序列和布尔表达式)。 这是我试过的:
property a_and_b;
@(posedge clk)
a && b;
endproperty
property a_and_c;
@(posedge clk)
a && c;
endproperty
使用|->
第一个表单不能编译:
// this doesn't compile
assert property(a_and_b |-> a_and_c);
第二种形式使用implies
会编译:
// this does compile
assert property(a_and_b implies a_and_c);
语义方面,它与|->
运算符一样。 当a_and_b
失败时,断言a_and_b
通过。 如果a_and_b
成功但b_and_c
没有,则发出失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.