Pseudorandom number generator in VHDL

The LFSR (Linear Feedback Shift Register) is one of the simpler designs we can run on an FPGA chip, yet it is very useful. This type of application is primarily used for:

  • Test pattern generators,
  • Data encryption,
  • Cryptography

A sliding register with linear feedback is implemented as a series of flip-flops that together form a sliding register. The outputs of several metastables are used as inputs of an XOR or XNOR gate. The signal generated by the gate is then used as feedback, connected to the input of the first flip-flop.

The idea of a shifting register with feedback

The LFSR at runtime is capable of generating pseudo-random, near random variables. However, it should be remembered that in the world of electronics nothing is completely random, and having the current state of the LFSR counter, we are able to predict what the next generated variable will look like. It may be interesting to note that using an XOR gate to generate the feedback at the output, there will never be the zeros themselves, the analogy is when we use an XNOR gate, but in this case there will never be the ones themselves at the output. 

We can use the shift register with linear feedback to build a simple pseudo-random number generator. We will implement it on the Mimas v2 board. The value of the pseudo-random variable will be refreshed every second and will appear on the LEDs. 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;

Entity counter is
  Port( clk : in std_logic;		                      --clock
		  reset : in std_logic;		                  --reset
        counter : out std_logic_vector(7 downto 0));  --counter output
end counter;

First, of course, we start with the declaration of libraries and the definition of input/output ports. The circuit will have two inputs for clock and reset signals and a single 8-bit output. 

architecture Behavioral of counter is
  signal Currstate : std_logic_vector(7 downto 0); 	            --current state
  signal Nextstate : std_logic_vector(7 downto 0);	            --next state
  signal feedback : std_logic;				                    --signal after xor operation	
  signal one_second_counter : STD_LOGIC_VECTOR(27 downto 0);    --1s counter
  signal one_second_enable : std_logic;			                --1Hz signal
begin

Next, internal signals must be added. There are five of them, the first three store information about the states of the LFSR, and the next two are used in the process of generating a 1Hz signal. 

	process(clk, reset)					--1s counter
		begin
			if(reset='0') then
				one_second_counter <= (others => '0');
			elsif(rising_edge(clk)) then
				if(one_second_counter>=x"5F5E0FF") then
					one_second_counter <= (others => '0');
            else
               one_second_counter <= one_second_counter + "0000001";
            end if;
			end if;
	end process;

one_second_enable <= '1' when one_second_counter=x"5F5E0FF" else '0';

After the begin keyword, a one-second counter is described, generating a 1Hz signal whose task will be to refresh the LFSR value. This is a design that I have already used in other projects. With each clock beat, the value of the one_second_counter signal is increased, and when it reaches 5F5E0FF, the one_second_enable state is changed. Someone might ask, where did the value 5F5E0FF come from? Well, this is the value that the counter will reach after about a second when clocked by a 100MHz signal.

  process(one_second_enable,reset)	--lfsr counter
	begin
    if(reset = '0') then
      Currstate <= (0 => '1', others =>'0');
    elsif (rising_edge(one_second_enable)) then
      Currstate <= Nextstate;
    end if;
  end process;
  
  feedback <= Currstate(4) xor Currstate(3) xor Currstate(2) xor Currstate(0); --xor operation
  Nextstate <= feedback & Currstate(7 downto 1);	  --to the current state assign the next
  counter <= Currstate;	                              --assign the current state to the output

end Behavioral;

Finally, there was a description of our pseudo-random number generator. Here we have a counter based on the one_second_enable signal, with each rising logical edge the Nextstate value is assigned to the Currstate variable. Each next state is determined by combining the feedback bit and the seven older bits of the current state. On the other hand, the feedback bit – feedback is generated through a four-input XOR gate, to which the fourth, third, second and zero bits of the variable storing the current state data are connected. At the very end, the current state is assigned to the counter output. It is also worth noting what happens when the reset signal occurs. The zeros themselves are assigned to the Currstate variable, but the youngest bit must be a one, because, as you will remember, the zeros themselves in the output of the counter if an XOR gate is used will suspend the counter.   

I ran the project on a Mimas v2 board, and you can see the effect in the video above.

Sources:

  • https://zipcpu.com/dsp/2017/10/27/lfsr.html
  • https://nandland.com/lfsr-linear-feedback-shift-register/
  • https://ieeexplore.ieee.org/document/6292169
  • https://docs.xilinx.com/r/2021.2-English/ug1483-model-composer-sys-gen-user-guide/LFSR
  • https://numato.com/docs/mimas-v2-spartan-6-fpga-development-board-with-ddr-sdram/

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top