System verilog 为什么约束求解器至少未求解a==b约束

System verilog 为什么约束求解器至少未求解a==b约束,system-verilog,System Verilog,我有一个有约束的代码 ((((a == b) == c) == d) == e) 我能理解c、d和e所取的值。但是既然a==b在这里是一个约束,为什么解算器不解a==b呢?至少a和b应具有相同的值 module tb; class packet; rand bit [4:0] a,b,c,d,e; endclass initial begin packet pkt; pkt = new(); if(pkt.randomize() with {

我有一个有约束的代码

((((a == b) == c) == d) == e)
我能理解c、d和e所取的值。但是既然a==b在这里是一个约束,为什么解算器不解a==b呢?至少a和b应具有相同的值

module tb;
  class packet;
    rand bit [4:0] a,b,c,d,e;

  endclass

  initial
  begin
    packet pkt;
    pkt = new();
    if(pkt.randomize() with {pkt.a == pkt.b == pkt.c == pkt.d == pkt.e;})
      $display("a is %h, b is %h, c is %h,d is %h, e is %d \n", pkt.a, pkt.b, pkt.c, pkt.d, pkt.e);
    if(pkt.randomize() with {pkt.a == pkt.b == pkt.c;})
      $display("a is %h, b is %h, c is %h,d is %h \n", pkt.a, pkt.b, pkt.c, pkt.d);

  end  

endmodule
我得到的输出是

a is 00, b is 08, c is 1c,d is 00, e is  1 

a is 0d, b is 1d, c is 00,d is 09

我可以把c,d和e取的值联系起来。但是,我不理解a和b的值

您发现了典型的SystemVerilog约束问题,让我解释一下

==是一个从左到右求值的二进制运算符

例如:pkt.a==pkt.b-这里,如果pkt.a与pkt.b的值相同,则求值结果为1,否则结果为0

pkt.a==pkt.b==pkt.c—要使整个表达式为真,pkt.c必须等于pkt.a==pkt.b求值的结果,这意味着如果pkt.a与pkt.b不同,pkt.c将具有值0,否则将具有值1

这意味着pkt.c将始终是0或1,因此满足pkt.a==pkt.b==pkt.c的唯一值集都是1。类似的问题也出现在

解决方法是,按如下所述分别拆分约束以获得所需的结果

if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c; pkt.c == pkt.d; pkt.d == pkt.e;})


if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c;})
为了便于理解和避免混淆,在整个过程中保持相同的打印格式,我发现在您的示例中混合了十六进制和十进制格式

$displaya是%h,b是%h,c是%h,d是%h,e是%d\n,pkt.a, b组、c组、d组、e组


您发现了典型的SystemVerilog约束问题让我解释一下

==是一个从左到右求值的二进制运算符

例如:pkt.a==pkt.b-这里,如果pkt.a与pkt.b的值相同,则求值结果为1,否则结果为0

pkt.a==pkt.b==pkt.c—要使整个表达式为真,pkt.c必须等于pkt.a==pkt.b求值的结果,这意味着如果pkt.a与pkt.b不同,pkt.c将具有值0,否则将具有值1

这意味着pkt.c将始终是0或1,因此满足pkt.a==pkt.b==pkt.c的唯一值集都是1。类似的问题也出现在

解决方法是,按如下所述分别拆分约束以获得所需的结果

if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c; pkt.c == pkt.d; pkt.d == pkt.e;})


if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c;})
为了便于理解和避免混淆,在整个过程中保持相同的打印格式,我发现在您的示例中混合了十六进制和十进制格式

$displaya是%h,b是%h,c是%h,d是%h,e是%d\n,pkt.a, b组、c组、d组、e组


您应该参考Stuart Sutherland和Don Mills的Verilog和SystemVerilog Gotchas:101常见编码错误。所列书籍涵盖了上述问题以及fork-join_-none前面的问题

您应该参考Stuart Sutherland和Don Mills的Verilog和SystemVerilog Gotchas:101常见编码错误。所列书籍涵盖了上述问题以及fork-join_-none前面的问题

但是当我只做pkt.a==pkt.b时,两者得到相同的值,那么为什么引入==pkt.c会使pkt.a==pkt.b约束无效。?引入pkt.c不会使pkt.a,pkt.b成为无效约束,如果你能仔细观察的话,==是一个二进制运算符,它的计算结果为0或1,与pkt.cI相比,它也是二进制的。我同意你的观点,但当我简单地执行约束pkt.a==pkt.b时,不管怎样,它总是得到相等的a和b值。由于引入了新的约束,模拟器无法知道选择哪一个,并且这个场景没有记录在LRM中,这导致了Gotchas,但是当我只做pkt.a==pkt.b时,两者得到相同的值,那么,为什么引入==pkt.c会使pkt.a==pkt.b约束无效。?引入pkt.c不会使pkt.a,pkt.b成为无效约束,如果您能仔细观察的话,==是一个二进制运算符,计算结果为0或1,与pkt.cI相比,它再次是二进制的。同意您的观点,但是,当我简单地做一个约束pkt.a==pkt.b时,无论发生什么情况,它都会得到相等的a和b值。由于引入了新的约束,模拟器无法知道选择哪个约束,并且这个场景没有在LRM中记录,这导致了gotchas