Verilog 之 LFSR伪随机数 (转载)

转载:http://blog.csdn.net/hengzo/article/details/49689725

The linear feedback shift register is implemented as a series of Flip-Flops inside of an FPGA that are wired together as a shift register. Several taps off of the shift register chain are used as inputs to either an XOR or XNOR gate. The output of this gate is then used as feedback to the beginning of the shift register chain, hence the Feedback in LFSR.

  • LFSR patterns are pseudo-random.
  • Output patterns are deterministic. You can figure out the next state by knowing the position of the XOR gates as well as the current pattern.
  • A pattern of all 0‘s cannot appear when the taps use XOR gates. Since 0 XORed with 0 will always produce 0, the LFSR will stop running.注意初始化种子
  • A pattern of all 1‘s cannot appear when the taps use XNOR gates. Since 1 XNORed with 1 will always produce 1, the LFSR will stop running.
  • The maximum possible number of iterations of any LFSR = 2Bits-1

产生伪随机数的方法最常见的是利用一种线性反馈移位寄存器(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结构如下图:

假设在开始时,D2D1D0=111(seed),那么,当时钟到来时,有:

  D2=D1_OUT=1;

  D1=D0_OUT^D2_OUT=0;

  D0=D2_OUT=1;

即D2D1D0=101;同理,又一个时钟到来时,可得D2D1D0=001. ………………

画出状态转移图如下:

从图可以看出,正好有2^3-1=7个状态,不包括全0;

  如果您理解了上图,至少可以得到三条结论:

  1)初始状态是由SEED提供的;

  2)当反馈系数不同时,得到的状态转移图也不同;必须保证gn===1。

  3)D触发器的个数越多,产生的状态就越多,也就越“随机”;

