LFSR(线性反馈移位寄存器)

线性反馈移位寄存器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。

如果初始序列是101,
则输出为:101001110100111010011……

`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,其下一时刻值就是其前一位的值,但是输入位的值,就需要其参与异或得到。

  • 10
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值