LFSR Divider

From Hamsterworks Wiki!

Jump to: navigation, search

This FPGA Project was completed in November 2014.

A LFSR can be used to divide a clock without using any counters, just registers and XORs.

Here I am dividing the Papilio One's 32MHz clock to a single pulse per second for use in a Digital Clock. You usually wouldn't use a LFSR this big unless you wanted to generate a pseudo-random bit stream, but it makes a most excellent way to give somebody a chance to think about what is going on, and what is so special about the magic constant "0111110111010111001000000".

C Source for testing method

/************************************
* Testing a 32,000,000 state LFSR
* counter before implementing in VHDL
************************************/
#include <stdio.h>

int main(int ch, char *v[])
{
  unsigned reg = 0x1FFFFFF;
  unsigned i = 0;

  while(1) {
    if(reg == 0x1FFFFFF) {
       reg = 0xfbae40;
       printf("i = %i\r\n",i);
    } else {
       unsigned new = (reg & 1) ^ ((reg >> 3)&1);
       reg = (reg >> 1) | (new<<24);
    }
    i++;
  }
  return 0;
}

The output proves that this should work!

$ ./lfsr_test
i = 0
i = 32000000
i = 64000000
i = 96000000
i = 128000000
i = 160000000
i = 192000000
i = 224000000
i = 256000000

And here it is VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity pulse_per_second is
    Port ( clk : in  STD_LOGIC;
           pps : out  STD_LOGIC);
end pulse_per_second;

architecture Behavioral of pulse_per_second is
   signal lfsr : std_logic_vector(24 downto 0) := (others => '1');
begin
p: process(clk)
   begin
      if rising_edge(clk) then
         if lfsr  = "1111111111111111111111111" then
            lfsr <= "0111110111010111001000000";
            pps  <= '1';
         else
            lfsr <= (lfsr(0) xor lfsr(3)) & lfsr(lfsr'high downto 1);
            pps  <= '0';
         end if;
      end if;
   end process;
end Behavioral;

Personal tools