System verilog SystemVerilog:表示运算符与|->;

System verilog SystemVerilog:表示运算符与|->;,system-verilog,system-verilog-assertions,implication,System Verilog,System Verilog Assertions,Implication,最近,一个问题出现了,SystemVerilog中常用的隐含运算符(|->)和隐含运算符之间有什么区别。不幸的是,我还没有找到一个明确的答案。但是,我收集了以下信息: 发件人: §16.12.7暗示和iff属性: property\u expr1意味着property\u expr2 当且仅当属性_expr1的计算结果为false或属性_expr2的计算结果为true时,此形式的属性的计算结果为true §F.3.4.3.2导出布尔运算符: p1表示p2≡ (不是p1或p2) §F.3.4

最近,一个问题出现了,SystemVerilog中常用的隐含运算符(
|->
)和
隐含运算符之间有什么区别。不幸的是,我还没有找到一个明确的答案。但是,我收集了以下信息:

发件人:

  • §16.12.7暗示和iff属性:

    property\u expr1意味着property\u expr2

    当且仅当属性_expr1的计算结果为false或属性_expr2的计算结果为true时,此形式的属性的计算结果为true

  • §F.3.4.3.2导出布尔运算符:

    p1表示p2≡ (不是p1或p2)

  • §F.3.4.3.4派生条件运算符:

    (如果(b)p)≡ (b |->P)

然而,LRM并没有真正指出实际的区别是什么。我假设他们在错误前因(成功与空洞的成功)的情况下的评估不同,但我找不到任何来源或证据支持这一假设。此外,我知道
implies
操作符与像OneSpin这样的正式验证工具结合在一起非常常见

有人能帮我吗


附言:在下面的书中似乎有一个关于这个问题的答案:SystemVerilog断言手册,第三版。但是仅仅为了得到这个问题的答案,155美元对我来说有点太多了:)

我试过了,显然属性(仅序列和布尔表达式)不允许使用
->
。以下是我尝试过的:

  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);
使用
的第二种形式意味着编译:

// this does compile
assert property(a_and_b implies a_and_c);

就语义而言,它与
|->
操作符一样。当
a_和_b
失败时,断言将以真空方式通过。如果
a_和b
成功,但
b_和c
没有成功,那么就会发出失败。

我认为还有更显著的区别。假设我们有以下示例:

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##1b
触发,并将在
a
的时钟周期内检查
c
是否匹配。这意味着属性将适用于以下场景:

属性p1通过,而p2失败: 属性p2通过,而p1失败:

可以在SystemVerilog LRM中找到此行为的提示。定义的替换为:

(if(b) P) = (b |-> P)
p1 implies p2 = (not p1 or p2)

总而言之,如果使用暗示运算符,则定义多周期操作会变得更容易,因为先行项和结果具有相同的评估起点。

我认为您使用属性的方式不正确。您应该使用序列定义,而不是对a_和b以及a_和c使用属性定义并将它们组合到新属性中。这样做之后,两个示例都应该编译。你用了哪个模拟器?我使用以下示例来模拟Incisive:第一个属性:a |->b第二个属性:a暗示b当使用这些属性模拟设计时,两个结果之间没有差异。当信号a变低时,两个属性都变为非活动状态。所以没有成功,或者没有成功。同意如果你使用序列,它将用两个操作符编译,但是你问的是如何使用带有属性的操作符。这些只是我为了尝试而编造的一些疯狂的属性。如果你专注于如何重写这些属性,你就不会因为树木而看到森林。在不同的模拟器上试用,它的行为是相同的。看来你是对的。