为什么这种约束在不同的模拟器上表现不同?

时间:2014-02-15 01:19:15

标签: constraints system-verilog

我在测试平台中遇到了以下约束。它的行为似乎取决于使用的模拟器。

constraint wr_c {
    if (!one_beat) { addr[5:0] == 0, len == 15 };
}

它实际上应该做什么,如写的那样?

一个例子:

import uvm_pkg::*;

class pkt extends uvm_object;

  rand bit one_beat;
  rand int len;
  rand bit [31:0] addr;

  `uvm_object_utils_begin(pkt)
    `uvm_field_int(one_beat, UVM_DEFAULT)
    `uvm_field_int(len, UVM_DEFAULT)
    `uvm_field_int(addr, UVM_DEFAULT)
  `uvm_object_utils_end

  constraint wr_c {
    if (!one_beat) { addr[5:0] == 0, len == 15 };
  } 

endclass

module test;

  initial begin
    for (int i = 0; i < 10; i++) begin
      automatic pkt p = new();
      p.randomize();
      p.print();
    end
  end

endmodule

2 个答案:

答案 0 :(得分:4)

不同模拟器给出不同结果的原因可能与解算器的true构成的原因有关。使用以下示例:

rand bit [1:0] example;
rand bit one_beat;
constraint example_c { if(!one_beat) example; }

在这种情况下,example的随机化宽度与{ addr[5:0] == 0, len == 15 }相同。根据模拟器,上述约束可能会推断example==2'b1example!=2'b0example>2'b0(带有签名和无符号的不同结果)。如果one_beat不是一位值,那么对于if()语句,如果需要计数为真,则同样的问题也是如此。

如果打算使用 OR 选项,则编写约束的更好方法是:

if (!one_beat) ( addr[5:0] == 0  ||  len == 15 );

if (!one_beat) { addr[5:0] == 0, len == 15 } != 0; // or '>0', '>=1', etc

约束的创建者有一个很好的改变,这两个约束在if(!one_beat)时都是真的。在这种情况下,以下是更好的约束选项:

if (!one_beat) { addr[5:0] == 0; len == 15; } // note the semicolon positions

if (!one_beat) ( addr[5:0] == 0 && len == 15 );

另请注意,对于给定的SSCCE,one_beat成为1'b0的可能性非常低,因为解算器正在尝试为one_beataddr找到合法条件和len平行优先。

  • addr[5:0]==0 || len==15概率为1/(1+2**6) + 1/(1+2**32)
  • addr[5:0]==0 && len==15概率为1/(1+2**(6+32))

如果这不是意图,则添加另一个约束,例如one_beat dist { ... };sovle one_beat before addr,len;

答案 1 :(得分:1)

这是约束在不同模拟器上的行为方式。约束的行为有所不同,因为模拟器以不同的方式处理串联约束{a, b};

以下代码是伪代码,用于演示问题的约束如何起作用。

在VCS 2013.06上:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
  // distribution highly favors 2'b01
}

在Questa SIM 10.1d上:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b10;
}

关于INCISIV 13.10.001:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
  // distribution favors 2'b10
}