System verilog 使用蕴涵算子的双向约束

System verilog 使用蕴涵算子的双向约束,system-verilog,System Verilog,在下面的代码中,如果a==1,那么b==0。由于双向性,如果b==0,那么我的理解是a应该是1。但是,输出与我预期的不同 class ex_sv; rand bit a; rand bit b; constraint c { (a==1) -> (b==0); } endclass module ex_mod; ex_sv h = new(); initial begin for( int i = 0; i<10; i++ ) begin void'(h.rand

在下面的代码中,如果a==1,那么b==0。由于双向性,如果b==0,那么我的理解是a应该是1。但是,输出与我预期的不同

class ex_sv;

rand bit a;
rand bit b;

constraint c {
   (a==1) -> (b==0);
 }
endclass

module ex_mod;

ex_sv h = new();

initial begin
for( int i = 0; i<10; i++ ) begin
 void'(h.randomize() with {b==0;});
 $display("ITER : %0d a = %0d b = %0d",i, h.a, h.b);
end
end

endmodule

你的结果是意料之中的

在IEEE标准1800-2017第18.5.6节中, 有一个与您类似的示例,使用4位变量

由于声明了两个1位变量,因此有4种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}
类中的
c
约束删除其中一个(a=1,b=1), 留下这三种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}
带约束的内联
强制b=0,保留以下两种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}

这意味着
a
可以是0或1,这就是您看到的结果。

您的结果是预期的

在IEEE标准1800-2017第18.5.6节中, 有一个与您类似的示例,使用4位变量

由于声明了两个1位变量,因此有4种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}
类中的
c
约束删除其中一个(a=1,b=1), 留下这三种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}
约束的内联
强制b=0,保留以下两种组合:

{0,0}, {0,1}, {1,0}, {1,1}
{0,0}, {0,1}, {1,0}
{0,0}, {1,0}

这意味着
a
可以是0或1,这就是您看到的。

隐含运算符
a==1->b==0
在逻辑上等同于
(a==0 | b==0)
(来自18.5.6)

如果
b==0
,则方程已经满足,
a
可以取任何值,但仍然满足约束

如果尝试用a==0模拟
,则
b
可以取任何值


你可以用a==1试验
,那么满足表达式的唯一方法是如果
b==0
隐含操作符
a==1->b==0
在逻辑上等同于
(a==0 | b==0)
(从18.5.6开始)

如果
b==0
,则方程已经满足,
a
可以取任何值,但仍然满足约束

如果尝试用a==0模拟
,则
b
可以取任何值


你可以用a==1试验
,然后满足表达式的唯一方法是如果
b==0

,这不是我的理解。考虑这一点:约束NoWordErrROM {(ADDR<Max SyrMyAdDR)->(DIR=Read);}。您仍然希望在内存映射的其他位置读取,否则
->
操作符的意义是什么?我不理解这一点。考虑这一点:约束NoWordErrROM {(ADDR<Max SyrMyAdDR)->(DIR=Read);}。您仍然希望在内存映射中的其他位置读取,否则
->
操作符有什么意义?