0
0
VerilogHow-ToBeginner · 4 min read

Verilog Code for LFSR: Syntax, Example, and Common Pitfalls

A Linear Feedback Shift Register (LFSR) in Verilog is implemented using a shift register and XOR feedback taps. You define the register, specify the feedback polynomial taps, and update the register on each clock cycle to generate pseudo-random sequences.
📐

Syntax

An LFSR in Verilog typically uses a reg to hold the shift register bits, a clock input to update the register, and XOR operations to calculate the feedback bit. The feedback taps are chosen based on the polynomial to ensure maximal length sequences.

Key parts:

  • reg [N-1:0] lfsr; - holds the current state of the LFSR.
  • always @(posedge clk or posedge reset) - updates the LFSR on clock or resets it.
  • feedback = lfsr[tap1] ^ lfsr[tap2] ^ ... - XOR of selected bits for feedback.
verilog
module lfsr(
    input wire clk,
    input wire reset,
    output reg [3:0] lfsr
);
    wire feedback;

    assign feedback = lfsr[3] ^ lfsr[2]; // taps for 4-bit LFSR

    always @(posedge clk or posedge reset) begin
        if (reset)
            lfsr <= 4'b0001; // non-zero seed
        else
            lfsr <= {lfsr[2:0], feedback};
    end
endmodule
💻

Example

This example shows a 4-bit LFSR with taps at bits 4 and 3 (index 3 and 2). It shifts bits on each clock and outputs a pseudo-random sequence. The reset initializes the register to a non-zero value.

verilog
module testbench;
    reg clk = 0;
    reg reset = 1;
    wire [3:0] lfsr_out;

    lfsr uut(
        .clk(clk),
        .reset(reset),
        .lfsr(lfsr_out)
    );

    always #5 clk = ~clk; // 10 time units clock period

    initial begin
        $monitor("Time=%0t LFSR=%b", $time, lfsr_out);
        #10 reset = 0;
        #100 $finish;
    end
endmodule

module lfsr(
    input wire clk,
    input wire reset,
    output reg [3:0] lfsr
);
    wire feedback;

    assign feedback = lfsr[3] ^ lfsr[2];

    always @(posedge clk or posedge reset) begin
        if (reset)
            lfsr <= 4'b0001;
        else
            lfsr <= {lfsr[2:0], feedback};
    end
endmodule
Output
Time=0 LFSR=0001 Time=10 LFSR=0011 Time=20 LFSR=0110 Time=30 LFSR=1100 Time=40 LFSR=1001 Time=50 LFSR=0010 Time=60 LFSR=0101 Time=70 LFSR=1011 Time=80 LFSR=0111 Time=90 LFSR=1110 Time=100 LFSR=1101
⚠️

Common Pitfalls

Common mistakes when coding an LFSR in Verilog include:

  • Using an all-zero seed, which causes the LFSR to lock at zero and never change.
  • Incorrect feedback taps that do not produce maximal length sequences.
  • Forgetting to reset the LFSR to a non-zero value.
  • Mixing bit indices incorrectly when selecting taps.
verilog
/* Wrong: all zero seed causes no output change */
reg [3:0] lfsr = 4'b0000; // bad seed

/* Right: non-zero seed */
reg [3:0] lfsr = 4'b0001; // good seed
📊

Quick Reference

Tips for writing LFSRs in Verilog:

  • Always initialize the LFSR with a non-zero seed.
  • Choose taps based on known maximal polynomials for your LFSR size.
  • Use XOR of taps for feedback calculation.
  • Update the register on the clock's rising edge.
  • Test your LFSR output to verify the sequence length.

Key Takeaways

An LFSR uses XOR feedback taps and a shift register to generate pseudo-random sequences.
Always initialize the LFSR with a non-zero seed to avoid locking at zero.
Select feedback taps carefully to ensure maximal length sequences.
Update the LFSR state on the clock's rising edge with proper reset handling.
Test your LFSR output to confirm correct sequence generation.