Hoe willekeurige getallen te genereren in VHDL
VHDL heeft een ingebouwde pseudo-willekeurige generator, maar deze kan alleen drijvende-kommagetallen tussen 0 en 1 genereren. Gelukkig kunt u hieruit elk ander willekeurig gegevensformaat afleiden dat u nodig heeft. Lees dit artikel verder om erachter te komen hoe u real
. kunt maken of integer
waarden van elk bereik, evenals willekeurige std_logic_vector
reeksen en time
waarden.
De uniform
procedure uit het IEEE MATH_REAL-pakket vormt de basis voor de algoritmen die in dit artikel worden beschreven. Houd er rekening mee dat uniform
vertrouwt op software om willekeurige getallen te genereren. Daarom kan geen van deze algoritmen worden gesynthetiseerd. Je kunt ze alleen in testbanken gebruiken.
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
De bovenstaande lijst toont het prototype van de uniform
procedure. Het heeft twee seed-variabelen nodig om te werken, en het zal deze elke keer dat u de procedure aanroept wijzigen. De uitvoer, X, is het willekeurige getal, dat altijd een waarde heeft tussen 0 en 1.
Net als andere pseudo-willekeurige nummergenerators, uniform
genereert dezelfde reeks nummers wanneer ze worden gebeld met dezelfde initiële beginwaarden. Vanwege dit gedrag kunt u de testbench opnieuw uitvoeren en hetzelfde resultaat krijgen als u dezelfde seed-waarden gebruikt.
Raadpleeg het document Efficient and Portable Combined Random Number Generators van Pierre L'Ecuyer voor een gedetailleerde beschrijving van hoe dit algoritme werkt. U kunt ook een daadwerkelijke implementatie van het algoritme bekijken in de GHDL open-source VHDL-simulator.
De testcase
Alle voorbeelden in dit artikel gebruiken de waarde 999 voor beide zaden. We declareren de seed-variabelen zoals hieronder vermeld in het declaratieve gebied van een proces. Vervolgens implementeren we onze aangepaste randomisatie-algoritmen als onzuivere functies binnen hetzelfde proces.
variable seed1, seed2 : integer := 999;
Via onderstaand formulier kunt u een complete testbench downloaden met daarin alle voorbeelden in dit artikel. Het Zip-bestand bevat ook een ModelSim-project met een script dat de simulatie voor u compileert en uitvoert.
Willekeurige reële waarde
De uniform
procedure genereert een willekeurige real
waarde tussen 0,0 en 1,0. De real
type is het drijvende-kommaformaat van VHDL. De kans is echter groot dat u wilt dat het willekeurige getal op een ander bereik staat.
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;
Gelukkig kunnen we de uitvoer van uniform
gemakkelijk vertalen door te vermenigvuldigen met een schaal en er een offset aan toe te voegen. De bovenstaande code toont een functie die een willekeurige real
. retourneert waarde binnen een min/max bereik.
Willekeurige gehele waarde
Een willekeurige integer
genereren waarde binnen een bepaald bereik, moet u vermenigvuldigen met een schaal en er een offset aan toevoegen. Maar er is een valkuil die je moet vermijden. Je kunt niet zomaar een willekeurige real
waarde binnen het bereik en rond het af op integer
.
De afbeelding hierboven laat het probleem zien. In het voorbeeld willen we een willekeurige integer
. genereren waarde in het bereik -1 tot 1. Als we onze integer
. baseren op een willekeurige real
dat gaat precies naar de eindpunten, de min en max gehele getallen krijgen maar de helft van de kans om gekozen te worden. Afronding op de 0 integer
waarde gebeurt de helft van de tijd, ook al zijn er drie nummerkeuzes.
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;
In de bovenstaande code corrigeren we het probleem met de afronding van het eindpunt door de willekeurige real
. aan te passen waarde om een extra 0,5 boven en onder de eindpunten op te nemen.
Willekeurige std_logic_vector
Er zijn veel manieren om een vector met willekeurige waarden te vullen, maar deze methode werkt met vectoren van elke lengte. Ik gebruik een for-lus om de vector te doorkruisen en voor elke bit een willekeurige waarde te selecteren. In de onderstaande code, de len
parameter bepaalt de lengte van de willekeurige std_logic_vector
om terug te keren.
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
Soms moet je een willekeurige time
. genereren waarde in uw testbank. Misschien wilt u een externe interface simuleren die op willekeurige tijdstippen gegevens uitbarst. Wat de reden ook is, willekeurige time
waarden zijn eenvoudig te produceren.
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;
Een willekeurige time
genereren waarde in VHDL, moet u eerst de gewenste min en max waarden converteren naar real
soorten. Vervolgens, nadat de randomisatieformule zijn magie heeft gedaan, converteert u het resultaat terug naar een VHDL time
type. Merk op dat u de simulatietijdseenheid die u in de simulator gebruikt, moet opgeven als argument voor deze functie, zoals weergegeven in de bovenstaande code.
Het OSVVM Random-pakket
Ten slotte kunt u, als alternatief voor het handmatig maken van het randomisatie-algoritme, het Random-pakket uit de OSVVM-bibliotheek gebruiken. Het heeft meerdere overbelaste functies voor het genereren van willekeurige waarden voor alle soorten VHDL-typen.
Open Source VHDL Verification Methodology (OSVVM) is een VHDL-bibliotheek voor het maken van gestructureerde testbanken. Het Random-pakket is slechts een van de vele nuttige pakketten in deze bibliotheek.
library osvvm; use osvvm.RandomPkg.all;
De bovenstaande code laat zien hoe u het OSVVM-pakket importeert. ModelSim bevat de bibliotheek out-of-the-box, dus u hoeft deze niet te downloaden voor deze simulator. Raadpleeg het RandomPck.vhd-bestand van de OSVVM GitHub-repo om een geschikte randomisatiefunctie voor uw behoeften te vinden.
VHDL
- Een lijst met strings maken in VHDL
- Simulatie stoppen in een VHDL-testbench
- Een PWM-controller maken in VHDL
- Een gekoppelde lijst maken in VHDL
- Een procedure gebruiken in een proces in VHDL
- Een onzuivere functie gebruiken in VHDL
- Een functie gebruiken in VHDL
- Een eindige-toestandsmachine maken in VHDL
- Een procedure gebruiken in VHDL
- Een timer maken in VHDL
- Willekeurige getallen genereren in Java