线性反馈移位寄存器LFSR,是移位寄存器的一种,通常用于在数字电路中产生伪随机数。寄存器中的初始值叫做种子,种子应该是非零的。LFSR的下一时刻输入为是由整个移位寄存器值的某些位做异或运算的结果。选取哪些位置 用于移位,是需要进行预先设计好的,目的是要产生一个伪随机并且尽可能长周期的数字序列。
n位LFSR,最多产生2^(n-1)种序列(全零或全一被排除,因为全零异或nor结果为0,不会产生新序列,全1同或xnor也是)。
影响下一个状态的比特位叫做抽头。移位寄存器链的多个抽头用作XOR或XNOR门的输入。 然后,此门的输出用作对移位寄存器链开始的反馈,因此用作LFSR中的反馈。
注意:当抽头使用XOR门时,全0的模式不会出现。 当抽头使用XNOR门时,全1的模式将不会出现。 此两种情况LFSR将停止运行。LFSR是伪随机的。输出模式是确定性,可以通过了解XOR门的位置以及当前模式来确定下一个状态。
怎样选取抽头可以产生最大长度的随机序列,可以参考下表;

LFSR的特征方程根据抽头位置来定:

这里可以表示为f(x)=1+c1x+c2x^(2)+c3x^(3)+…+cnx^(n)
比如,如果n=3,f(x)=1+c1x+c2x^(2)+c3x^(3),其中c1和c3为1,那么f(x)=1+x+x^3,抽头对应为a3,a2。
`timescale 1ns/1ps module top_module (); reg clk=0; always #5 clk = ~clk; // Create clock with period=10 initial `probe_start; // Start the timing diagram `probe(clk); // Probe signal "clk" // A testbench reg set_seed; reg [2:0] seed_data; reg enable; parameter bits_num=3; initial begin set_seed=1; enable=1; seed_data=3'b101; #10 set_seed=0; #60 $finish; // Quit the simulation end LFSR #(.bits_num(bits_num)) inst1( .clk(clk),.enable(enable),.set_seed(set_seed),.seed_data(seed_data)); // Sub-modules work too. endmodule module LFSR #(parameter bits_num=3)( input clk, input enable, input set_seed, input [bits_num-1:0] seed_data, output [bits_num-1:0] lfsr_data, output lfsr_done//cycle done ); `probe(clk); `probe(enable); `probe(set_seed); `probe(seed_data); `probe(lfsr_data); `probe(r_lfsr); reg [bits_num:1] r_lfsr; reg r_xnor; always @(posedge clk) begin if (enable == 1'b1) begin if (set_seed == 1'b1) r_lfsr <= seed_data; else begin $display("1.r_lfsr=%b,time=%g",r_lfsr,$time); r_lfsr <= {r_lfsr[bits_num-1:1],r_xnor}; $display("2.r_lfsr=%b,r_xnor=%b,time=%g",r_lfsr,r_xnor,$time); end end end always @(*)//一开始就要有变化,所以不设置为posedge clk。 begin case (bits_num)//3-32 3: begin r_xnor = r_lfsr[3] ^~ r_lfsr[2]; end 4: begin r_xnor = r_lfsr[4] ^~ r_lfsr[3]; end 5: begin r_xnor = r_lfsr[5] ^~ r_lfsr[3]; end 6: begin r_xnor = r_lfsr[6] ^~ r_lfsr[5]; end 7: begin r_xnor = r_lfsr[7] ^~ r_lfsr[6]; end 8: begin r_xnor = r_lfsr[8] ^~ r_lfsr[6] ^~ r_lfsr[5] ^~ r_lfsr[4]; end 9: begin r_xnor = r_lfsr[9] ^~ r_lfsr[5]; end 10: begin r_xnor = r_lfsr[10] ^~ r_lfsr[7]; end 11: begin r_xnor = r_lfsr[11] ^~ r_lfsr[9]; end 12: begin r_xnor = r_lfsr[12] ^~ r_lfsr[6] ^~ r_lfsr[4] ^~ r_lfsr[1]; end 13: begin r_xnor = r_lfsr[13] ^~ r_lfsr[4] ^~ r_lfsr[3] ^~ r_lfsr[1]; end 14: begin r_xnor = r_lfsr[14] ^~ r_lfsr[5] ^~ r_lfsr[3] ^~ r_lfsr[1]; end 15: begin r_xnor = r_lfsr[15] ^~ r_lfsr[14]; end 16: begin r_xnor = r_lfsr[16] ^~ r_lfsr[15] ^~ r_lfsr[13] ^~ r_lfsr[4]; end 17: begin r_xnor = r_lfsr[17] ^~ r_lfsr[14]; end 18: begin r_xnor = r_lfsr[18] ^~ r_lfsr[11]; end 19: begin r_xnor = r_lfsr[19] ^~ r_lfsr[6] ^~ r_lfsr[2] ^~ r_lfsr[1]; end 20: begin r_xnor = r_lfsr[20] ^~ r_lfsr[17]; end 21: begin r_xnor = r_lfsr[21] ^~ r_lfsr[19]; end 22: begin r_xnor = r_lfsr[22] ^~ r_lfsr[21]; end 23: begin r_xnor = r_lfsr[23] ^~ r_lfsr[18]; end 24: begin r_xnor = r_lfsr[24] ^~ r_lfsr[23] ^~ r_lfsr[22] ^~ r_lfsr[17]; end 25: begin r_xnor = r_lfsr[25] ^~ r_lfsr[22]; end 26: begin r_xnor = r_lfsr[26] ^~ r_lfsr[6] ^~ r_lfsr[2] ^~ r_lfsr[1]; end 27: begin r_xnor = r_lfsr[27] ^~ r_lfsr[5] ^~ r_lfsr[2] ^~ r_lfsr[1]; end 28: begin r_xnor = r_lfsr[28] ^~ r_lfsr[25]; end 29: begin r_xnor = r_lfsr[29] ^~ r_lfsr[27]; end 30: begin r_xnor = r_lfsr[30] ^~ r_lfsr[6] ^~ r_lfsr[4] ^~ r_lfsr[1]; end 31: begin r_xnor = r_lfsr[31] ^~ r_lfsr[28]; end 32: begin r_xnor = r_lfsr[32] ^~ r_lfsr[22] ^~ r_lfsr[2] ^~ r_lfsr[1]; end endcase end assign lfsr_data = r_lfsr[bits_num:1]; assign lfsr_done = (r_lfsr[bits_num:1] == seed_data) ? 1'b1 : 1'b0; endmodule
结果:


LFSR分为两种:一种是IE型的LFSR,即异或门内接的线性反馈移位寄存器,如下图第一张。另一种是异或门外接的线性反馈移位寄存器,简称EE型LFSR,如第二张。这两种类型在代码表现上是不一样的。第一种LFSR的任何一位,如果g=1,其下一时刻值就是输出位以及其前一位的异或。
第二种LFSR的任何一位,如果g=1,其下一时刻值就是其前一位的值,但是输入位的值,就需要其参与异或得到。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229974.html原文链接:https://javaforall.net