verilog实现

  1 <pre name="code" class="plain">//文章地址:http://www.nandland.com/vhdl/modules/lfsr-linear-feedback-shift-register.html
  2 //程序地址:http://www.nandland.com/verilog/modules/code/LFSR.v
  3
  4
  5 ///////////////////////////////////////////////////////////////////////////////
  6 // File downloaded from http://www.nandland.com
  7 ///////////////////////////////////////////////////////////////////////////////
  8 // Description:
  9 // A LFSR or Linear Feedback Shift Register is a quick and easy way to generate
 10 // pseudo-random data inside of an FPGA.  The LFSR can be used for things like
 11 // counters, test patterns, scrambling of data, and others.  This module
 12 // creates an LFSR whose width gets set by a parameter.  The o_LFSR_Done will
 13 // pulse once all combinations of the LFSR are complete.  The number of clock
 14 // cycles that it takes o_LFSR_Done to pulse is equal to 2^g_Num_Bits-1.  For
 15 // example setting g_Num_Bits to 5 means that o_LFSR_Done will pulse every
 16 // 2^5-1 = 31 clock cycles.  o_LFSR_Data will change on each clock cycle that
 17 // the module is enabled, which can be used if desired.
 18 //
 19 // Parameters:
 20 // NUM_BITS - Set to the integer number of bits wide to create your LFSR.
 21 ///////////////////////////////////////////////////////////////////////////////
 22 module LFSR #(parameter NUM_BITS)
 23   (
 24    input i_Clk,
 25    input i_Enable,
 26
 27    // Optional Seed Value
 28    input i_Seed_DV,
 29    input [NUM_BITS-1:0] i_Seed_Data,
 30
 31    output [NUM_BITS-1:0] o_LFSR_Data,
 32    output o_LFSR_Done
 33    );
 34
 35   reg [NUM_BITS:1] r_LFSR = 0;
 36   reg              r_XNOR;
 37
 38
 39   // Purpose: Load up LFSR with Seed if Data Valid (DV) pulse is detected.
 40   // Othewise just run LFSR when enabled.
 41   // 初始化seed值可以选择载入,
 42   always @(posedge i_Clk)
 43     begin
 44       if (i_Enable == 1‘b1)
 45         begin
 46           if (i_Seed_DV == 1‘b1)
 47             r_LFSR <= i_Seed_Data;
 48           else
 49             r_LFSR <= {r_LFSR[NUM_BITS-1:1], r_XNOR};
 50         end
 51     end
 52
 53   // Create Feedback Polynomials.  Based on Application Note:
 54   // http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
 55   //使用同或运算,初始化种子不能全1
 56
 57
 58   always @(*)
 59     begin
 60       case (NUM_BITS)
 61         3: begin
 62           r_XNOR = r_LFSR[3] ^~ r_LFSR[2];
 63         end
 64         4: begin
 65           r_XNOR = r_LFSR[4] ^~ r_LFSR[3];
 66         end
 67         5: begin
 68           r_XNOR = r_LFSR[5] ^~ r_LFSR[3];
 69         end
 70         6: begin
 71           r_XNOR = r_LFSR[6] ^~ r_LFSR[5];
 72         end
 73         7: begin
 74           r_XNOR = r_LFSR[7] ^~ r_LFSR[6];
 75         end
 76         8: begin
 77           r_XNOR = r_LFSR[8] ^~ r_LFSR[6] ^~ r_LFSR[5] ^~ r_LFSR[4];
 78         end
 79         9: begin
 80           r_XNOR = r_LFSR[9] ^~ r_LFSR[5];
 81         end
 82         10: begin
 83           r_XNOR = r_LFSR[10] ^~ r_LFSR[7];
 84         end
 85         11: begin
 86           r_XNOR = r_LFSR[11] ^~ r_LFSR[9];
 87         end
 88         12: begin
 89           r_XNOR = r_LFSR[12] ^~ r_LFSR[6] ^~ r_LFSR[4] ^~ r_LFSR[1];
 90         end
 91         13: begin
 92           r_XNOR = r_LFSR[13] ^~ r_LFSR[4] ^~ r_LFSR[3] ^~ r_LFSR[1];
 93         end
 94         14: begin
 95           r_XNOR = r_LFSR[14] ^~ r_LFSR[5] ^~ r_LFSR[3] ^~ r_LFSR[1];
 96         end
 97         15: begin
 98           r_XNOR = r_LFSR[15] ^~ r_LFSR[14];
 99         end
100         16: begin
101           r_XNOR = r_LFSR[16] ^~ r_LFSR[15] ^~ r_LFSR[13] ^~ r_LFSR[4];
102           end
103         17: begin
104           r_XNOR = r_LFSR[17] ^~ r_LFSR[14];
105         end
106         18: begin
107           r_XNOR = r_LFSR[18] ^~ r_LFSR[11];
108         end
109         19: begin
110           r_XNOR = r_LFSR[19] ^~ r_LFSR[6] ^~ r_LFSR[2] ^~ r_LFSR[1];
111         end
112         20: begin
113           r_XNOR = r_LFSR[20] ^~ r_LFSR[17];
114         end
115         21: begin
116           r_XNOR = r_LFSR[21] ^~ r_LFSR[19];
117         end
118         22: begin
119           r_XNOR = r_LFSR[22] ^~ r_LFSR[21];
120         end
121         23: begin
122           r_XNOR = r_LFSR[23] ^~ r_LFSR[18];
123         end
124         24: begin
125           r_XNOR = r_LFSR[24] ^~ r_LFSR[23] ^~ r_LFSR[22] ^~ r_LFSR[17];
126         end
127         25: begin
128           r_XNOR = r_LFSR[25] ^~ r_LFSR[22];
129         end
130         26: begin
131           r_XNOR = r_LFSR[26] ^~ r_LFSR[6] ^~ r_LFSR[2] ^~ r_LFSR[1];
132         end
133         27: begin
134           r_XNOR = r_LFSR[27] ^~ r_LFSR[5] ^~ r_LFSR[2] ^~ r_LFSR[1];
135         end
136         28: begin
137           r_XNOR = r_LFSR[28] ^~ r_LFSR[25];
138         end
139         29: begin
140           r_XNOR = r_LFSR[29] ^~ r_LFSR[27];
141         end
142         30: begin
143           r_XNOR = r_LFSR[30] ^~ r_LFSR[6] ^~ r_LFSR[4] ^~ r_LFSR[1];
144         end
145         31: begin
146           r_XNOR = r_LFSR[31] ^~ r_LFSR[28];
147         end
148         32: begin
149           r_XNOR = r_LFSR[32] ^~ r_LFSR[22] ^~ r_LFSR[2] ^~ r_LFSR[1];
150         end
151
152       endcase // case (NUM_BITS)
153     end // always @ (*)
154
155
156   assign o_LFSR_Data = r_LFSR[NUM_BITS:1];
157
158   // Conditional Assignment (?)
159   //一个循坏结束,数据个数2^NUM_BITS -1
160   assign o_LFSR_Done = (r_LFSR[NUM_BITS:1] == i_Seed_Data) ? 1‘b1 : 1‘b0;
161
162 endmodule // LFSR 

