Verilog設(shè)計(jì)實(shí)例(1)線性反饋移位寄存器(LFSR)

寫在前面

相關(guān)博文
博客首頁(yè)
注:學(xué)習(xí)交流使用!

正文

原理

線性反饋移位寄存器(LFSR)的英文全稱為:Linear Feedback Shift Register。
賽靈思公司的高速串口IP核示例程序經(jīng)常以LFSR為例,例如Aurora IP的例子程序:

    //______________________________ Transmit Data  __________________________________   
    //Transmit data when TX_DST_RDY_N is asserted.
    //Random data is generated using XNOR feedback LFSR
    //TX_SRC_RDY_N is asserted on every cycle with data
    always @(posedge USER_CLK)
        if(reset_c)
        begin
            data_lfsr_r          <=  `DLY    16'hABCD;  //random seed value
            TX_SRC_RDY_N    <=  `DLY    1'b1;   
        end
        else if(!TX_DST_RDY_N)
        begin
            data_lfsr_r          <=  `DLY    {!{data_lfsr_r[3]^data_lfsr_r[12]^data_lfsr_r[14]^data_lfsr_r[15]},
                                data_lfsr_r[0:14]};
            TX_SRC_RDY_N    <=  `DLY    1'b0;
        end
   
    //Connect TX_D to the DATA LFSR register
    assign  TX_D    =   {1{data_lfsr_r}};

相關(guān)博客鏈接


LFSR代表線性反饋移位寄存器,它是一種在FPGA內(nèi)部有用的設(shè)計(jì)。 LFSR易于合成,這意味著它們占用的資源相對(duì)較少,并且可以在FPGA內(nèi)部以很高的時(shí)鐘速率運(yùn)行。 使用LFSR可以使許多應(yīng)用受益,包括:

  • 計(jì)數(shù)器(Counters)
  • 測(cè)試碼型發(fā)生器(Test Pattern Generators)
  • 數(shù)據(jù)加擾(Data Scrambling)
  • 密碼學(xué)(Cryptography)

線性反饋移位寄存器實(shí)現(xiàn)為FPGA內(nèi)部的一系列觸發(fā)器,這些觸發(fā)器連接在一起作為移位寄存器。 移位寄存器鏈的多個(gè)抽頭用作XOR或XNOR門的輸入。 然后,此門的輸出用作對(duì)移位寄存器鏈開始的反饋,因此用作LFSR中的反饋。
例如5bit的LFSR的一種形式:


5位LFSR

運(yùn)行LFSR時(shí),由各個(gè)觸發(fā)器生成的模式是偽隨機(jī)的,這意味著它接近隨機(jī)。 它不是完全隨機(jī)的,因?yàn)閺腖FSR模式的任何狀態(tài),您都可以預(yù)測(cè)下一個(gè)狀態(tài)。 有一些重要的移位寄存器屬性需要注意:

  • LFSR模式是偽隨機(jī)的。
  • 輸出模式是確定性的。 您可以通過了解XOR門的位置以及當(dāng)前模式來確定下一個(gè)狀態(tài)。
    當(dāng)抽頭使用XOR門時(shí),全0的模式不會(huì)出現(xiàn)。 由于0與0異或?qū)⑹冀K產(chǎn)生0,因此LFSR將停止運(yùn)行。
  • 當(dāng)抽頭使用XNOR門時(shí),全1的模式將不會(huì)出現(xiàn)。 由于將1與1進(jìn)行異或運(yùn)算將始終產(chǎn)生1,因此LFSR將停止運(yùn)行。
  • 任何LFSR的最大可能迭代次數(shù)= 2^Bits-1

更長(zhǎng)的LFSR將花費(fèi)更長(zhǎng)的時(shí)間來運(yùn)行所有迭代。 N位LFSR的最大可能迭代次數(shù)為2^N-1。
如果您考慮一下,所有N位長(zhǎng)的東西的所有可能模式都是2^N。 因此,只有一種模式無法使用LFSR表示。 當(dāng)使用XOR門時(shí),該模式全為0,而使用XNOR門作為您的反饋門時(shí)全為1。
VHDL和Verilog代碼創(chuàng)建所需的任何N位寬的LFSR。 它使用多項(xiàng)式(這是LFSR背后的數(shù)學(xué)方法)為每個(gè)位寬創(chuàng)建最大可能的LFSR長(zhǎng)度。
因此,對(duì)于3位,需要2^3-1 = 7個(gè)時(shí)鐘來運(yùn)行所有可能的組合;
對(duì)于4位:2^4-1 = 15;
對(duì)于5位:2^5-1 = 31,依此類推。
我基于XNOR實(shí)現(xiàn) 以允許FPGA在LFSR上以全零狀態(tài)啟動(dòng)。 這是Xilinx發(fā)布的所有LFSR模式的完整表

Verilog實(shí)現(xiàn)

下面給出Verilog實(shí)現(xiàn)代碼:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Reborn Lee
// Module Name: lfsr
//https://blog.csdn.net/Reborn_Lee
//////////////////////////////////////////////////////////////////////////////////


