Efficiënt LFSR-ontwerp in FPGA met VHDL & Verilog
LFSR in een FPGA – VHDL & Verilog Code
Hoe een Linear Feedback Shift Register werkt binnen een FPGA
LFSR staat voor Linear Feedback Shift Register en is een ontwerp dat nuttig is binnen FPGA's. LFSR's zijn eenvoudig te synthetiseren, wat betekent dat ze relatief weinig resources verbruiken en bij zeer hoge kloksnelheden kunnen draaien binnen een FPGA. Er zijn veel toepassingen die profiteren van het gebruik van een LFSR, waaronder:
- Tellers
- Testpatroongeneratoren
- Data Scrambling
- Cryptografie
De linear feedback shift register wordt geïmplementeerd als een serie Flip-Flops binnen een FPGA die samen bedraad zijn als een schuifregister. Verschillende taps afkomstig van de schuifregisterketen worden gebruikt als ingangen voor een XOR of XNOR poort. De uitgang van deze poort wordt vervolgens als feedback gebruikt naar het begin van de schuifregisterketen, vandaar de Feedback in LFSR.
5-Bit LFSR met XNOR poorten
Wanneer een LFSR draait, is het gegenereerde patroon door de individuele Flip-Flops pseudo-random, wat betekent dat het dicht bij random is. Het is niet volledig random omdat u vanaf elke toestand van het LFSR-patroon de volgende toestand kunt voorspellen. Er zijn een paar belangrijke eigenschappen van schuifregisters om te onthouden:
- LFSR-patronen zijn pseudo-random.
- Uitgangspatronen zijn deterministisch. U kunt de volgende toestand bepalen door de positie van de XOR-poorten en het huidige patroon te kennen.
- Een patroon van alle 0's kan niet voorkomen wanneer de taps XOR-poorten gebruiken. Omdat 0 XOR 0 altijd 0 oplevert, stopt de LFSR met draaien.
- Een patroon van alle 1's kan niet voorkomen wanneer de taps XNOR-poorten gebruiken. Omdat 1 XNOR 1 altijd 1 oplevert, stopt de LFSR met draaien.
- Het maximaal mogelijke aantal iteraties van een LFSR = 2Bits-1
Langere LFSR's nemen meer tijd om door alle iteraties te lopen. Het langst mogelijke aantal iteraties voor een LFSR van N-bits is 2N-1. Als u erover nadenkt, zijn alle mogelijke patronen van iets dat N-bits lang is 2N. Er is dus slechts één patroon dat niet uitgedrukt kan worden met een LFSR. Dat patroon is alle 0's bij gebruik van XOR-poorten, of alle 1's bij gebruik van XNOR-poorten als uw feedback-poort.
De VHDL- en Verilog-code creëert een LFSR van elke gewenste N-bit breedte. Het gebruikt polynomen (de wiskunde achter de LFSR) om de maximaal mogelijke LFSR-lengte voor elke bitbreedte te creëren. Daarvoor duurt het voor 3 bits 23-1=7 klokken om door alle combinaties te lopen, voor 4 bits: 24-1=15, voor 5 bits: 25-1=31, enz. Ik baseerde dit op een XNOR-implementatie om de FPGA op te laten starten in een all-zero toestand op de LFSR. Hier is de volledige tabel van alle LFSR-patronen gepubliceerd door Xilinx.
VHDL Implementatie:
LFSR.vhd
-------------------------------------------------------------------------------
-- File downloaded from https://www.nandland.com
-------------------------------------------------------------------------------
-- Description:
-- A LFSR or Linear Feedback Shift Register is a quick and easy
-- way to generate pseudo-random data inside of an FPGA. The LFSR can be used
-- for things like counters, test patterns, scrambling of data, and others.
-- This module creates an LFSR whose width gets set by a generic. The
-- o_LFSR_Done will pulse once all combinations of the LFSR are complete. The
-- number of clock cycles that it takes o_LFSR_Done to pulse is equal to
-- 2^g_Num_Bits-1. For example, setting g_Num_Bits to 5 means that o_LFSR_Done
-- will pulse every 2^5-1 = 31 clock cycles. o_LFSR_Data will change on each
-- clock cycle that the module is enabled, which can be used if desired.
--
-- Generics:
-- g_Num_Bits - Set to the integer number of bits wide to create your LFSR.
-------------------------------------------------------------------------------
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;
-- Optional Seed Value
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
-- Purpose: Load up LFSR with Seed if Data Valid (DV) pulse is detected.
-- Othewise just run LFSR when enabled.
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
Testbench (LFSR_TB.vhd)
-------------------------------------------------------------------------------
-- File downloaded from https://www.nandland.com
-------------------------------------------------------------------------------
-- Description: Simple Testbench for LFSR.vhd. Set c_NUM_BITS to different
-- values to verify operation of LFSR
-------------------------------------------------------------------------------
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 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 Implementatie:
LFSR.v
///////////////////////////////////////////////////////////////////////////////
// File downloaded from https://www.nandland.com
///////////////////////////////////////////////////////////////////////////////
// Description:
// A LFSR or Linear Feedback Shift Register is a quick and easy way to generate
// pseudo-random data inside of an FPGA. The LFSR can be used for things like
// counters, test patterns, scrambling of data, and others. This module
// creates an LFSR whose width gets set by a parameter. The o_LFSR_Done will
// pulse once all combinations of the LFSR are complete. The number of clock
// cycles that it takes o_LFSR_Done to pulse is equal to 2^g_Num_Bits-1. For
// example setting g_Num_Bits to 5 means that o_LFSR_Done will pulse every
// 2^5-1 = 31 clock cycles. o_LFSR_Data will change on each clock cycle that
// the module is enabled, which can be used if desired.
//
// Parameters:
// NUM_BITS - Set to the integer number of bits wide to create your LFSR.
///////////////////////////////////////////////////////////////////////////////
module LFSR #(parameter NUM_BITS) (
input i_Clk,
input i_Enable,
// Optional Seed Value
input i_Seed_DV,
input [NUM_BITS-1:0] i_Seed_Data,
output [NUM_BITS-1:0] o_LFSR_Data,
output o_LFSR_Done
);
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
Testbench (LFSR_TB.v)
///////////////////////////////////////////////////////////////////////////////
// File downloaded from https://www.nandland.com
///////////////////////////////////////////////////////////////////////////////
// Description: Simple Testbench for LFSR.v. Set c_NUM_BITS to different
// values to verify operation of LFSR
///////////////////////////////////////////////////////////////////////////////
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(}), // Replication
.o_LFSR_Data(w_LFSR_Data),
.o_LFSR_Done(w_LFSR_Done)
);
always @(*) #10 r_Clk
Verilog
- Efficiënt LFSR-ontwerp in FPGA met VHDL & Verilog
- Verilog File I/O onder de knie: Openen, Lezen, Schrijven en Sluiten
- Verilog-toewijzingen begrijpen: types, syntax en best practices
- Verilog Gray-code Teller Module – 4-bit Gray Code Generator
- Uitgebreide ASIC Ontwerpstroom: Van Vereisten tot Productie
- D Flip-Flop met Asynchrone Actieve-Lage Reset: Ontwerp en Testbench
- Verilog Basics: Uw Eerste AND-poort Ontwerpen
- Verilog module basis: Structuur & syntaxis
- Verilog Simulatie Technieken voor betrouwbare RTL-verificatie
- Verilog \`ifdef: Conditionele compilatie uitgelegd
- Beginner's Guide to Verilog: Hello World Voorbeeld