Forum Discussion
Altera_Forum
Honored Contributor
16 years agoLFSR 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
Honored 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:
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.// 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;