Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21602 Discussions

LFSR as counter in VHDL

Altera_Forum
Honored Contributor II
2,010 Views

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?
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
1,228 Views

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.
0 Kudos
Reply