Diseño LFSR eficiente en FPGA usando VHDL y Verilog
LFSR en una FPGA – VHDL y código Verilog
Cómo funciona un registro de desplazamiento de retroalimentación lineal dentro de una FPGA
LFSR significa Registro de desplazamiento de retroalimentación lineal y es un diseño que es útil dentro de los FPGA. Los LFSR son fáciles de sintetizar, lo que significa que requieren relativamente pocos recursos y pueden ejecutarse a velocidades de reloj muy altas dentro de una FPGA. Hay muchas aplicaciones que se benefician del uso de un LFSR, entre ellas:
- Contadores
- Generadores de patrones de prueba
- Codificación de datos
- Criptografía
El registro de desplazamiento de retroalimentación lineal se implementa como una serie de Flip-Flops dentro de una FPGA que están conectados entre sí como un registro de desplazamiento. Se utilizan varias derivaciones de la cadena del registro de desplazamiento como entradas para un XOR o XNOR puerta. La salida de esta puerta se utiliza luego como retroalimentación al comienzo de la cadena del registro de desplazamiento, de ahí la retroalimentación en LFSR.
LFSR de 5 bits usando puertas XNOR
Cuando se ejecuta un LFSR, el patrón que generan los Flip-Flops individuales es pseudoaleatorio, lo que significa que es casi aleatorio. No es completamente aleatorio porque desde cualquier estado del patrón LFSR, puedes predecir el siguiente estado. Hay algunas propiedades de los registros de desplazamiento que es importante tener en cuenta:
- Los patrones LFSR son pseudoaleatorios.
- Los patrones de producción son deterministas. Puede determinar el siguiente estado conociendo la posición de las puertas XOR así como el patrón actual.
- No puede aparecer un patrón de todos 0 cuando los grifos usan puertas XOR. Dado que 0 XORed con 0 siempre producirá 0, el LFSR dejará de ejecutarse.
- No puede aparecer un patrón de todos 1 cuando los grifos usan puertas XNOR. Dado que 1 XNORed con 1 siempre producirá 1, el LFSR dejará de ejecutarse.
- El número máximo posible de iteraciones de cualquier LFSR =2Bits-1
Los LFSR más largos tardarán más en ejecutarse en todas las iteraciones. El mayor número posible de iteraciones para un LFSR de N bits es 2N-1. Si lo piensas bien, todos los patrones posibles de algo que tiene N bits de largo son 2N. Por lo tanto, sólo hay un patrón que no se puede expresar utilizando un LFSR. Ese patrón es todo 0 cuando se usan puertas XOR, o todo 1 cuando se usan puertas XNOR como puerta de retroalimentación.
El código VHDL y Verilog crea cualquier LFSR de N-Bit que desee. Utiliza polinomios (que son las matemáticas detrás del LFSR) para crear la longitud máxima posible de LFSR para cada ancho de bit. Por lo tanto, para 3 bits, se necesitan 23-1=7 relojes para ejecutar todas las combinaciones posibles, para 4 bits:24-1=15, para 5 bits:25-1=31, etc. Basé esto en una implementación XNOR para permitir que la FPGA se inicie en un estado todo cero en el LFSR. Aquí está la tabla completa de todos los patrones LFSR publicados por Xilinx.
Implementación de 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
Banco de pruebas (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;
Implementación 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
Banco de pruebas (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
- Operaciones de E/S de archivos de Verilog
- Verilog para bucle
- Ámbito de referencia jerárquica de Verilog
- Verilog generar bloque
- Lógica combinacional con asignación
- RAM de puerto único Verilog
- Declaración del caso Verilog
- Verilog siempre bloquea
- Parámetros de Verilog
- Bloque inicial de Verilog
- Capas de abstracción de diseño