【问题标题】:Why does this constraint behave differently on different simulators?为什么这个约束在不同的模拟器上表现不同?
【发布时间】:2014-02-15 01:19:15
【问题描述】:

我在测试台中遇到了以下约束。它的行为似乎因使用的模拟器而异。

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

【问题讨论】:

  • 解释一下你看到的不同行为怎么样?
  • @dave_59,根据 Greg 的回答,我添加了一个回答,描述了不同模拟器会发生什么。

标签: constraints system-verilog


【解决方案1】:

不同模拟器给出不同结果的原因可能与求解器的 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&gt;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_beataddrlen 的合法条件,同时等于优先级。

  • addr[5:0]==0 <b>||</b> len==15它的概率是1/(1+2**6) + 1/(1+2**32)
  • addr[5:0]==0 <b>&amp;&amp;</b> len==15它的概率是1/(1+2**(6+32))

如果不打算这样做,则添加另一个约束,例如 one_beat dist { ... };sovle one_beat before addr,len;

【讨论】:

    【解决方案2】:

    这就是约束在不同模拟器上的行为方式。约束的行为不同,因为模拟器以不同的方式处理串联约束{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
    }
    

    【讨论】:

    • 2'b10 的偏爱在默认权重下是有意义的。 addr[5:0]==0 的概率为1/(1+2**6),大于len==15 (1/(1+2**32)) 的概率。颠倒约束中addr & len 的顺序,1'b01 将受到青睐。使用dist {} 控制分发。例如{address[5:0]==0,len==25} dist { 1:=3, 2:=2};
    • 另外,Questa 的发行版有什么优势?这些信息不应该在问题中吗?
    • 对于 Questa,它始终是 addr[5:0] == 0 &amp;&amp; len != 15 when !one_beat。此信息可能在问题中,尽管它实际上回答了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2011-10-10
    相关资源
    最近更新 更多