VHDL 的随机数有多好?

Pae*_*els 5 random statistics vhdl

我正在使用来自 的 VHDL 随机数IEEE.math_real,但是这些生成的数字有多好?

.... 假设与rand(...)C相比。

有没有统计测试?


这是高斯分布的直方图。参数:

  • 随机源:由生成的 2 个均匀分布的 REAL 值 math_real.Uniform(...)
  • Box-Muller 变换
  • 使用 REAL 计算
  • 输出范围:0..4095 INTEGER
  • 102.400 次迭代

经典直方图视图:
NormalDistributedRandomValue 100Ki 迭代; 范围 0..4095

作为点云:
NormalDistributedRandomValue 100Ki 迭代; 范围 0..4095


这是均匀分布的直方图。参数:

  • 随机源:由生成的均匀分布的 REAL 值 math_real.Uniform(...)
  • 使用 REAL 计算
  • 输出范围:0..4095 INTEGER
  • 102.400 次迭代

经典直方图视图:
NormalDistributedRandomValue 100Ki 迭代; 范围 0..4095

作为点云:
NormalDistributedRandomValue 100Ki 迭代; 范围 0..4095

Gnuplot 拟合结果为f(x)=m*x+b

m = -0.0000343906
b = 25.0704
Run Code Online (Sandbox Code Playgroud)

在我看来,两个直方图都有很高的抖动。

Mor*_*mer 2

的实现IEEE.math_real.UNIFORM是:

procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE;variable X:out REAL) is
  ...
  variable Z, K: INTEGER;
  variable TSEED1 : INTEGER := INTEGER'(SEED1);
  variable TSEED2 : INTEGER := INTEGER'(SEED2);
begin
  ...

  K := TSEED1 / 53668;
  TSEED1 := 40014 * (TSEED1 - K * 53668) - K * 12211;
  if TSEED1 < 0  then
    TSEED1 := TSEED1 + 2147483563;
  end if;

  K := TSEED2 / 52774;
  TSEED2 := 40692 * (TSEED2 - K * 52774) - K * 3791;
  if TSEED2 < 0  then
    TSEED2 := TSEED2 + 2147483399;
  end if;

  Z := TSEED1 - TSEED2;
  if Z < 1 then
    Z := Z + 2147483562;
  end if;

  SEED1 := POSITIVE'(TSEED1);
  SEED2 := POSITIVE'(TSEED2);
  X :=  REAL(Z) * 4.656613e-10;
end UNIFORM;
Run Code Online (Sandbox Code Playgroud)

关于实施的这些描述:

a) 此函数的语义由 Pierre L'Ecuyer 在“Communications of the ACM”(《ACM 通信》,第 1 卷)中发布的算法描述。31、没有。6,1988 年 6 月,第 742-774 页。该算法基于 32 位平台的两个乘法线性同余生成器的组合。

b) 在第一次调用 UNIFORM 之前,种子值 (SEED1, SEED2) 必须分别初始化为 [1, 2147483562] 和 [1, 2147483398] 范围内的值。每次调用 UNIFORM 后都会修改种子值。

c) 该随机数生成器可移植于 32 位计算机,并且每组种子值的周期约为 2.30584*(10**18)。

d) 有关算法光谱测试的信息,请参阅 L'Ecuyer 文章。

L'ecuyer 的论文是“高效便携的组合随机数生成器”,由 user1155120 在评论中给出。

因此它是使用 Wichmann/Hill/Schrage/Bratley 等的组合线性同余生成器 (CLCG) 。al. 的方法(参见 L'ecuyer 论文)在使用 32 位整数实现时避免整数溢出。

根据 Wiki 和我可以通过快速搜索找到的其他参考资料,为 CLCG 选择的常数似乎是众所周知的。正如 user1155120 在评论中告知的,CLCG 的随机属性已在“A Comparison of Four Pseudo Random Number Generators Implemented in Ada”中进行了分析。

基于此,VHDL 随机生成器似乎非常可靠,因此我预计您发现的抖动/异常值只是随机性的结果。