为什么 $urandom_range 返回相同的值?

Why $urandom_range is returning the same value?

我是 运行 UVM 测试台。在组件的一个 run_phase() 任务中,我执行 fork...join_none 以启动以下循环,该循环贯穿整个模拟:

fork
   forever @(posedge trigger) begin
      force dut.a = $urandom_range('h00,'hFF);
      force dut.b = $urandom_range( 'h0, 'hF);
      force dut.c = $urandom_range('h00,'hFF);
      force dut.d = $urandom_range( 'h0, 'hF);
      force dut.e = $urandom_range('h00,'hFF);
      force dut.f = $urandom_range( 'h0, 'hF);
   end

 ...
 some other stuff
 ...
join_none

问题是信号 ace 被迫相同价值。 bde 相同。

如果以后有新的触发姿势,新值会随机化并强制执行,但我再次得到 a == c == eb == d == e

似乎每个参数的选择(0 到 FF,0 到 F)只调用一次 $urandom_range,return 值重新用于三个 force 命令。


编辑:我能够在最小的 TB 上重现该问题:http://www.edaplayground.com/x/4_ph

我使用的供应商似乎有问题,选择其他工具后问题消失了。


编辑 2:我还没有弄清楚为什么会发生这种情况,但这似乎与 force 语句就像一个连续的赋值(即如果以后RHS信号变化,强制LHS会跟着变化,直到forcereleased,不像'='赋值)。

所以我的猜测是问题在于使用函数的 returned 值作为 RHS。 (我不知道这个 returned 值有多少生命周期)

我的解决方案是将 $urandom 值保存到一个具有静态生命周期的变量,然后将该变量强制到 RTL(如 J Reid 所建议的)

您的代码有两个问题。 首先,您将 $urandom_range 的参数反转;它是 (max,min),并且 min 是可选的,默认为 0。一些模拟器将弄清楚这一点,但这不是标准的。

第二个问题是因为你反复强迫同一个表达。模拟器可能不会将其视为新表达式并且不会再次调用 $urandom。尝试在每个 force.

之前放置一个 release 语句
 forever @(posedge trigger) begin
      release dut.a; force dut.a = $urandom_range('hFF);
      release dut.b; force dut.b = $urandom_range('hF);
      release dut.c; force dut.c = $urandom_range('hFF);
      release dut.d; force dut.d = $urandom_range('hF);
      release dut.e; force dut.e = $urandom_range('hFF);
      release dut.f; force dut.f = $urandom_range('hF);
   end

为什么不使用带有随机变量和约束的 class???

// outside of the test-bench
class my_stimulus;
    rand bit [7:0] a, c, e;  // can be logic if you like
    rand bit [3:0] b, d, f;  // rand won't give X or Z

    constraint c1 { 
        unique {a, c, e}; 
        unique {b, d, f};       
    }       
endclass;   

// inside the actual testbench 
my_stimulus to_dut = new; 

fork
   forever @(posedge trigger) begin
    if (!(to_dut.randomize()) $error;
    force dut.a = to_dut.a;
    ...
    force dut.f = to_dut.f;
   end
...
join_none   

唯一约束要么导致错误,要么每次都为您提供唯一值。指定大小后就无需设置边界,但这也可以通过另一个约束来完成。

我 运行 遇到了与 "urandom_range" 非常相似的问题,因为 OP 使用 NCSIM。然而,"urandom" 工作得很好。不应该有任何理由 "urandom" 不应该在你的情况下而不是 "urandom_range" 工作(当然假设 "urandom" 工作正常)。 "urandom" 的结果将被截断。

背景信息:以防万一有人好奇,我 运行 在 NCSIM 中遇到了一个关于 "urandom_range"(但不是 "urandom")的错误,其中第一次调用该函数无论如何,总是 return 最小指定值。但是所有后续调用都运行良好。