FPGA项目开发:基于FPGA的伪随机数发生器(带代码)今天,画师和大师们见面了。 我在写绘画FPGA江湖。 本人写了关于FPGA的伪随机数发生器的学习笔记。 这里分享仅供参考。
另一方面,概念随机数是专业随机试验的结果,产生随机数有几种不同的方法。 这些方法称为随机数发生器。 随机数最重要的特性是发生时的后数与前数无关。 随机数分为伪随机数、密码学安全伪随机数和真随机数三种。
这次设计为基于FPGA生成的伪随机数发生器,但什么是伪随机数呢? 统计学伪随机性指的是在给定随机比特流的样本中1的数目近似等于0,并且类似地,四个“10”、“01”、“00”和“11”的数目近似相等。 相似的标准被称为统计学随机性。 满足这种要求的数字对人类来说是“乍一看”随机的。
实用上,伪随机数往往就足够了。 这些数列是“宛如”随机数,实际上通过固定的可重复计算方法产生。 计算机和计算机产生的随机数有很长的周期性。 它们实际上不是随机的,因为它们可以实际计算,但具有类似随机数的统计特征。 这种发生器称为伪随机数发生器。
二、设计原理本次设计采用线性反馈移位寄存器(Linear Feedback Shift Register,LFSR ) )实现伪随机数发生器。 线性反馈移位寄存器是给出紧接在前状态的输出并使用其输出的线性函数作为输入的移位寄存器。 异或运算是最常见的单比特线性函数。 对寄存器的部分位进行异或运算后,作为输入,将寄存器内的各位整体移位。
线性反馈移位寄存器通常由动态或静态主从触发器构成。 反馈电路由异或门构成。 其特性通常用一个特征多项式表示。 LFSR结构如下图所示。
图1 LFSR结构示意图
对应的特征多项式如下:
Gm是多项式的系数,多项式系数只有1或0。
要利用LFSR生成伪随机数,必须给出随机种子(seed )。 种子不能为全0,因为它由n个触发器和异或门组成。 给定全0,就会陷入0的死循环,一直出不来,得不到我们想要的伪随机数。 在设计时,可以给出任意非0的数。
根据以上原理,我们用本原多项式x^32 x^7 x^5 x^3 x^2 x 1构造最大周期的LFSR。
三、架构设计框架如下图。
将输入时钟命名为clk,将复位信号命名为rst_n,将输入有效信号命名为ivalid,将输入的随机种子命名为seed[31:0],将生成的随机数命名为data[31:0]。
四、Verilog码实现代码中的data=seed部分可以不需要,可以不输入有效信号和随机种子,也可以直接初始化为零值以外的值。 如果直接初始化为零以外的值,则重置模拟代码即可。
实现代码如下:
模块prng (inputwireclk,inputwirerst_n,inputwireivalid,inputwire[31:0]seed,outputreg[31:0]data ) elseif(ivalid==1'B1 ) data=seed; elsebegindata[0]=data[31]; data[1]=data[0]^data[31]; data[2]=data[1]^data[31]; data[3]=data[2]^data[31]; 数据[4]=数据[3]; data[5]=data[4]^data[31]; data[6]=data[5]; data[7]=data[6]^data[31]; data[8]=data[7]; 数据[9]=数据[8]; data[10]=data[9]; 数据[ 11 ]=数据[ 10 ]; 数据[ 12 ]=数据[ 11 ]; 数据[ 13 ]=数据[ 12 ]; 数据[ 14 ]=数据[ 13 ]; 数据[ 15 ]=数据[ 14 ]; data[16]=data[15]; 数据[ 17 ]=数据[ 16 ]; 数据[ 18 ]=数据[ 17 ]; 数据[ 19 ]=数据[ 18 ]; 数据[ 20 ]=数据[ 19 ]; 数据传输
[21] <= data[20]; data[22] <= data[21]; data[23] <= data[22]; data[24] <= data[23]; data[25] <= data[24]; data[26] <= data[25]; data[27] <= data[26]; data[28] <= data[27]; data[29] <= data[28]; data[30] <= data[29]; data[31] <= data[30]; end endendmodule 五、仿真测试及结果仿真代码如下:
`timescale 1ns/1psmodule PRNG_tb; reg clk; reg rst_n; reg ivalid; reg [31:0] seed; wire [31:0] data; PRNG PRNG_inst( .clk (clk), .rst_n (rst_n), .ivalid (ivalid), .seed (seed), .data (data) ); initial clk = 1'b0; always # 5 clk = ~clk; initial begin rst_n = 1'b0; ivalid = 1'b0; seed = 32'd0; # 201; rst_n = 1'b1; #200; @ (posedge clk); # 2; ivalid = 1'b1; seed = {$random} % 4294967295; @ (posedge clk); # 2; ivalid = 1'b0; seed = 32'd0; #200000; $stop; endendmodule本次仿真采用100M时钟进行,输入种子为非零随机数。
六、总结以上是经过学习,集合了各家所长得到的结果。由于想做一个32位的伪随机数发生器,在网上找了各种资料,并没有找到有规定的标准多项式,于是随意定了一个。在实际运用当中,如果有标准的多项式系数,可能得到了一个伪随机数,就可以根据已知的特征式得出后面的结果,安全性也就大大降低了。
【QQ交流群】群号:173560979,进群暗语:FPGA技术江湖粉丝。
多年的FPGA企业开发经验,各种通俗易懂的学习资料以及学习方法,浓厚的交流学习氛围,QQ群目前已有1000多名志同道合的小伙伴,无广告纯净模式,给技术交流一片净土,从初学ddw到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有。
【微信交流群】现微信交流群已建立09群,人数已达数千人,欢迎关注“FPGA技术江湖”微信公众号,可获取进群方式。
完
后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。
江湖偌大,继续闯荡,愿大侠一切安好,有缘再见!