Willekeurige getallen genereren in VHDL: Van Uniform naar OSVVM
VHDL bevat een ingebouwde pseudo-random generator die drijvende-komma waarden in het [0, 1] interval oplevert. Door deze waarden te schalen en te verschuiven, kun je willekeurige data van elk type creëren — real, integer, std_logic_vector of time — geschikt voor testbenches. De volgende gids laat zien hoe je deze generators bouwt met de IEEE MATH_REAL uniform procedure en hoe je het OSVVM Random-pakket benut voor nog grotere flexibiliteit.
De uniform procedure, gedefinieerd in het IEEE MATH_REAL pakket, is de fundament van de onderstaande voorbeelden:
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
Het vereist twee seed-variabelen die bij elke aanroep geüpdatet worden. De uitvoer, X, is een pseudo-random reëel getal tussen 0 en 1. Omdat het algoritme deterministisch is, produceert hetzelfde initiële seed-paar de exactezelfde getallenreeks — een essentiële eigenschap voor herhaalbare testbenches.
Voor een dieper begrip van het onderliggende algoritme, raadpleeg Pierre L'Ecuyer's Efficient and Portable Combined Random Number Generators paper, of inspecteer de implementatie gebundeld met de GHDL-simulator.
De Testcase
Alle onderstaande voorbeelden gebruiken 999 als beide seed-waarden. Declareer de seeds in het proces-declaratieve gebied en implementeer de randomisatiefuncties als impure functions binnen hetzelfde proces:
variable seed1, seed2 : integer := 999;
Je kunt een complete testbench downloaden die elk voorbeeld in dit artikel bevat als ZIP-bestand. Het archief bevat ook een ModelSim-project met een script dat compileert en de simulatie draait.
Willekeurige reële waarde
De uniform procedure retourneert een reëel getal in het [0.0, 1.0] bereik. Om dit af te beelden op willekeurig interval [min_val, max_val], vermenigvuldig met de breedte en tel de offset op:
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;
Willekeurige integer-waarde
Een willekeurige integer genereren vanuit een reële waarde is lastig omdat simpele afronding de kans op de extreme waarden scheeftrekt. De volgende functie corrigeert deze bias door 0.5 toe te voegen vóór afronding:

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;
De correctie zorgt ervoor dat elk integer in het interval [min_val, max_val] een gelijke kans heeft om geselecteerd te worden.
Willekeurige std_logic_vector
Om een willekeurige-lengte std_logic_vector te vullen met willekeurige bits, itereer over elke positie en wijs '1' toe wanneer de willekeurige reële waarde 0.5 overschrijdt, anders '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;
Willekeurige tijdswaarde
Wanneer je een willekeurige tijdstempel nodig hebt — bijvoorbeeld om bursty dataverkeer te simuleren — kun je een willekeurige reële waarde schalen naar het gewenste interval en terugconverteren naar een VHDL-tijdstype:
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;
Let op dat je de simulator's tijdseenheid (bijv. ns) aan de functie moet doorgeven.
Het OSVVM Random Pakket
Voor gebruikers die een kant-en-klaar oplossing prefereren, biedt OSVVM's Random-pakket een rijke set overgeladen functies die willekeurige waarden genereren voor alle standaard VHDL-typen. Importeer het pakket met:
library osvvm; use osvvm.RandomPkg.all;
ModelSim wordt geleverd met OSVVM voorgeïnstalleerd, dus geen extra download vereist op dat platform. Voor andere simulators, raadpleeg het OSVVM GitHub-repository's RandomPck.vhd bestand.
VHDL
- Dynamische string-lijsten in VHDL: Best Practices & Voorbeeld
- Een VHDL-testbench netjes beëindigen: methoden en best practices
- Een PWM-controller implementeren in VHDL: Ontwerp, Simulatie en FPGA-demo
- Een dynamische gelinkte lijst in VHDL implementeren met protected types en access pointers
- In-process procedures benutten voor schonere VHDL FSM-ontwerpen
- Impure functies in VHDL gebruiken: FSM-leesbaarheid en onderhoudbaarheid verbeteren
- VHDL-functies onder de knie krijgen: een praktische gids voor efficiënt ontwerp
- Een eindige-toestandsmachine in VHDL ontwerpen: een praktisch verkeerslichtvoorbeeld
- Procedures in VHDL gebruiken: je ontwerp vereenvoudigen met herbruikbare code
- Een betrouwbare timer in VHDL bouwen: klokcycli tellen tot uren
- Willekeurige Getallen Genereren in Java: Praktische Gids met Random en Math.random