testbench程序:

`timescale 1ns / 100ps  

`define N_BITS 4
module tb_lfsr;  

    reg i_Clk;
    reg i_Enable;  

    // Optional Seed Value
    reg i_Seed_DV;
    reg [`N_BITS-1:0] i_Seed_Data;  

    wire [`N_BITS-1:0] o_LFSR_Data;
    wire o_LFSR_Done;  

    LFSR #(.NUM_BITS(`N_BITS)) dut( .i_Clk(i_Clk),
                                    .i_Enable(i_Enable),
                                    .i_Seed_DV(i_Seed_DV),
                                    .i_Seed_Data(i_Seed_Data),
                                    .o_LFSR_Data(o_LFSR_Data),
                                    .o_LFSR_Done(o_LFSR_Done));  

    always #10 i_Clk = ~i_Clk;  

    initial begin
        i_Clk = 0;
        i_Enable = 0;
        i_Seed_DV = 0;
        i_Seed_Data = 0;  

        #15;
        i_Enable = 1;
        i_Seed_DV = 1;
        @(posedge i_Clk);
        #5;
        i_Seed_DV = 0;
    end  

endmodule  

Modelsim仿真结果:


//参考文章地址:http://www.nandland.com/vhdl/modules/lfsr-linear-feedback-shift-register.html
//参考程序地址:http://www.nandland.com/verilog/modules/code/LFSR.v

时间: 2024-08-24 06:29:39

Verilog 之 LFSR伪随机数 (转载)的相关文章

verilog断言(SVA:systemverlog assertion)语法 ---- 转载

转载自:http://blog.sina.com.cn/s/blog_4c270c730101f6mw.html 作者:白栎旸 断言assertion被放在verilog设计中,方便在仿真时查看异常情况.当异常出现时,断言会报警.一般在数字电路设计中都要加入断言,断言占整个设计的比例应不少于30%.以下是断言的语法: 1. SVA的插入位置:在一个.v文件中: module ABC (); rtl 代码 SVA断言 endmodule 注意:不要将SVA写在enmodule外面. 2. 断言编写

转载Verilog乘法器

