目录
线性反馈移位寄存器(Linear Feedback Shift Register, LFSR)是一种广泛应用于密码学、通信系统和计算机科学中的重要工具。在很多领域上都有使用到LFSR,譬如说密码学、白噪声,还有我们这里的随机功能实现,之所以把它使用到我们的radio的随机功能里面,除了它可以产生伪随机数序列实现随机播放功能之外,更重要的是我们利用了它的两个特点。其一,只需要在代码中开辟几个byte的位置,就能够实现随机序列的产生,需要的空间很少。其二,是它的记忆功能,我们在随机的功能里面,选择了下一曲,则上一曲可以通过调整抽头数的序列来从新获得,而不需要开辟空间进行存储。
1.LFSR的基本概念
线性反馈移位寄存器是一种特殊的移位寄存器,它通过将寄存器中的值进行线性反馈操作来更新状态。LFSR的状态更新由一个多项式确定,该多项式称为反馈多项式。有两种LFSR的实现方式,伽罗瓦(Galois)和斐波那契(Fibonacci)两种形式,也有人称为外部(External)执行方式和内部(Internal)执行方式。所以这两种方式也是有着本质的区别的。
伽罗瓦方式(Internal)
从图中我们可以看到Galois方式的一些特征,其中包括数据的方向从左至右而反馈线路则是由右至左的。其中X^0项(本原多项式里面的”1”这一项),作为起始项。按照本原多项式所指示的,确定异或门(XOR)在移位寄存器电路上的位置。如上图中的X^4.因此Galois方式也有人称它为线内或模类型(M-型)LFSR.
斐波那契方式(External)
从图中我们可以看到Fibonacci方式的数学流向和反馈形式是恰好跟Galois方式相反的,按照本原多项式,其中的X^0这一项则作为最后一项,这里只需要一个XOR门,将本原多项式中所给出的taps来设定它的异或方式。因此Fibonacci方式也被叫做线外或者简型(S-型)LFSR.
2.LFSR的特性
最大周期
LFSR的周期是指重复出现相同的序列所需的移位次数。对于一个n-级LFSR,如果它的反馈多项式是本原多项式,则LFSR的周期可以达到最大值2^n−1。这样的LFSR被称为最大周期LFSR。
本原多项式
一个多项式f(x)被称为本原多项式,如果它满足以下条件:
序列的统计特性
LFSR生成的序列具有良好的统计特性,如均匀分布、长周期性等,这些特性使其适用于生成伪随机数序列。
3.LFSR的应用
LFSR的应用包括如下几个方面:
密码学:LFSR在密码学中有多种应用,包括密钥生成、流加密等。
通信系统:LFSR在通信系统中用于错误检测和纠正,如循环冗余校验(CRC)。
计算机科学:LFSR在计算机科学中有多种应用,如测试模式生成、随机数生成等。
以通信系统中的伪随机序列为例,介绍下如何通过LFSR实现m序列:
M序列的意思就是最大序列,专业点来说就是周期,就是这些不同的伪随机数在什么时候才会回到初始的输入状态,M序列的最大值为2^n-1,因为全0的初始状态不起作用,所以不能以全0的状态作为初始输入。M序列就是我们在随机功能中获得的那个随机播放的序列。它有些很好的特性:
1).通过反馈抽头数获得与之前输出的值的输入值,这也是我们所说的记忆功能。
2).这些给定的反馈抽头数永远都是偶数的,而且只包括最高位,不包括最低位。
4.matlab/FPGA仿真测试
在MATLAB中编写一个M序列(最大长度线性反馈移位寄存器序列)产生的模块相对简单。M序列是由最大周期的线性反馈移位寄存器产生的伪随机序列,其周期等于2^n-1,其中n是寄存器的级数。为了生成M序列,我们需要知道寄存器的级数以及对应的本原多项式。
function m_sequence = generateMSequence(n, taps)
% 生成一个n级的M序列
% 参数:
% n - LFSR的级数
% taps - 参与反馈的位位置组成的向量,包括最高位(例如 [3 2] 表示 x^3 + x^2 + 1)
%
% 返回:
% m_sequence - 生成的M序列
% 初始化LFSR状态
state = ones(1, n); % 初始状态设为全1
m_sequence = [];
% 计算M序列的周期
period = 2^n - 1;
% 生成序列
for i = 1:period
m_sequence = [m_sequence state(1)]; % 添加当前状态的最高位到序列
feedback = mod(sum(state(taps)), 2); % 计算反馈位
state = [feedback state(1:n-1)]; % 更新状态
end
end
Verilog程序如下:
module m_sequence_generator (
input wire clk,
input wire reset,
output reg [3:0] sequence
);
// 定义寄存器的大小
localparam N = 4; // 寄存器的位数
// 定义反馈连接点
localparam FEEDBACK_TAPS = 4'b1100; // 对应于x^4 + x^3 + 1
// 定义状态寄存器
reg [N-1:0] lfsr;
always @(posedge clk or posedge reset) begin
if (reset) begin
lfsr <= (1 << (N-1)); // 初始状态设为全1
end else begin
// 计算反馈位
reg feedback;
feedback = (lfsr[N-1] & FEEDBACK_TAPS[N-1]) ^
(lfsr[N-2] & FEEDBACK_TAPS[N-2]) ^
(lfsr[N-3] & FEEDBACK_TAPS[N-3]) ^
(lfsr[N-4] & FEEDBACK_TAPS[N-4]);
// 移位操作
lfsr <= {feedback, lfsr[N-2:N-1], lfsr[N-3:0]};
end
end
// 输出M序列
assign sequence = lfsr;
endmodule
本文转载自博主公众号文章: