线性反馈移位寄存器LFSR verilog实现

一、什么是LFSR?

线性反馈移位寄存器(linear feedback shift register, LFSR)是指,给定前一状态的输出,将该输出的线性函数再用作输入的移位寄存器。异或运算是最常见的单比特线性函数:对寄存器的某些位进行异或操作后作为输入,再对寄存器中的各比特进行整体移位(百度百科定义)。

线性反馈移位寄存器反馈分为两种,一种是IE型的LFSR,即异或门内接的线性反馈移位寄存器:

在这里插入图片描述
另一种是异或门外接的线性反馈移位寄存器,简称EE型LFSR
在这里插入图片描述
gi表示接不接入反馈,只能为0或1,为1即为接入,为0不接入。

关于线性反馈移位寄存器(LFSR)数学原理更加详细的介绍,可以参考下面这篇文章。

本文主要是介绍如果使用verilog来实现LFSR电路的编写。

需要注意的是,LFSR是伪随机的,这意味着它只是接近随机,并不是完全随机的。这是因为其实从LFSR的任何状态,你都可以预测下一个状态。 有一些重要的移位寄存器属性需要注意:

  • LFSR是伪随机的,从LFSR的任何状态,都可以预测下一个状态。

  • 影响下一个状态的比特位叫做抽头。当抽头使用XOR门时,全0状态不会出现,这是因为0与0异或将始终产生0,此时LFSR将停止运行。当抽头使用XNOR门时,全1状态不会出现,这是因为1与1同或(异或非)将始终产生1,此时LFSR将停止运行。

  • 任何LFSR的最大可能迭代次数 = 2^N-1,N为级数,也就是寄存器bit位的个数。

那么怎样的LFSR才能遍历2^N-1个状态,产生最大的迭代次数呢?也就是到底寄存器的哪些位去组合然后反馈到输入端,才能使该LFSR的所有2^N-1个状态都出现呢?这里官方给了一个表,我们可以根据这个表来确定LFSR的结构:
在这里插入图片描述
需要注意的是LFSR的每一位的索引是从1开始,然后到N,一共 2^N-1个状态(因为使用异或反馈时要除去全0状态,使用异或非反馈时要除去全1状态)。表中使用的是异或非XNOR。

二、代码设计

代码设计部分没有什么难点,主要是会移位寄存器的写法就可以。然后初始值seed_data在使用XNOR时,不要给全1就可以。

