基于FPGA的LFSR16位伪随机数产生算法实现,可以配置不同的随机数种子和改生成多项式,包含testbench

目录

1.算法仿真效果

2.算法涉及理论知识概要

3.Verilog核心程序

4.完整算法代码文件


1.算法仿真效果

vivado2019.2仿真结果如下:

2.算法涉及理论知识概要

          LFSR(线性反馈移位寄存器)提供了一种在微控制器上快速生成非序列数字列表的简单方法。生成伪随机数只需要右移操作和 XOR 操作。LFSR 完全由其多项式指定。例如,6千-次多项式与每个项存在用方程 x 表示6+ x5+ x4+ x3+ x2+ x + 1。有 2 个(6 - 1)= 32 个这种大小的不同可能多项式。与数字一样,一些多项式是素数或原始数。我们对原始多项式感兴趣,因为它们会在移位时为我们提供最大长度周期。n 次的最大长度多项式将有 2n- 1个不同的州。每个班次后都会转换到新状态。因此,6千-次多项式将有 31 种不同的状态。1 到 31 之间的每个数字在重复之前都会出现在移位寄存器中。在基元 6 的情况下千-次多项式,只有六个。表 1 列出了所有基元 6千-次多项式及其各自的多项式掩码。多项式掩码是通过采用多项式的二进制表示并截断最右侧的位来创建的。掩码用于实现多项式的代码中。实现 n 的多项式掩码需要 n 位千-次多项式。

        每个基元多项式都有奇数项,这意味着基元多项式的每个掩码都有一个偶数 1 位。每个原始多项式还定义了第二个原始多项式,即它的对偶。可以通过从每项的多项式次数中减去指数来找到对偶。例如,给定 6千-次多项式,x6+ x + 1,它的对偶是 x6-6+ x6-1+ x6-0,等于 x6+ x5+ 1.在表 1 中,多项式 1 和 2、3 和 4、5 和 6 是彼此的对偶。表 2 列出了每个不同大小多项式的周期以及每个大小存在的基元多项式的数量。表 3 列出了每个不同大小的多项式的一个多项式掩码。它还显示了当 LFSR 初始化为 1 时,LFSR 在连续班次后将保持的前四个值。此表应有助于确保实现正确。

       LFSR 的值永远不会为零,因为归零的 LFSR 的每个偏移都会将其保留为零。LFSR 必须初始化,即种子,为非零值。当 LFSR 保持 1 并移动一次时,其值将始终为多项式掩码的值。当寄存器除最高有效位外全部为零时,接下来的几个偏移将显示高位偏移到零填充的低位。例如,任何具有基元多项式的 8 位移位寄存器最终将生成序列 0x80、0x40、0x20、0x10、8、4、2、1,然后生成多项式掩码。

        一般来说,基本的LFSR不会产生非常好的随机数。通过选择较大的LFSR并使用较低的位作为随机数,可以改进更好的数字序列。例如,如果您有一个 10 位 LFSR 并且想要一个 8 位数字,则可以将寄存器底部的 8 位作为您的号码。使用此方法,您将看到每个 8 位数字四次和零,三次,然后 LFSR 完成一个周期并重复。这解决了得到零的问题,但数字仍然没有表现出非常好的统计特性。相反,您可以将 LFSR 的子集用于随机数,以增加数字的排列并改善 LFSR 输出的随机属性。

       在获得随机数之前多次移动LFSR也可以改善其统计特性。将LFSR移动其周期的一个因子将使总周期长度减少该因子。表2列出了各期间的因素。

       LFSR 相对较短的周期可以通过将两个或多个不同大小的 LFSR 的值异或相处来解决。这些异或LFSR的新周期将是周期的LCM(最小公倍数)。例如,基元 4 位和基元 6 位 LFSR 的 LCM 是 LCM(15, 63),即 315。以这种方式加入 LFSR 时,请确保仅使用最小位数的 LFSR;使用少于此量是更好的做法。对于 4 位和 6 位 LFSR,不应使用超过底部的 4 位。在图 2 中,底部的 16 位用于 32 位和 31 位 LFSR。 请注意,对两个相同大小的 LFSR 进行异或运算不会增加周期。

       LFSR的不可预测性可以通过用反馈项对一点“熵”进行异或来增加。这样做时应该小心——加上熵位,LFSR 到所有零的可能性很小。如果定期添加熵,LFSR 的归零将自行校正。这种与反馈项进行异或的方法就是CRC(循环冗余校验)的计算方式。

       多项式不是生而相等的。有些多项式肯定会比其他多项式更好。表 2 列出了可用于最大 31 位大小的基元多项式的数量。尝试不同的多项式,直到找到满足您需求的多项式。表3中给出的掩模是随机选择的。

       可以使用NIST的统计测试套件进行更广泛的测试。NIST还有几本出版物描述了随机数测试和对其他测试软件的引用。

       通过一定的算法对事先选定的随机种子(seed)做一定的运算可以得到一组人工生成的周期序列,在这组序列中以相同的概率选取其中一个数字,该数字称作伪随机数,由于所选数字并不具有完全的随机性,但是从实用的角度而言,其随机程度已足够了。

       这里的“伪”的含义是,由于该随机数是按照一定算法模拟产生的,其结果是确定的,是可见的,因此并不是真正的随机数。伪随机数的选择是从随机种子开始的,所以为了保证每次得到的伪随机数都足够地“随机”,随机种子的选择就显得非常重要,如果随机种子一样,那么同一个随机数发生器产生的随机数也会一样。

       产生伪随机数的方法最常见的是利用一种线性反馈移位寄存器(LFSR)。它是由n个D触发器和若干个异或门组成的,如图: 

       其中,gn为反馈系数,取值只能为0或1,取为0时表明不存在该反馈之路,取为1时表明存在该反馈之路;n个D触发器最多可以提供2^n-1个状态(不包括全0的状态),为了保证这些状态没有重复,gn的选择必须满足一定的条件。下面以n=3,g0=1,g1=1,g2=0,g3=1为例,说明LFSR的特性,具有该参数的LFSR结构如下图:

3.Verilog核心程序

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 

// Create Date: 2023/03/24 15:39:40
// Design Name: 
// Module Name: TEST
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module TEST();
 
reg          i_clk;  	
reg          i_rst;    	 
reg          i_load;  		 
reg  [15:0]	 i_seed;   	//随机种子
wire [15:0]	 o_rand;  	//16位随机数



tops uut(
			   	    .i_clk  (i_clk),  	
					.i_rst  (i_rst),    	 
					.i_load (i_load),  		 
					.i_seed (i_seed),     	//随机种子
					.o_rand (o_rand)  	    //16位随机数
);


initial
begin
i_clk=1'b1;
i_rst=1'b1;
i_load=1'b1;
i_seed=16'd12315;
#1000
i_rst=1'b0;
#100
i_load=1'b0;
#500;
i_load=1'b1;
i_seed=16'd5285;
#500;
i_load=1'b0;
#800;
i_load=1'b1;
end

always #5 i_clk=~i_clk;


endmodule

4.完整算法代码文件

V

猜你喜欢

转载自blog.csdn.net/hlayumi1234567/article/details/129771414
今日推荐