FPGA 中高效 LFSR 设计:VHDL 与 Verilog 完整实现
FPGA 中的线性反馈移位寄存器(LFSR)—— VHDL 与 Verilog 代码
LFSR 工作原理
LFSR(Linear Feedback Shift Register)在 FPGA 内部由一系列触发器串联成移位寄存器,从链路中抽取若干抽头接入 XOR 或 XNOR 门,门输出作为反馈接回链路起始端。这种结构资源占用少、可运行极高时钟频率,广泛用于:
- 计数器
- 测试模式发生器
- 数据扰码
- 密码学
LFSR 产生的序列为伪随机:接近随机但可预测(已知当前状态与抽头位置即可推导下一状态)。关键性质:
- 使用 XOR 反馈时,全 0 状态不会出现(0⊕0=0 导致锁死)。
- 使用 XNOR 反馈时,全 1 状态不会出现(1⊙1=1 导致锁死)。
- N 位 LFSR 最大周期为 2N−1,仅缺少全 0 或全 1 这一种模式。
VHDL 实现(参数化 N 位)
代码基于 XNOR 反馈,支持上电全 0 启动,使用 Xilinx 发布的最大周期多项式表。通过泛型 g_Num_Bits 设置位宽,o_LFSR_Done 在跑完 2N−1 个周期后拉高一个时钟。
LFSR.vhd(核心模块)
-------------------------------------------------------------------------------
-- File downloaded from https://www.nandland.com
-------------------------------------------------------------------------------
library ieee; use ieee.std_logic_1164.all;
entity LFSR is
generic ( g_Num_Bits : integer := 5 );
port (
i_Clk : in std_logic;
i_Enable : in std_logic;
-- 可选种子值
i_Seed_DV : in std_logic;
i_Seed_Data : in std_logic_vector(g_Num_Bits-1 downto 0);
o_LFSR_Data : out std_logic_vector(g_Num_Bits-1 downto 0);
o_LFSR_Done : out std_logic
);
end entity LFSR;
architecture RTL of LFSR is
signal r_LFSR : std_logic_vector(g_Num_Bits downto 1) := (others => '0');
signal w_XNOR : std_logic;
begin
p_LFSR : process (i_Clk) is
begin
if rising_edge(i_Clk) then
if i_Enable = '1' then
if i_Seed_DV = '1' then
r_LFSR <= i_Seed_Data(g_Num_Bits downto 1);
else
r_LFSR <= r_LFSR(g_Num_Bits-1 downto 1) & w_XNOR;
end if;
end if;
end if;
end process;
-- XNOR 反馈多项式(此处以 5 位为例,实际应根据 g_Num_Bits 查表)
w_XNOR <= r_LFSR(5) xnor r_LFSR(3); -- 示例:5 位 LFSR 抽头 [5,3]
o_LFSR_Data <= r_LFSR(g_Num_Bits downto 1);
o_LFSR_Done <= '1' when r_LFSR = (r_LFSR'range => '1') else '0'; -- 全 1 标志周期结束
end RTL;
LFSR_TB.vhd(测试平台)
library ieee; use ieee.std_logic_1164.all;
entity LFSR_TB is end entity LFSR_TB;
architecture behave of LFSR_TB is
constant c_NUM_BITS : integer := 5;
constant c_CLK_PERIOD: time := 40 ns; -- 25 MHz
signal r_Clk : std_logic := '0';
signal w_LFSR_Data : std_logic_vector(c_NUM_BITS-1 downto 0);
signal w_LFSR_Done : std_logic;
begin
-- 时钟产生
r_Clk <= not r_Clk after c_CLK_PERIOD/2;
-- 例化被测模块
DUT : entity work.LFSR
generic map (g_Num_Bits => c_NUM_BITS)
port map (
i_Clk => r_Clk,
i_Enable => '1',
i_Seed_DV => '0',
i_Seed_Data => (others => '0'),
o_LFSR_Data => w_LFSR_Data,
o_LFSR_Done => w_LFSR_Done
);
end architecture behave;
Verilog 实现(参数化 N 位)
LFSR.v(核心模块)
///////////////////////////////////////////////////////////////////////////////
// File downloaded from https://www.nandland.com
///////////////////////////////////////////////////////////////////////////////
module LFSR #(
parameter NUM_BITS = 5
)(
input wire i_Clk,
input wire i_Enable,
// 可选种子值
input wire i_Seed_DV,
input wire [NUM_BITS-1:0] i_Seed_Data,
output reg [NUM_BITS-1:0] o_LFSR_Data,
output reg o_LFSR_Done
);
reg [NUM_BITS:1] r_LFSR = 0;
reg r_XNOR;
always @(posedge i_Clk) begin
if (i_Enable == 1'b1) begin
if (i_Seed_DV == 1'b1)
r_LFSR <= i_Seed_Data[NUM_BITS:1];
else
r_LFSR <= {r_LFSR[NUM_BITS-1:1], r_XNOR};
end
end
// XNOR 反馈多项式(示例:5 位抽头 [5,3])
always @* r_XNOR = ~(r_LFSR[5] ^ r_LFSR[3]); // XNOR
assign o_LFSR_Data = r_LFSR[NUM_BITS:1];
assign o_LFSR_Done = (r_LFSR == {NUM_BITS{1'b1}}); // 全 1 表示周期结束
endmodule
LFSR_TB.v(测试平台)
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}}),
.o_LFSR_Data(w_LFSR_Data), .o_LFSR_Done(w_LFSR_Done)
);
always #10 r_Clk = ~r_Clk; // 50 MHz 时钟
endmodule
提示: 实际工程中,反馈多项式应根据位宽查表(Xilinx 应用笔记 XAPP052 或 Nandland 网站提供完整表),上述代码中的抽头仅为 5 位示例。参数化设计让同一模块可复用于不同位宽需求。
Verilog
- Verilog 数组与存储器:掌握多维数据结构
- Verilog T 触发器设计:RTL 实现与测试平台
- 掌握Verilog参数:构建可复用可扩展模块
- Verilog 优先编码器:可靠的 4 输入 8 位选择器
- Verilog 高级开关级建模:晶体管级仿真指南
- Verilog 入门指南:Hello World 示例
- 掌握 Verilog 文件 I/O:打开、读取、写入和关闭
- Verilog 运算符:综合必备的算术与控制运算符
- 深入理解 Verilog 赋值语句:类型、语法与最佳实践
- 掌握 Verilog 层次引用作用域:避免模块与块中的名称冲突
- Verilog 全加器设计与实现指南
- 使用 Verilog assign 语句设计组合逻辑