`timescale 1ns / 1ps
module lfsr #(parameter Bits_Num = 5)(
   input clk,
   input rst_n,
 
   // data valid
   input seed_valid,

   // Optional Seed Value
   input [Bits_Num-1:0] seed_data,
 
   output [Bits_Num-1:0] o_LFSR_data

    );

  reg [Bits_Num:1] LFSR_reg = 0;//保存移位寄存器的状态
  reg              XNOR_reg;
 
 
    always @(posedge clk)
    begin
      if (rst_n != 1'b0)
      begin
          if (seed_valid == 1'b1)
            LFSR_reg <= seed_data;
          else
            LFSR_reg <= {LFSR_reg[Bits_Num-1:1],XNOR_reg}; //left right
      end
    end


    always @(*)
    begin
      case (Bits_Num)
        3: begin
          XNOR_reg = LFSR_reg[3] ^~ LFSR_reg[2];
        end
        4: begin
          XNOR_reg = LFSR_reg[4] ^~ LFSR_reg[3];
        end
        5: begin
          XNOR_reg = LFSR_reg[5] ^~ LFSR_reg[3];
        end
        6: begin
          XNOR_reg = LFSR_reg[6] ^~ LFSR_reg[5];
        end
        7: begin
          XNOR_reg = LFSR_reg[7] ^~ LFSR_reg[6];
        end
        8: begin
          XNOR_reg = LFSR_reg[8] ^~ LFSR_reg[6] ^~ LFSR_reg[5] ^~ LFSR_reg[4];
        end
        9: begin
          XNOR_reg = LFSR_reg[9] ^~ LFSR_reg[5];
        end
        10: begin
          XNOR_reg = LFSR_reg[10] ^~ LFSR_reg[7];
        end
        11: begin
          XNOR_reg = LFSR_reg[11] ^~ LFSR_reg[9];
        end
        12: begin
          XNOR_reg = LFSR_reg[12] ^~ LFSR_reg[6] ^~ LFSR_reg[4] ^~ LFSR_reg[1];
        end
        13: begin
          XNOR_reg = LFSR_reg[13] ^~ LFSR_reg[4] ^~ LFSR_reg[3] ^~ LFSR_reg[1];
        end
        14: begin
          XNOR_reg = LFSR_reg[14] ^~ LFSR_reg[5] ^~ LFSR_reg[3] ^~ LFSR_reg[1];
        end
        15: begin
          XNOR_reg = LFSR_reg[15] ^~ LFSR_reg[14];
        end
        16: begin
          XNOR_reg = LFSR_reg[16] ^~ LFSR_reg[15] ^~ LFSR_reg[13] ^~ LFSR_reg[4];
          end
        17: begin
          XNOR_reg = LFSR_reg[17] ^~ LFSR_reg[14];
        end
        18: begin
          XNOR_reg = LFSR_reg[18] ^~ LFSR_reg[11];
        end
        19: begin
          XNOR_reg = LFSR_reg[19] ^~ LFSR_reg[6] ^~ LFSR_reg[2] ^~ LFSR_reg[1];
        end
        20: begin
          XNOR_reg = LFSR_reg[20] ^~ LFSR_reg[17];
        end
        21: begin
          XNOR_reg = LFSR_reg[21] ^~ LFSR_reg[19];
        end
        22: begin
          XNOR_reg = LFSR_reg[22] ^~ LFSR_reg[21];
        end
        23: begin
          XNOR_reg = LFSR_reg[23] ^~ LFSR_reg[18];
        end
        24: begin
          XNOR_reg = LFSR_reg[24] ^~ LFSR_reg[23] ^~ LFSR_reg[22] ^~ LFSR_reg[17];
        end
        25: begin
          XNOR_reg = LFSR_reg[25] ^~ LFSR_reg[22];
        end
        26: begin
          XNOR_reg = LFSR_reg[26] ^~ LFSR_reg[6] ^~ LFSR_reg[2] ^~ LFSR_reg[1];
        end
        27: begin
          XNOR_reg = LFSR_reg[27] ^~ LFSR_reg[5] ^~ LFSR_reg[2] ^~ LFSR_reg[1];
        end
        28: begin
          XNOR_reg = LFSR_reg[28] ^~ LFSR_reg[25];
        end
        29: begin
          XNOR_reg = LFSR_reg[29] ^~ LFSR_reg[27];
        end
        30: begin
          XNOR_reg = LFSR_reg[30] ^~ LFSR_reg[6] ^~ LFSR_reg[4] ^~ LFSR_reg[1];
        end
        31: begin
          XNOR_reg = LFSR_reg[31] ^~ LFSR_reg[28];
        end
        32: begin
          XNOR_reg = LFSR_reg[32] ^~ LFSR_reg[22] ^~ LFSR_reg[2] ^~ LFSR_reg[1];
        end
 
      endcase // case (Bits_Num)
    end // always @ (*)

    assign o_LFSR_data = LFSR_reg;


endmodule
仿真程序:
`timescale 1ns / 1ps
module lfsr_tb ();
 
  parameter Bits_Num = 5;
  //input
  reg clk = 1'b0;
  reg rst_n = 1'b0;
  reg seed_valid = 1'b0;
  reg [Bits_Num-1:0]seed_data = 1'b0;
  //output
  wire [Bits_Num-1:0] o_LFSR_data;
   
  lfsr #(.Bits_Num(Bits_Num)) u_lfsr
         (.clk(clk),
          .rst_n(rst_n),
          .seed_valid(seed_valid),
          .seed_data(seed_data),
          .o_LFSR_data(o_LFSR_data)
          );
  
  always @(*)
    #5 clk <= ~clk; 
   
initial
begin
    #20 rst_n  =  1;
end

initial
begin
    #15 seed_valid  =  1;
        seed_data   =  5;
    #10 seed_valid  =  0;
end
initial
begin
    #100 $finish;
end
endmodule 

在这里插入图片描述
在25ns时采样到seed_data = 5LFSR_reg初始值被置为了00101,然后通过:

LFSR_reg <= {LFSR_reg[Bits_Num-1:1],XNOR_reg}; //left right
XNOR_reg = LFSR_reg[5] ^~ LFSR_reg[3];

计算得到00001也即1,然后后面依次按照算法计算即可。

posted @ 2021-09-27 12:07  耐心的小黑  阅读(745)  评论(0编辑  收藏  举报