寫在前面
相關(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}};
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的一種形式:
運(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é)果:

代碼提示
值得注意的是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ù)這張圖來的:
至于仿真文件中對(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)度為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)度序列。
參考資料
交個(gè)朋友
個(gè)人微信公眾號(hào): FPGA LAB
FPGA/IC技術(shù)交流2020