Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

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

  1. So erstellen Sie eine Liste von Zeichenfolgen in VHDL
  2. So stoppen Sie die Simulation in einer VHDL-Testbench
  3. So erstellen Sie einen PWM-Controller in VHDL
  4. So erstellen Sie eine verknüpfte Liste in VHDL
  5. So verwenden Sie eine Prozedur in einem Prozess in VHDL
  6. So verwenden Sie eine unreine Funktion in VHDL
  7. So verwenden Sie eine Funktion in VHDL
  8. So erstellen Sie einen endlichen Automaten in VHDL
  9. So verwenden Sie eine Prozedur in VHDL
  10. So generieren Sie Zufallszahlen in Java