Générer des nombres aléatoires en VHDL : De l'uniforme à OSVVM
Le VHDL inclut un générateur pseudo-aléatoire intégré qui produit des valeurs à virgule flottante dans l'intervalle [0, 1]. En mettant à l'échelle et en décalant ces valeurs, vous pouvez créer des données aléatoires de tout type — réel, entier, std_logic_vector, ou temps — adaptées aux bancs de test. Le guide suivant montre comment construire ces générateurs avec la procédure uniform du paquet IEEE MATH_REAL et comment tirer parti du paquet Random d'OSVVM pour encore plus de flexibilité.
La procédure uniform, définie dans le paquet IEEE MATH_REAL, est la base des exemples ci-dessous :
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
Elle nécessite deux variables de graine qui sont mises à jour à chaque appel. La sortie, X, est un nombre réel pseudo-aléatoire entre 0 et 1. Comme l'algorithme est déterministe, la même paire de graines initiales produira la même séquence de nombres — une propriété essentielle pour des bancs de test reproductibles.
Pour une compréhension plus approfondie de l'algorithme sous-jacent, référez-vous à l'article de Pierre L'Ecuyer Efficient and Portable Combined Random Number Generators, ou inspectez l'implémentation fournie avec le simulateur GHDL.
Le cas de test
Tous les exemples ci-dessous utilisent 999 comme valeurs de graine. Déclarez les graines dans la région déclarative du processus et implémentez les fonctions de randomisation comme des fonctions impures à l'intérieur du même processus :
variable seed1, seed2 : integer := 999;
Vous pouvez télécharger un banc de test complet contenant chaque exemple de cet article sous forme de fichier ZIP. L'archive inclut aussi un projet ModelSim avec un script qui compile et lance la simulation.
Valeur réelle aléatoire
La procédure uniform retourne un nombre réel dans l'intervalle [0.0, 1.0]. Pour mapper cela sur un intervalle arbitraire [min_val, max_val], multipliez par la largeur et ajoutez le décalage :
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;
Valeur entière aléatoire
Générer un entier aléatoire à partir d'une valeur réelle est délicat car un arrondi simple fausse la probabilité des valeurs extrêmes. La fonction suivante corrige ce biais en ajoutant 0.5 avant d'arrondir :

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;
L'ajustement assure que chaque entier dans l'intervalle [min_val, max_val] a une chance égale d'être sélectionné.
Vecteur std_logic_vector aléatoire
Pour remplir un std_logic_vector de longueur arbitraire avec des bits aléatoires, itérez sur chaque position et assignez '1' quand le réel aléatoire dépasse 0.5, sinon '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;
Valeur de temps aléatoire
Quand vous avez besoin d'un horodatage aléatoire — par exemple, pour simuler un trafic de données en rafales — vous pouvez mettre à l'échelle un réel aléatoire sur l'intervalle désiré et convertir à nouveau en type time VHDL :
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;
Notez que vous devez fournir l'unité de temps du simulateur (par ex., ns) à la fonction.
Le paquet Random d'OSVVM
Pour les utilisateurs qui préfèrent une solution prête à l'emploi, le paquet Random d'OSVVM offre un ensemble riche de fonctions surchargées qui génèrent des valeurs aléatoires pour tous les types VHDL standards. Importez le paquet avec :
library osvvm; use osvvm.RandomPkg.all;
ModelSim est livré avec OSVVM préinstallé, donc aucun téléchargement supplémentaire n'est requis sur cette plateforme. Pour les autres simulateurs, référez-vous au fichier RandomPck.vhd du dépôt GitHub OSVVM.
VHDL
- Créer des listes de chaînes en VHDL : Bonnes pratiques et exemple
- Terminer proprement une simulation de banc de test VHDL
- Implémenter un contrôleur PWM en VHDL : Conception, simulation et démo FPGA
- Implémentation d'une liste chainée dynamique en VHDL avec types protégés et pointeurs d'accès
- Exploiter les procédures in-process pour un design FSM VHDL plus propre
- Utilisation des fonctions impures en VHDL : Améliorer la lisibilité et la maintenabilité des FSM
- Maîtriser les fonctions VHDL : Guide pratique pour un design efficace
- Conception d'une machine d'état finie en VHDL : Exemple pratique de feu tricolore
- Générer des Nombres Aléatoires en Java : Guide Pratique avec Random et Math.random