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

Zufallszahlen in VHDL generieren: Von Uniform zu OSVVM

VHDL beinhaltet einen eingebauten Pseudo-Zufallsgenerator, der Gleitkommawerte im Intervall [0, 1] liefert. Durch Skalieren und Verschieben dieser Werte können Sie Zufallsdaten beliebigen Typs erstellen – real, integer, std_logic_vector oder time – passend für Testbenches. Die folgende Anleitung zeigt, wie Sie diese Generatoren mit der IEEE MATH_REAL uniform-Prozedur bauen und wie Sie das OSVVM Random Package für noch mehr Flexibilität nutzen.

Die uniform-Prozedur, definiert im IEEE MATH_REAL-Paket, ist die Grundlage der folgenden Beispiele:

procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL); 

Sie erfordert zwei Seed-Variablen, die bei jedem Aufruf aktualisiert werden. Die Ausgabe X ist eine pseudo-zufällige reelle Zahl zwischen 0 und 1. Da der Algorithmus deterministisch ist, erzeugt dasselbe initiale Seed-Paar exakt dieselbe Zahlenfolge – eine essenzielle Eigenschaft für reproduzierbare Testbenches.

Für ein tieferes Verständnis des zugrundeliegenden Algorithmus verweisen Sie auf Pierre L'Ecuyers Paper Efficient and Portable Combined Random Number Generators oder inspizieren Sie die Implementierung, die mit dem GHDL-Simulator mitgeliefert wird.

Der Testfall

Alle Beispiele unten nutzen 999 als beide Seed-Werte. Deklarieren Sie die Seeds im deklarativen Bereich des Prozesses und implementieren Sie die Randomisierungsfunktionen als impure Functions innerhalb desselben Prozesses:

variable seed1, seed2 : integer := 999; 

Sie können einen vollständigen Testbench mit allen Beispielen dieses Artikels als ZIP-Datei herunterladen. Das Archiv enthält auch ein ModelSim-Projekt mit einem Skript, das kompiliert und die Simulation startet.

Zufälliger reeller Wert

Die uniform-Prozedur liefert eine reelle Zahl im Bereich [0.0, 1.0]. Um dies auf ein beliebiges Intervall [min_val, max_val] abzubilden, multiplizieren Sie mit der Breite und addieren den Offset:

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; 

Zufälliger Integer-Wert

Einen zufälligen Integer aus einem reellen Wert zu erzeugen, ist knifflig, da einfaches Runden die Wahrscheinlichkeit der Extremwerte verzerrt. Die folgende Funktion korrigiert diesen Bias, indem sie 0.5 vor dem Runden addiert:

Zufallszahlen in VHDL generieren: Von Uniform zu OSVVM

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; 

Die Anpassung stellt sicher, dass jeder Integer im Intervall [min_val, max_val] die gleiche Chance hat, ausgewählt zu werden.

Zufälliger std_logic_vector

Um einen std_logic_vector beliebiger Länge mit zufälligen Bits zu füllen, iterieren Sie über jede Position und weisen '1' zu, wenn der zufällige reelle Wert 0.5 übersteigt, sonst '0':

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

Wenn Sie einen zufälligen Zeitstempel benötigen – beispielsweise zur Simulation von burstartigem Datenverkehr – können Sie einen zufälligen reellen Wert auf das gewünschte Intervall skalieren und zurück in einen VHDL-Zeittyp konvertieren:

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; 

Beachten Sie, dass Sie die Simulator-Zeiteinheit (z. B. ns) an die Funktion übergeben müssen.

Das OSVVM Random Package

Für Nutzer, die eine fertige Lösung bevorzugen, bietet OSVVMs Random Package einen reichen Satz überladener Funktionen, die Zufallswerte für alle Standard-VHDL-Typen erzeugen. Importieren Sie das Paket mit:

library osvvm; use osvvm.RandomPkg.all; 

ModelSim wird mit vorinstalliertem OSVVM ausgeliefert, sodass auf dieser Plattform kein zusätzlicher Download nötig ist. Für andere Simulatoren verweisen Sie auf die RandomPck.vhd-Datei im OSVVM-GitHub-Repository.

VHDL

  1. String-Listen in VHDL erstellen: Best Practices & Beispiel
  2. VHDL-Testbench-Simulation sauber beenden
  3. PWM-Controller in VHDL implementieren: Design, Simulation & FPGA-Demo
  4. Dynamische verkettete Liste in VHDL mit Protected Types und Access-Pointern
  5. In-Prozess-Prozeduren für saubere VHDL-FSM-Entwürfe nutzen
  6. Impure Functions in VHDL nutzen: FSM-Lesbarkeit und Wartbarkeit steigern
  7. VHDL-Funktionen meistern: Praktischer Leitfaden für effizientes Design
  8. Endlicher Automat in VHDL entwerfen: Praktisches Ampel-Beispiel
  9. Prozeduren in VHDL: Wiederverwendbaren Code für einfachere Designs
  10. Zufallszahlen in Java generieren: Praktischer Leitfaden mit Random und Math.random