Generator liczb pseudolosowych VHDL

LFSR (Linear Feedback Shift Register) jest jedną z prostszych konstrukcji, jakie możemy uruchomić na układzie FPGA, a jednocześnie jest ona bardzo przydatna. Tego typu aplikacje stosuje się przede wszystkimi przy:

  • Generatorach wzorców testowych,
  • Szyfrowaniu danych,
  • Kryptografii

Rejestr przesuwny z liniowym sprzężeniem zwrotnym implementowany jest jako seria przerzutników, które razem tworzą rejestr przesuwny. Wyjścia kilku przerzutników używane są jako wejścia bramki XOR lub XNOR. Wygenerowany przez bramkę sygnał wykorzystywany jest następnie jako sprzężenie zwrotne, połączone z wejściem pierwszego przerzutnika.

Idea rejestru przesuwającego ze sprzężeniem zwrotnym

LFSR w czasie działania jest w stanie generować zmienne pseudolosowe, bliskie losowym. Trzeba jednak pamiętać, że w świecie elektroniki nic nie jest do końca losowe i dysponując aktualnym stanem licznika LFSR, jesteśmy w stanie przewidzieć jak będzie wyglądać kolejna wygenerowana zmienna. Ciekawostką może być fakt, że używając bramki XOR do generowania sprzężenia zwrotnego na wyjściu, nigdy nie pojawią się same zera, analogicznie sprawa wygląda, gdy skorzystamy z bramki XNOR, ale w tym przypadku na wyjściu nigdy nie będzie samych jedynek. 

Rejestr przesuwający z liniowym sprzężeniem zwrotnym możemy wykorzystać do budowy prostego generatora liczb pseudolosowych. Zaimplementujemy go na płytce Mimas v2. Wartość pseudolosowej zmiennej odświeżana będzie co sekundę i pojawi się na diodach LED. 

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;

Na początku zaczynamy oczywiście od deklaracji bibliotek i zdefiniowaniu portów wejścia/wyjścia. Układ będzie dysponować dwoma wejściami dla sygnału zegarowego i resetu oraz pojedynczym 8-bitowym wyjściem. 

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

Następnie należy dodać sygnały wewnętrzne. Jest ich pięć, pierwsze trzy przechowują informację o stanach LFSR, a kolejne dwa używane są w procesie generowania sygnału o częstotliwości 1Hz. 

	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';

Po słowie kluczowym begin opisany został licznik jednosekundowy, generujący sygnał o częstotliwości 1Hz, którego zadaniem będzie odświeżać wartość LFSR. Jest to konstrukcja, którą używałem już w innych projektach. Wraz z każdym taktem zegara zwiększana jest wartość sygnału one_second_counter i gdy osiągnie ona wartość 5F5E0FF, zmieniany jest stan one_second_enable. Ktoś mógłby zapytać, skąd wzięła się wartość 5F5E0FF? Otóż jest to wartość, którą osiągnie licznik po około sekundzie przy taktowaniu sygnałem o częstotliwości 100MHz.

  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;

Na końcu znalazł się opis naszego generatora liczb pseudolosowych. Mamy tutaj licznik bazujący na sygnale one_second_enable, przy każdym narastającym zboczu logicznym do zmiennej Currstate przypisywana jest wartość Nextstate. Każdy kolejny stan wyznaczany jest poprzez połączenie bitu feedback i siedmiu starszych bitów aktualnego stanu. Natomiast bit sprzężenia zwrotnego – feedback generowany jest poprzez czterowejściową bramkę XOR, do której podłączono bit czwarty, trzeci, drugi i zerowy zmiennej przechowującej dane o aktualnym stanie. Na samym końcu do wyjścia counter przypisywany jest aktualny stan. Warto też zwrócić uwagę co dzieje się w przypadku wystąpienia sygnału reset. Do zmiennej Currstate przypisane zostają same zera, ale najmłodszy bit musi być jedynką, bo jak pamiętacie, same zera na wyjściu licznika w przypadku zastosowania bramki XOR zawieszą licznik.   

Projekt uruchomiłem na płytce Mimas v2, efekt możecie zobaczyć na filmie powyżej.

W ostatnich latach żarówki LED na dobre zagościły w naszych domach, zastępując wysłużone już konstrukcje z wolframowym żarnikiem. Nic w tym dziwnego, LEDy w porównaniu do innych źródeł światła wypadają zaskakująco dobrze – zużywają niewiele energii, mogą świecić w różnych kolorach, włączają się natychmiast i nie nagrzewają się aż tak bardzo.

Nie ulega wątpliwości, że tranzystor jest czymś, co zrewolucjonizowało świat. Ciężko wyobrazić sobie dzisiejszą elektronikę bez tego niewielkiego elementu. Jest on na tyle uniwersalny, że w dzisiejszym świecie możemy znaleźć go w praktycznie każdym obwodzie elektronicznym.

Źródła:

  • 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/

Chcesz być na bieżąco?
Dołącz do newslettera

Otrzymywać będziesz powiadomienia o nowych artykułach oraz informacje o projektach, nad którymi pracuję.

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Przewiń do góry