Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

LFSR as counter in VHDL

I am running a bit low on gates in a VHDL design, and I am replacing a counter implemented by addition with a counter implemented as an LFSR. The main crystal is 3.6864 MHz and the counter needs to have a period of roughly 0.5 seconds, so I figured that a 20-bit LFSR giving a maximum period of 1048575 (taps 3 and 17) would be close enough.

However, I am pretty new to LFSRs, and I keep getting conflicting explanations about how they work... is bit 20 or bit 1 always considered a tap? Do I use XOR or XNOR? Which direction do I shift? Ordinarily I'd write some C code to test it quickly but I am at work and software is restricted (can't SSH to my server at home either).

I am using the following VHDL code right now, but it never reaches the given combination (so whatever I am doing, it is clearly not a max-length LFSR). Other attempts have given things like a period 1/10 what it should be.

(hb_lfsr is a 20-bit vector; hb_init is a 20-bit constant vector, with all 0s except bit 1 which is 1)

heartbeat_process: process (clk, reset_n, hb_lfsr, heartbeat)

begin

if (reset_n = '0') then

hb_lfsr <= hb_init;

heartbeat <= '0';

elsif (rising_edge(clk)) then

hb_lfsr <= hb_lfsr(19 downto 1) & (hb_lfsr(3) xor hb_lfsr(17));

if(hb_lfsr = hb_init) then

heartbeat <= not(heartbeat);

end if;

end if;

end process;

Can anyone shed some light on this?

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This page does a pretty good job describing the difference between whether or not tap 1 or 20 would be considered a tap:

    http://www.walterg.uklinux.net/prbs.htm

    I recommend the "Galois-Field Arithmetic" implementation since it yields faster hardware (fewer XOR terms in front of the shift register).

    I think the issue with your implementation is the way you are trying to feed the taps back into the shift register. I just finished coding up an LFSR to generate pseudo random values and here is the structure that I'm using .... assuming you know verilog:

    
    // LSFR input data for all the pipeline stages
    genvar d;
    generate
      for (d = 0; d < (DATA_WIDTH-1); d = d + 1)  // highest order pipeline input will be generated independent of this loop 
      begin: pipeline_taps
        assign pipeline_input = pipeline ^ (pipeline & polynomial);
      end
    endgenerate
      assign pipeline_input = pipeline;
    
    I take the pipeline_input bus and use it as the input to the pipeline register. So I use the polynomial bus (without including the +1 of the polynomial) and bitwise AND each bit with the output stage of the shift register. I then take that resulting bus and bitwise XOR it with the values of the shift register.

    I think you could do this in VHDL by taking the pipeline output stage and replicating it 20 times and then performing the bus wide AND and XOR operations.