Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Verilog

Efficiënt LFSR-ontwerp in FPGA met behulp van VHDL en 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 het is een ontwerp dat nuttig is in FPGA's. LFSR's zijn eenvoudig te synthetiseren, wat betekent dat ze relatief weinig bronnen in beslag nemen en met zeer hoge kloksnelheden binnen een FPGA kunnen worden uitgevoerd. Er zijn veel toepassingen die baat hebben bij het gebruik van een LFSR, waaronder:

  • Tellers
  • Testpatroongeneratoren
  • Gegevens door elkaar gooien
  • Cryptografie

Het schuifregister met lineaire feedback is geïmplementeerd als een reeks flip-flops in een FPGA die als schuifregister met elkaar zijn verbonden. Verschillende tikken van de schuifregisterketen worden gebruikt als invoer voor een XOR of XNOR poort. De uitvoer van deze poort wordt vervolgens gebruikt als feedback naar het begin van de schuifregisterketen, vandaar de Feedback in LFSR.

5-bits LFSR met XNOR-poorten

Wanneer een LFSR actief is, is het patroon dat door de individuele flip-flops wordt gegenereerd pseudo-willekeurig, wat betekent dat het bijna willekeurig is. Het is niet volledig willekeurig, omdat je vanuit elke toestand van het LFSR-patroon de volgende toestand kunt voorspellen. Er zijn een paar eigenschappen van schuifregisters die belangrijk zijn om op te merken:

  • LFSR-patronen zijn pseudo-willekeurig.
  • Uitvoerpatronen zijn deterministisch. Je kunt de volgende status achterhalen door de positie van de XOR-poorten en het huidige patroon te kennen.
  • Een patroon van allemaal nullen kan niet verschijnen als de tikken XOR-poorten gebruiken. Omdat 0 XORed met 0 altijd 0 oplevert, stopt de LFSR met werken.
  • Een patroon van allemaal 1-en kan niet verschijnen als de tikken XNOR-poorten gebruiken. Omdat 1 XNORed met 1 altijd 1 oplevert, stopt de LFSR met werken.
  • Het maximaal mogelijke aantal iteraties van elke LFSR =2Bits-1

Bij langere LFSR's zal het langer duren om alle iteraties te doorlopen. Het langst mogelijke aantal iteraties voor een LFSR van N-bits is 2N-1. Als je erover nadenkt, zijn alle mogelijke patronen van iets dat N-bits lang is, 2N. Daarom is er slechts één patroon dat niet kan worden uitgedrukt met behulp van een LFSR. Dat patroon bestaat uit allemaal nullen als je XOR-poorten gebruikt, of allemaal enen als je XNOR-poorten als feedbackpoort gebruikt.

De VHDL- en Verilog-code creëren elke gewenste N-Bit brede LFSR. Het maakt gebruik van polynomen (wat de wiskunde achter de LFSR is) om de maximaal mogelijke LFSR-lengte voor elke bitbreedte te creëren. Daarom zijn er voor 3 bits 23-1=7 klokken nodig om alle mogelijke combinaties te doorlopen, voor 4 bits:24-1=15, voor 5 bits:25-1=31, enz. Ik heb dit gebaseerd op een XNOR-implementatie om de FPGA in staat te stellen op te starten in een toestand van nul op de LFSR. Hier is de volledige tabel met alle LFSR-patronen gepubliceerd door Xilinx.

VHDL-implementatie:

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 

Testbench (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;

Verilog-implementatie:

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 

Testbench (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

  1. Modellering van schakelniveau
  2. Verilog `ifdef voorwaardelijke compilatie'
  3. Verilog-module-instanties
  4. Verilog-functies
  5. Verilog Scheduling Semantiek
  6. D Vergrendeling
  7. Verilog altijd blokkeren
  8. Verilog-parameters
  9. Verilog blok genereren
  10. Verilog T-teenslipper
  11. Verilog Mod-N-teller