So generieren Sie Zufallszahlen in VHDL
VHDL hat einen eingebauten Pseudozufallsgenerator, kann aber nur Gleitkommazahlen zwischen 0 und 1 erzeugen. Glücklicherweise können Sie daraus jedes andere zufällige Datenformat ableiten, das Sie benötigen. Lesen Sie diesen Artikel weiter, um herauszufinden, wie Sie real
herstellen oder integer
Werte eines beliebigen Bereichs sowie zufällige std_logic_vector
Sequenzen und time
Werte.
Die uniform
Prozedur aus dem Paket IEEE MATH_REAL ist die Grundlage für die in diesem Artikel beschriebenen Algorithmen. Bitte beachten Sie, dass uniform
ist auf Software angewiesen, um Zufallszahlen zu generieren. Daher ist keiner dieser Algorithmen synthetisierbar. Sie können sie nur in Testbenches verwenden.
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
Das obige Listing zeigt den Prototyp des uniform
Verfahren. Es benötigt zwei Seed-Variablen, um zu funktionieren, und es wird sie jedes Mal ändern, wenn Sie die Prozedur aufrufen. Die Ausgabe X ist die Zufallszahl, die immer einen Wert zwischen 0 und 1 hat.
Genau wie andere Pseudo-Zufallszahlengeneratoren, uniform
generiert die gleiche Zahlenfolge, wenn sie mit den gleichen anfänglichen Seed-Werten aufgerufen wird. Aufgrund dieses Verhaltens können Sie die Testbench erneut ausführen und dasselbe Ergebnis erzielen, wenn Sie dieselben Seed-Werte verwenden.
Eine detaillierte Beschreibung der Funktionsweise dieses Algorithmus finden Sie im Artikel Efficient and Portable Combined Random Number Generators von Pierre L’Ecuyer. Sie können auch eine tatsächliche Implementierung des Algorithmus im GHDL-Open-Source-VHDL-Simulator anzeigen.
Der Testfall
Alle Beispiele in diesem Artikel verwenden den Wert 999 für beide Startwerte. Wir deklarieren die Seed-Variablen wie unten aufgelistet im deklarativen Bereich eines Prozesses. Dann implementieren wir unsere benutzerdefinierten Randomisierungsalgorithmen als unreine Funktionen innerhalb desselben Prozesses.
variable seed1, seed2 : integer := 999;
Sie können eine vollständige Testbench mit allen Beispielen in diesem Artikel herunterladen, indem Sie das folgende Formular verwenden. Die Zip-Datei enthält auch ein ModelSim-Projekt mit einem Skript, das die Simulation für Sie kompiliert und ausführt.
Zufälliger reeller Wert
Die uniform
Prozedur generiert einen zufälligen real
Wert zwischen 0,0 und 1,0. Die real
type ist das Fließkommaformat von VHDL. Es besteht jedoch die Möglichkeit, dass Sie möchten, dass die Zufallszahl in einem anderen Bereich liegt.
impure function rand_real(min_val, max_val : real) return real is variable r : real; begin uniform(seed1, seed2, r); return r * (max_val - min_val) + min_val; end function;
Glücklicherweise können wir die Ausgabe von uniform
leicht übersetzen durch Multiplizieren mit einer Skala und Hinzufügen eines Offsets dazu. Der obige Code zeigt eine Funktion, die einen zufälligen real
zurückgibt Wert innerhalb eines Min/Max-Bereichs.
Ganzzahliger Zufallswert
Um einen zufälligen integer
zu generieren Wert innerhalb eines bestimmten Bereichs, müssen Sie mit einer Skala multiplizieren und einen Offset dazu addieren. Aber es gibt eine Falle, die Sie vermeiden müssen. Sie können nicht einfach einen zufälligen real
generieren Wert innerhalb des Bereichs und runden ihn auf integer
.
Die obige Abbildung zeigt das Problem. In dem Beispiel beabsichtigen wir, einen zufälligen integer
zu generieren Wert im Bereich von -1 bis 1. Wenn wir unseren integer
zugrunde legen auf einem zufälligen real
das geht genau bis zu den Endpunkten, die Min- und Max-Ganzzahlen bekommen nur die halbe Wahrscheinlichkeit, gewählt zu werden. Rundung auf 0 integer
Wert passiert die Hälfte der Zeit, obwohl es drei Zahlen zur Auswahl gibt.
impure function rand_int(min_val, max_val : integer) return integer is variable r : real; begin uniform(seed1, seed2, r); return integer( round(r * real(max_val - min_val + 1) + real(min_val) - 0.5)); end function;
Im obigen Code korrigieren wir das Endpunktrundungsproblem, indem wir den zufälligen real
anpassen Wert, um zusätzlich 0,5 über und unter den Endpunkten einzuschließen.
Zufälliger std_logic_vector
Es gibt viele Möglichkeiten, einen Vektor mit Zufallswerten zu füllen, aber diese Methode funktioniert mit Vektoren beliebiger Länge. Ich verwende eine for-Schleife, um den Vektor zu durchlaufen und einen zufälligen Wert für jedes Bit auszuwählen. Im folgenden Code ist der len
Parameter bestimmt die Länge des zufälligen std_logic_vector
zurück.
impure function rand_slv(len : integer) return std_logic_vector is variable r : real; variable slv : std_logic_vector(len - 1 downto 0); begin for i in slv'range loop uniform(seed1, seed2, r); slv(i) := '1' when r > 0.5 else '0'; end loop; return slv; end function;
Zufälliger Zeitwert
Manchmal müssen Sie einen zufälligen time
generieren Wert in Ihrer Testbench. Vielleicht möchten Sie eine externe Schnittstelle simulieren, die zu zufälligen Zeiten Datenblöcke schreibt. Was auch immer der Grund ist, zufällig time
Werte sind leicht zu erzeugen.
impure function rand_time(min_val, max_val : time; unit : time := ns) return time is variable r, r_scaled, min_real, max_real : real; begin uniform(seed1, seed2, r); min_real := real(min_val / unit); max_real := real(max_val / unit); r_scaled := r * (max_real - min_real) + min_real; return real(r_scaled) * unit; end function;
Um einen zufälligen time
zu generieren Wert in VHDL, müssen Sie zunächst die gewünschten Min- und Max-Werte in real
umwandeln Typen. Nachdem die Randomisierungsformel ihre Wirkung entfaltet hat, konvertieren Sie das Ergebnis zurück in ein VHDL time
Typ. Beachten Sie, dass Sie die Simulationszeiteinheit, die Sie im Simulator verwenden, als Argument für diese Funktion angeben müssen, wie im obigen Code gezeigt.
Das OSVVM Random-Paket
Schließlich können Sie als Alternative zum manuellen Erstellen des Randomisierungsalgorithmus das Random-Paket aus der OSVVM-Bibliothek verwenden. Es hat mehrere überladene Funktionen zum Generieren von Zufallswerten für alle Arten von VHDL-Typen.
Open Source VHDL Verification Methodology (OSVVM) ist eine VHDL-Bibliothek zum Erstellen strukturierter Testbenches. Das Random-Paket ist nur eines von vielen nützlichen Paketen in dieser Bibliothek.
library osvvm; use osvvm.RandomPkg.all;
Der obige Code zeigt, wie das OSVVM-Paket importiert wird. ModelSim enthält die Bibliothek sofort einsatzbereit, sodass Sie sie für diesen Simulator nicht herunterladen müssen. In der Datei RandomPck.vhd aus dem OSVVM-GitHub-Repo finden Sie eine geeignete Randomisierungsfunktion für Ihre Anforderungen.
VHDL
- So erstellen Sie eine Liste von Zeichenfolgen in VHDL
- So stoppen Sie die Simulation in einer VHDL-Testbench
- So erstellen Sie einen PWM-Controller in VHDL
- So erstellen Sie eine verknüpfte Liste in VHDL
- So verwenden Sie eine Prozedur in einem Prozess in VHDL
- So verwenden Sie eine unreine Funktion in VHDL
- So verwenden Sie eine Funktion in VHDL
- So erstellen Sie einen endlichen Automaten in VHDL
- So verwenden Sie eine Prozedur in VHDL
- So generieren Sie Zufallszahlen in Java