Conception LFSR efficace dans FPGA utilisant VHDL et Verilog
LFSR dans un FPGA – VHDL &Verilog Code
Comment fonctionne un registre à décalage à rétroaction linéaire à l'intérieur d'un FPGA
LFSR signifie Linear Feedback Shift Register et c'est une conception utile à l'intérieur des FPGA. Les LFSR sont simples à synthétiser, ce qui signifie qu'ils nécessitent relativement peu de ressources et peuvent être exécutés à des fréquences d'horloge très élevées au sein d'un FPGA. De nombreuses applications bénéficient de l'utilisation d'un LFSR, notamment :
- Compteurs
- Générateurs de modèles de test
- Brouillage des données
- Cryptographie
Le registre à décalage à rétroaction linéaire est implémenté sous la forme d'une série de bascules à l'intérieur d'un FPGA qui sont câblées ensemble comme un registre à décalage. Plusieurs dérivations de la chaîne du registre à décalage sont utilisées comme entrées soit pour un XOR ou XNOR porte. La sortie de cette porte est ensuite utilisée comme feedback au début de la chaîne du registre à décalage, d'où le feedback dans LFSR.
LFSR 5 bits utilisant des portes XNOR
Lorsqu'un LFSR est en cours d'exécution, le modèle généré par les bascules individuelles est pseudo-aléatoire, ce qui signifie qu'il est presque aléatoire. Ce n'est pas complètement aléatoire car à partir de n'importe quel état du modèle LFSR, vous pouvez prédire l'état suivant. Il est important de noter quelques propriétés des registres à décalage :
- Les modèles LFSR sont pseudo-aléatoires.
- Les modèles de sortie sont déterministes. Vous pouvez déterminer l'état suivant en connaissant la position des portes XOR ainsi que le modèle actuel.
- Un modèle composé uniquement de 0 ne peut pas apparaître lorsque les taps utilisent des portes XOR. Puisque 0 XORed avec 0 produira toujours 0, le LFSR cessera de fonctionner.
- Un motif composé uniquement de 1 ne peut pas apparaître lorsque les taps utilisent des portes XNOR. Puisque 1 XNORed avec 1 produira toujours 1, le LFSR cessera de fonctionner.
- Le nombre maximum possible d'itérations d'un LFSR =2Bits-1
Les LFSR plus longs prendront plus de temps à parcourir toutes les itérations. Le nombre d’itérations le plus long possible pour un LFSR de N bits est 2N-1. Si vous y réfléchissez, tous les modèles possibles de quelque chose de N bits sont 2N. Il n’existe donc qu’un seul modèle qui ne peut pas être exprimé à l’aide d’un LFSR. Ce modèle est composé uniquement de 0 lorsque vous utilisez des portes XOR, ou uniquement de 1 lorsque vous utilisez des portes XNOR comme porte de rétroaction.
Le code VHDL et Verilog crée n'importe quel LFSR de N bits que vous désirez. Il utilise des polynômes (qui sont les calculs derrière le LFSR) pour créer la longueur LFSR maximale possible pour chaque largeur de bit. Par conséquent, pour 3 bits, il faut 23-1=7 horloges pour parcourir toutes les combinaisons possibles, pour 4 bits :24-1=15, pour 5 bits :25-1=31, etc. J'ai basé cela sur une implémentation XNOR pour permettre au FPGA de démarrer dans un état tout zéro sur le LFSR. Voici le tableau complet de tous les modèles LFSR publiés par Xilinx.
Implémentation VHDL :
LFSR.vhd
------------------------------------------------------------------------------- -- File downloaded from http://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
Banc de test (LFSR_TB.vhd)
------------------------------------------------------------------------------- -- File downloaded from http://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;
Implémentation de Verilog :
LFSR.v
/////////////////////////////////////////////////////////////////////////////// // File downloaded from http://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
Banc de test (LFSR_TB.v)
/////////////////////////////////////////////////////////////////////////////// // File downloaded from http://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