Forum: FPGA, VHDL & Co. Zufallszahlen mit VHDL erzeugen


von Sebastian (Gast)


Lesenswert?

Hi,

Hat jemand eine Idee, wie man mit VHDL zufallszahlen erzeugen kann? Ich 
bräuchte etwas, um in ein Register Werte zwischen 0 und dem maximalwert 
des Registers zu schreiben. Dabei sollen die Werte möglichst zufällig 
sein. Hat jemand beispielcode?

Danke!!!

von Kest (Gast)


Lesenswert?

Hier hast Du so ein Beispiel:



use ieee.numeric_std.all;
use ieee.math_real.all;


  process
    variable seed1, seed2 : positive;
    variable rand         : real;
    variable int_rand     : integer;
    variable stim         : std_logic_vector(11 downto 0);
  begin
    loop
      UNIFORM(seed1, seed2, rand);
      int_rand := integer(TRUNC(rand*4096.0));
      stim     := std_logic_vector(to_unsigned(int_rand, stim'length));
      wait for 10 ns;
    end loop;
  end process;


Grüße,

Kest

von Mathi (Gast)


Lesenswert?

Wenn es synthetisierbar sein soll, dann kannst Du ein LFSR 
implementieren. Google mal danach...

von Morin (Gast)


Lesenswert?

LFSR geht gut und braucht wenig Hardware, aber Vorsicht: Die Doku im 
Netz ist mehr als bescheiden. Vor allem fehlende oder widersprüchliche 
Angaben darüber von welcher seite aus die Taps abgezählt sind, oder ob 
sie mit XOR oder XNOR kombiniert werden...

Wenn du da was falsch machst kann es schnell passieren, dass du eine 
nicht-optimale Folge bekommst oder das LFSR sich sogar aufhängt.

von spartanne (Gast)


Lesenswert?

Wie zufällig muss es denn sein?
Die Folgen bei einem LFSR sind deterministisch.
Wenn du ein LFSR auf einem FPGA implementierst und mit dem FPGA-Clock 
tacktest, so wirst du nach dem Startup wenn du z.B. immer nach 10us, 
nach 20us, .. auf das Register schaust, immer die gleichen Werte 
erhalten, da der Initalwert auch immer der selbe sein wird. Ist halt 
alles synchron getaktet.
Bei einem rein digitalen Design braucht man eigentlich immer einen 
analogen Effekt um es richtig zufällig zu machen (true random noise), 
z.B. Jitter, Resetzeiten, RTC o.ä., welche dann den Startwert des LFSR 
beeinflussen.
Oder (bei einer Steuerung mit Eingabe) nimmt man den Bediener als 
Zufall.

Es gibt noch dreckigere Möglichkeiten um einen Zufall zu erzeugen, wie 
z.B. metastabile FF auf dem FPGA erzeugen.. geschmackssache. Ich hätte 
da Probleme mit ob das bei jeder Temperatur funktioniert...
Oder die Zeit bis zum Einrasten einer PLL (falls auf FPGA vorhanden)..

Wenn man (wie Morin richtig erwähnt) die Rückkopplungen des LFSR richtig 
wählt, so durchläuft das LFSR auch alle möglichen Zustände. Wenn das 
ausreicht, dann ab dafür.

Gruß

von spartanne (Gast)


Lesenswert?

hab grad mal noch schnell ISE von Xilinx angeschmissen, hier die Makros 
für LFSR 8Bit, 16Bit, 32Bit:

8Bit:
process(<clock>)
begin
   if ( <clock>'event and <clock> ='1') then
      if (<reset> = '1') then
         <reg_name> <= (others => '0');
      elsif <clock_enable>='1' then
         <reg_name>(7 downto 1) <= <reg_name>(6 downto 0) ;
         <reg_name>(0) <= not(<reg_name>(7) XOR <reg_name>(6) XOR 
<reg_name>(4));
      end if;
   end if;
end process;


16Bit:
process(<clock>)
begin
   if ( <clock>'event and <clock> ='1') then
      if (<reset> = '1') then
         <reg_name> <= (others => '0');
      elsif <clock_enable>='1' then
         <reg_name>(15 downto 1) <= <reg_name>(14 downto 0) ;
         <reg_name>(0) <= not(<reg_name>(15) XOR <reg_name>(14) XOR 
<reg_name>(13) XOR <reg_name>(4));
      end if;
   end if;
end process;


32Bit:
process(<clock>)
begin
   if ( <clock>'event and <clock> ='1') then
      if (<reset> = '1') then
         <reg_name> <= (others => '0');
      elsif <clock_enable>='1' then
         <reg_name>(31 downto 1) <= <reg_name>(30 downto 0) ;
         <reg_name>(0) <= not(<reg_name>(31) XOR <reg_name>(22) XOR 
<reg_name>(2) XOR <reg_name>(1));
      end if;
   end if;
end process;


Diese sollten alle Zustände durchlaufen.
Man kann ein LFSR auch als ein Zähler mit nachgeschaltetem Decoder (z.B. 
ROM) betrachten. Der Zähler inkrementiert mit jedem Takt und adressiert 
das ROM, welches die Ausgangscodierung vornimmt.

von FPGA-Pongo (Gast)


Lesenswert?

Offene Leitung von out=1 auf tristate schalten und den Verfall der 
Ladung messen.

von Jörg (Gast)


Lesenswert?

Im Internet findet man eine Menge von VHDL-Algorithmen, z.B.

1.  http://en.wikipedia.org/wiki/LFSR

2.  http://www.ht-lab.com/freecores/mt32/mersenne.html

Beide erzeugen gleichverteilte Zufallsfolgen. Der zweite ist bzgl.
Periodendauer sogar sehr gut, ca 10^8000 ist die Periodendauer,
selbst bei 1 GHz: die Erde ist jünger. Zur Simulation hast Du den
Vorteil, das Du immer den selben Startwert wählen kannst, im Betrieb
kann der Startwert entweder als Schlüssel oder aber über einen
asynchron laufenden Quarz bestimmt werden.

von Morin (Gast)


Lesenswert?

> Wie zufällig muss es denn sein?

Das ist allerdings eine Wichtige Frage. Ich hab damals ein LFSR 
gebraucht, um Rauschen auf einem Lautsprecher auszugeben. Da ist es 
Wurst wenn sich die Folge nach 1 sec wiederholt.

Am anderen Ende hast du Krypto-Anwendungen, die werden gleich kriminell 
unsicher wenn du nicht weißt was du tust.

> Wenn du ein LFSR auf einem FPGA implementierst und mit dem FPGA-Clock
> tacktest, so wirst du nach dem Startup wenn du z.B. immer nach 10us,
> nach 20us, .. auf das Register schaust, immer die gleichen Werte
> erhalten, da der Initalwert auch immer der selbe sein wird. Ist halt
> alles synchron getaktet.

Wenn du nicht jeden Takt einen Zufallswert brauchst, kannst du per 
Clock-Enable das ganze in die Länge ziehen. Ansonsten gilt: Mehr Bits = 
länger, und da man mit den richtigen Taps auf "volle Länge" (*) kommt, 
eine Beispielrechnung: 200 MHz Takt = 5 ns Taktperiode, 32-Bit LFSR: ca. 
2^32 Zustände -> nach 20 Sekunden kommt die Wiederholung. Mit einem 
64-Bit LFSR bist du dann schon gleich bei mehreren tausen Jahren.

(*) <klugscheißermodus>Der Nullzustand wird nie erreicht -> es sind nur 
2^32-1 Zustände</klugscheißermodus>

von Morin (Gast)


Lesenswert?

Noch ein Nachtrag: Bei den Vorschlägen "Metastabiles FF", "Zeit zum 
Einrasten einer PLL" oder "Verfall der Ladung auf einer 
Tristate-Leitung" würde ich gerne mal den Nachweis einer 
gleichverteilten Zufallsfolge sehen...

von Εrnst B. (ernst)


Lesenswert?

Morin wrote:
> Noch ein Nachtrag: Bei den Vorschlägen "Metastabiles FF", "Zeit zum
> Einrasten einer PLL" oder "Verfall der Ladung auf einer
> Tristate-Leitung" würde ich gerne mal den Nachweis einer
> gleichverteilten Zufallsfolge sehen...

Das ist einfach... Diese Werte nimmt man nur zum Seeden eines PRNG, also 
bleiben die Eigenschaften des PRNG erhalten.
(Solang man's nicht wie die Debian-OpenSSL macht, und nur 2^16 
verschiedene Seeds erzeugt...)

von spartanne (Gast)


Lesenswert?

@Morin
Das Problem der Wiederholung tritt doch für halbwegs praktische 
Anwendungen nicht auf. Wie du richtig sagst, man nimmt halt 64Bit oder 
mehr und dann kann man ein paar Jahre warten.
Hängt halt alles von der Anwendung ab. Wäre gut wenn sich Sebastian dazu 
äußern würde...
Gerade bei Kryptografie kann man sich ordentlich austoben. Sonst ist ein 
LFSR allein sicher ausreichend.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.