前言
将笔者之前在学习FPGA上遇到的一些有意义的内容整理成文,分享给大家,共同探讨,共同进步。
1、什么是LFSR?
1.1、定义
线性反馈移位寄存器(linear feedback shift register, LFSR)是指,给定前一状态的输出,将该输出的线性函数再用作输入的移位寄存器。异或运算是最常见的单比特线性函数:对寄存器的某些位进行异或操作后作为输入,再对寄存器中的各比特进行整体移位(百度百科定义)。
LFSR用于产生可重复的伪随机序列,该电路有n级触发器和一些异或门组成,如下图所示。
其中,gn为反馈系数,取值只能为0或1,取为0时表明不存在该反馈之路,取为1时表明存在该反馈之路;这里的反馈系数决定了产生随机数的算法的不同。
LFSR的初始值被称为伪随机序列的种子,影响下一个状态的比特位叫做抽头。
1.2、举例
下图的抽头为 3,2,则其反馈多项式为 .
以下需要注意:
1.抽头的数量必须为偶数;
2.抽头之间不能成对出现必须是互质的;
若设定初始种子为100,则下一个状态为:D0=D2=1,D1=D0=0;D2=D1^D2=1,则该状态为101,以此类推,有:100--101--111--011--110--001--010,状态个数为 ,(不能包含全零状态,全零将导致永远出不来),D触发器的个数越多,产生的状态就越多,也就越随机。
1.3、代码验证
1.2的举例代码如下:
module RanGen(
input rst_n,
input clk,
input load,
input [2:0] seed,
output reg [2:0] rand_num
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
rand_num <=3'b0;
else if(load) //使能
rand_num <=seed; //装载初始种子
else
begin
rand_num[0] <= rand_num[2];
rand_num[1] <= rand_num[0];
rand_num[2] <= rand_num[1]^rand_num[2];//抽头为2,则在此处进行异或操作
end
end
endmodule
以下为测试代码:
`timescale 1 ns/ 1 ns
module RanGen_tb();
reg clk;
reg load;
reg rst_n;
reg [2:0] seed;
wire [2:0] rand_num;
RanGen i1 (
.clk(clk),
.load(load),
.rand_num(rand_num),
.rst_n(rst_n),
.seed(seed)
);
initial
begin
rst_n=1'b0;
clk=1'b0;
load=1'b0;
seed=3'b0;
#20 rst_n=1'b1;
#20 //开始使能,并装载初始种子
load=1'b1;
seed=3'b100;
#20
load=1'b0;//关闭使能
end
always #10 clk=~clk;
endmodule
仿真结果如下图:
符合1.2理论上的循环序列。
1.4、其他
下表为不同的bits下,抽头的设定(对应不同的本原多项式)和最大的输出状态个数关系表。
以下为赛灵思公司关于LSFR的技术文档。
www.xilinx.com/support/documentation/application_notes/xapp052.pdf
2、版本信息
文件:V1.0
编号:2
Vivado:无
Modelsim:Modelsim SE-64 10.4
Quartus II:无