如何重新设置静态过程的RNG?

时间:2019-03-15 08:52:07

标签: verilog system-verilog

我的测试台中有一个always进程正在运行,它调用$urandom_range(),在我运行测试台时是否可以重新设置种子?

我想它与srandom有关,但无法正常工作。

1 个答案:

答案 0 :(得分:1)

可以通过使用整数参数调用$urandom来为线程(即$urandom等使用的线程)生成随机数生成器,例如:

 $urandom(12345);

您提到srandom。这是与线程的随机数生成器进行交互的另一种方式,即使用process类,该类是std包中声明的类。该进程类具有一个称为srandom的方法,该方法从整数中播种当前线程。

要使用process类,首先需要一个类process的变量:

   std::process p;

,然后需要为该变量分配进程类的 static 方法的返回值,该方法称为self

   p = process::self(); 

如果您不熟悉面向对象的设计,请不要担心。相信我。这是您需要做的。将这两行想像成某种魔术。发出该魔术咒语后,我们可以调用srandom方法来播种线程的随机数生成器,例如:

  p.srandom(12345);

所以srandom$urandom?有什么区别,或者换句话说:

如果我使用流程类的srandom方法设置了种子,那是否将线程的随机数生成器设置为与使用$urandom设置相同种子的状态相同?

没有区别。除了那里。

什么?让我们在EDA Playground中放置一些代码(在此答案的底部):https://www.edaplayground.com/x/4yN4

让我们使用随机种子为线程的随机数生成器播种:

   p.srandom(9);

然后我们生成四个随机数:

   repeat(4) $display( $urandom ); 

看看我们得到什么:

# KERNEL:  659167701
# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565 

然后使用$urandom:

为线程的随机数生成器添加种子
   $urandom(9);

再次让我们生成四个随机数

  repeat(4) $display( $urandom ); 

再来看看我们得到了什么:

# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565
# KERNEL: 3967046865 

乍一看,似乎我们已经生成了四个不同的随机数。但是,通过仔细检查,我们发现第二个($urandom)系列的第一个数字与第一个(srandom)系列的第二个数字相同。为什么会这样呢?好吧,这是因为调用$urandom不仅设置了种子,而且还生成了一个随机数,而调用srandom则仅设置了种子。


module M;
  initial
    begin
      string randstate;
      std::process p;
      p = process::self();
      $display("p.srandom(9)");
      p.srandom(9);
      repeat(4) $display( $urandom );
      $display("$urandom(9)");
      $urandom(9);
      repeat(4) $display( $urandom );
    end
endmodule

另请参阅我的答案,其中包含有用的背景知识:

urandom_range(), urandom(), random() in verilog