1. 串行乘法器 两个N位二进制数x.y的乘积用简单的方法计算就是利用移位操作来实现. module multi_CX(clk, x, y, result); input clk; input [7:0] x, y; output [15:0] result; reg [15:0] result; parameter s0 = 0, s1 = 1, s2 = 2; reg [2:0] count = 0; reg [1:0] state = 0; reg [15:0] P, T; reg [7:

[转载](转帖)如何使用integer型別? (IC Design) (Verilog)

Abstract 在C/C++或任何程式語言,integer是最常用的型別之一,但在Verilog大部分用的都是wire和reg,很少用到integer,該如何正確地使用integer呢? Introduction 首先,integer和reg與wire最大的差別是,integer本身是個32位元的有號數,含正負. 實務上,若在RTL中,integer建議只出現於for loop中,用來複製電路,讓程式精簡一些,在其他地方使用這種類型的的變數,容易出現與設計者意料之外的情況[1]. 如一個4 b

verilog 实现fifo(转载)

对基于单体存储器的FIFO,作为一种数据缓冲器,其数据存放结构和RAM是一致的,只是存取方式有所不同.因RAM中的各存储单元可被随机读写,故FIFO的队首位置及队列长度均可浮动.为此,需要用两个地址寄存器,分别存储读地址(即队首元素地址)和写地址(即队尾元素地址加1).在读写过程中FIFO所存储的信息并不移动,而是通过改变读地址或写地址来指示队首队尾.      本32X8 FIFO的设计,采用了双体存储器的交替读写机制,使得在对其中一个存储器写操作的同时可以对另一个存储器进行读操作;对其中一个

(转载)FPGA实现开发运算verilog

http://bbs.ednchina.com/BLOG_ARTICLE_3003247.HTM 专题五:开方运算 开方运算虽然不像加法.乘法那么常用,但是也有其用武之地.在去年的一个项目中,笔者负责的模块中就使用了开方运算,开始时使用的是Altera的IP Core,验证模块使用没有问题:但是因为平台转换,需要转换到Xilinx的平台,许多IP Core也需要转移,最后干脆自己写一个得了,包括前几个专题中的乘法器.除法器. 开方运算模块也使用与除法器类似的NonRestoring算法,包含输入

【转载】关于generate用法的总结【Verilog】

http://www.cnblogs.com/nanoty/archive/2012/11/13/2768933.html Abtract generate语句允许细化时间(Elaboration-time)的选取或者某些语句的重复.这些语句可以包括模块实例引用的语句.连续赋值语句.always语句.initial语句和门级实例引用语句等.细化时间是指仿真开始前的一个阶段,此时所有的设计模块已经被链接到一起,并完成层次的引用. Introduction 1.generate语法 定义genvar

乘法器的Verilog HDL实现(转载)

原文地址:http://www.cnblogs.com/shengansong/archive/2011/05/23/2054401.html 1. 串行乘法器 两个N位二进制数x.y的乘积用简单的方法计算就是利用移位操作来实现. module multi_CX(clk, x, y, result); input clk; input [7:0] x, y; output [15:0] result; reg [15:0] result; parameter s0 = 0, s1 = 1, s2

伪随机数算法(一)

伪随机数概念在我大学一年级接触C语言基础的时候就听说过,并熟练掌握C语言中rand()函数的使用方法.不过,当时我对伪随机数的认识基本也就停留在百度百科那种小白水平,最多就知道老师说我们用的随机数是假的,是通过某种算法实现的.最近学习计算物理学讲到Monte Carlo方法时,通过课本和互联网才算真正意义上理解了什么是伪随机数.借此文好好总结一下吧! 一.随机数的分类 在计算物理学中,随机数被准确地分成了三类:真随机数.准随机数.伪随机数.那么这三种的区别是什么呢?拷贝一段书上的定义(我觉得写的

使用线性同余法生成伪随机数/序列(C++实现)2

以下是网上关于随机数生成的一类说法: 在计算机上可以用物理方法来产生随机数,但价格昂贵,不能重复,使用不便.另一种方法是用数学递推公式产生,这样产生的序列与真正的随机数序列不同,所以称为伪随机数或伪随机序列,只要方法和参数选择合适,所产生的伪随机数就能满足均匀性和独立性,与真正的随机数具有相近的性质. 以下是一个使用了线性同余的递推公式: Xt = (X0 * 17 + 29) mod 500 线性同余中的线性,是指"线性"表示方程中 x 的次数是一次,mod 取余运算符则体现了&qu