module lfsr #(parameter NUM_BITS = 3)(
   input i_Clk,
   input i_Enable,
 
   // data valid
   input i_Seed_DV,

   // Optional Seed Value
   input [NUM_BITS-1:0] i_Seed_Data,
 
   output [NUM_BITS-1:0] o_LFSR_Data,
   output o_LFSR_Done

    );

  // internal variables
  reg [NUM_BITS:1] r_LFSR = 0;
  reg              r_XNOR;
 
 
  // Purpose: Load up LFSR with Seed if Data Valid (DV) pulse is detected.
  // Othewise just run LFSR when enabled.
    always @(posedge i_Clk)
    begin
      if (i_Enable == 1'b1)
      begin
          if (i_Seed_DV == 1'b1)
            r_LFSR <= i_Seed_Data;
          else
            r_LFSR <= {r_LFSR[NUM_BITS-1:1],r_XNOR}; //left right
      end
    end

// Create Feedback Polynomials.  Based on Application Note:
  // http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
    always @(*)
    begin
      case (NUM_BITS)
        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 // case (NUM_BITS)
    end // always @ (*)

    assign o_LFSR_Data = r_LFSR[NUM_BITS:1];
 
    // Conditional Assignment (?)
    assign o_LFSR_Done = (r_LFSR[NUM_BITS:1] == i_Seed_Data) ? 1'b1 : 1'b0;


endmodule

仿真測(cè)試

給出一個(gè)簡(jiǎn)單的仿真測(cè)試:

`timescale 1ns / 1ps
module lfsr_tb ();
 
  parameter c_NUM_BITS = 4;
   
  reg r_Clk = 1'b0;
   
  wire [c_NUM_BITS-1:0] w_LFSR_Data;
  wire w_LFSR_Done;
   
  lfsr #(.NUM_BITS(c_NUM_BITS)) LFSR_inst
         (.i_Clk(r_Clk),
          .i_Enable(1'b1),
          .i_Seed_DV(1'b0),
          .i_Seed_Data({c_NUM_BITS{1'b0}}), // Replication
          .o_LFSR_Data(w_LFSR_Data),
          .o_LFSR_Done(w_LFSR_Done)
          );
  
  always @(*)
    #10 r_Clk <= ~r_Clk; 
   
endmodule // LFSR_TB

仿真結(jié)果:

5位LFSR仿真示意圖

代碼提示

值得注意的是r_LFSR的定義,內(nèi)部位從1到NUM_BITS,而非0到NUM_BITS -1;

  reg [NUM_BITS:1] r_LFSR = 0;

這就意味著移位代碼這樣寫:

 r_LFSR <= {r_LFSR[NUM_BITS-1:1],r_XNOR}; //left right

也就是低位往高位移,也即左移。
這是根據(jù)這張圖來的:


5bit LFSR

至于仿真文件中對(duì)仿真輸入設(shè)計(jì)的也十分簡(jiǎn)單,就是單純讓種子為0,也即初始值為0,之后進(jìn)行反饋移位操作。

lfsr #(.NUM_BITS(c_NUM_BITS)) LFSR_inst
         (.i_Clk(r_Clk),
          .i_Enable(1'b1),
          .i_Seed_DV(1'b0),
          .i_Seed_Data({c_NUM_BITS{1'b0}}), // Replication
          .o_LFSR_Data(w_LFSR_Data),
          .o_LFSR_Done(w_LFSR_Done)
          );

在設(shè)計(jì)文件內(nèi)部,r_LFSR初始值就是為0,因此,不給種子也可以,反正i_Seed_DV本身在測(cè)試文件中就無效。

關(guān)于反饋多項(xiàng)式是如何確定的呢?
正是上面提供的文檔:
抽頭確定

最大長(zhǎng)度LFSR抽頭確定示意圖

此表列出了最大長(zhǎng)度為168位的LFSR計(jì)數(shù)器的相應(yīng)抽頭。前40位的基本描述和表最初在XCELL中發(fā)布,并在1993年和1994年Xilinx數(shù)據(jù)手冊(cè)的第9-24頁(yè)上重印。

  • n位LFSR計(jì)數(shù)器的最大序列長(zhǎng)度可以是2^n-1。在這種情況下,它會(huì)經(jīng)歷所有可能的代碼排列,除了一個(gè)鎖定狀態(tài)。
  • 最大長(zhǎng)度的n位LFSR計(jì)數(shù)器由一個(gè)n位移位寄存器組成,該移位寄存器在從最后輸出Qn到第一輸入D1的反饋路徑中具有XNOR。XNOR將鎖定狀態(tài)設(shè)為all-one狀態(tài),也就是說如果種子為全1,則LFSR將鎖定,其最終移位結(jié)果永遠(yuǎn)為1;XOR將鎖定狀態(tài)設(shè)為all-zeros狀態(tài)。
  • 對(duì)于普通的Xilinx應(yīng)用程序,全1的觸發(fā)器都更容易避免,因?yàn)椤澳J(rèn)情況下”觸發(fā)器在全零狀態(tài)下喚醒。
  • Table3描述了必須用作XNOR輸入的輸出。LFSR輸出通常標(biāo)記為1到n,1是移位寄存器的第一級(jí),n是最后一級(jí)。這與二進(jìn)制計(jì)數(shù)器的傳統(tǒng)0到(n-1)表示法不同。多輸入XNOR也稱為均勻奇偶校驗(yàn)電路。
  • 請(qǐng)注意,此表中描述的連接不一定唯一;某些其他連接也可能導(dǎo)致最大長(zhǎng)度序列。

參考資料

參考資料1
參考資料2

交個(gè)朋友

個(gè)人微信公眾號(hào): FPGA LAB
FPGA/IC技術(shù)交流2020

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容