Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> VHDL

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

  1. Een lijst met strings maken in VHDL
  2. Simulatie stoppen in een VHDL-testbench
  3. Een PWM-controller maken in VHDL
  4. Een gekoppelde lijst maken in VHDL
  5. Een procedure gebruiken in een proces in VHDL
  6. Een onzuivere functie gebruiken in VHDL
  7. Een functie gebruiken in VHDL
  8. Een eindige-toestandsmachine maken in VHDL
  9. Een procedure gebruiken in VHDL
  10. Een timer maken in VHDL
  11. Willekeurige getallen genereren in Java