Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Comment générer des nombres aléatoires en VHDL

VHDL a un générateur pseudo-aléatoire intégré, mais il ne peut générer que des nombres à virgule flottante entre 0 et 1. Heureusement, vous pouvez en dériver tout autre type de format de données aléatoire dont vous auriez besoin. Continuez à lire cet article pour savoir comment produire real ou integer valeurs de n'importe quelle plage, ainsi que std_logic_vector aléatoire séquences et time valeurs.

Le uniform procédure du package IEEE MATH_REAL est la base des algorithmes décrits dans cet article. Veuillez noter que uniform s'appuie sur un logiciel pour générer des nombres aléatoires. Par conséquent, aucun de ces algorithmes n'est synthétisable. Vous ne pouvez les utiliser que dans des bancs d'essai.

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

La liste ci-dessus montre le prototype du uniform procédure. Il a besoin de deux variables de départ pour fonctionner, et il les modifiera chaque fois que vous appelez la procédure. La sortie, X, est le nombre aléatoire, qui a toujours une valeur comprise entre 0 et 1.

Tout comme les autres générateurs de nombres pseudo-aléatoires, uniform générera la même séquence de nombres lorsqu'il est appelé avec les mêmes valeurs de départ initiales. En raison de ce comportement, vous pouvez réexécuter le testbench et obtenir le même résultat en utilisant les mêmes valeurs de départ.

Reportez-vous à l'article Efficient and Portable Combined Random Number Generators de Pierre L'Ecuyer pour une description détaillée du fonctionnement de cet algorithme. Vous pouvez également afficher une implémentation réelle de l'algorithme dans le simulateur VHDL open source GHDL.

Le cas de test

Tous les exemples de cet article utilisent la valeur 999 pour les deux graines. Nous déclarons les variables de départ comme indiqué ci-dessous dans la région déclarative d'un processus. Ensuite, nous implémentons nos algorithmes de randomisation personnalisés en tant que fonctions impures au sein du même processus.

variable seed1, seed2 : integer := 999;

Vous pouvez télécharger un testbench complet contenant tous les exemples de cet article en utilisant le formulaire ci-dessous. Le fichier Zip contient également un projet ModelSim avec un script qui compile et exécute la simulation pour vous.

Valeur réelle aléatoire

Le uniform procédure génère un real aléatoire valeur comprise entre 0,0 et 1,0. Le real type est le format à virgule flottante de VHDL. Cependant, il est probable que vous souhaitiez que le nombre aléatoire se situe dans une plage différente.

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;

Heureusement, nous pouvons facilement traduire la sortie de uniform en multipliant par une échelle et en y ajoutant un décalage. Le code ci-dessus montre une fonction qui renvoie un real aléatoire valeur dans une plage min/max.

Valeur entière aléatoire

Pour générer un integer aléatoire valeur dans une plage spécifiée, vous devez multiplier par une échelle et lui ajouter un décalage. Mais il y a un écueil qu'il faut éviter. Vous ne pouvez pas simplement générer un real aléatoire valeur dans la plage et arrondissez-la à un integer .

L'illustration ci-dessus montre le problème. Dans l'exemple, nous avons l'intention de générer un integer aléatoire valeur comprise entre -1 et 1. Si nous basons notre integer sur un real aléatoire qui va précisément aux extrémités, les entiers min et max n'ont que la moitié de la probabilité d'être choisis. Arrondi au 0 integer la valeur se produit la moitié du temps, même s'il y a trois choix de nombres.

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;

Dans le code ci-dessus, nous corrigeons le problème d'arrondi des points finaux en ajustant le real aléatoire valeur pour inclure 0,5 supplémentaire au-dessus et au-dessous des extrémités.

Std_logic_vector aléatoire

Il existe de nombreuses façons de remplir un vecteur avec des valeurs aléatoires, mais cette méthode fonctionne avec des vecteurs de n'importe quelle longueur. J'utilise une boucle for pour parcourir le vecteur et sélectionner une valeur aléatoire pour chaque bit. Dans le code ci-dessous, le len paramètre détermine la longueur du std_logic_vector aléatoire pour revenir.

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;

Valeur de temps aléatoire

Parfois, vous devez générer un time aléatoire valeur dans votre testbench. Vous souhaitez peut-être simuler une interface externe qui écrit des rafales de données à des moments aléatoires. Quelle que soit la raison, aléatoire time les valeurs sont faciles à produire.

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;

Pour générer un time aléatoire valeur en VHDL, vous devez d'abord convertir les valeurs min et max souhaitées en real les types. Ensuite, une fois que la formule de randomisation a fait son effet, vous reconvertissez le résultat en VHDL time taper. Notez que vous devez donner l'unité de temps de simulation que vous utilisez dans le simulateur comme argument de cette fonction, comme indiqué dans le code ci-dessus.

Le package aléatoire OSVVM

Enfin, comme alternative à la fabrication manuelle de l'algorithme de randomisation, vous pouvez utiliser le package Random de la bibliothèque OSVVM. Il a plusieurs fonctions surchargées pour générer des valeurs aléatoires pour toutes sortes de types VHDL.

Open Source VHDL Verification Methodology (OSVVM) est une bibliothèque VHDL permettant de créer des bancs de test structurés. Le package Random n'est qu'un des nombreux packages utiles de cette bibliothèque.

library osvvm;
use osvvm.RandomPkg.all;

Le code ci-dessus montre comment importer le package OSVVM. ModelSim inclut la bibliothèque prête à l'emploi, vous n'avez donc pas besoin de la télécharger pour ce simulateur. Reportez-vous au fichier RandomPck.vhd du référentiel OSVVM GitHub pour trouver une fonction de randomisation adaptée à vos besoins.


VHDL

  1. Comment créer une liste de chaînes en VHDL
  2. Comment arrêter la simulation dans un testbench VHDL
  3. Comment créer un contrôleur PWM en VHDL
  4. Comment créer une liste chaînée en VHDL
  5. Comment utiliser une procédure dans un processus en VHDL
  6. Comment utiliser une fonction impure en VHDL
  7. Comment utiliser une fonction en VHDL
  8. Comment créer une machine à états finis en VHDL
  9. Comment générer des nombres aléatoires en Java