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!!!
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
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.
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ß
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.
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.
> 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>
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...
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...)
@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.