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

Beperkte willekeurige verificatie

Beperkte willekeurige verificatie is een testbench-strategie die berust op het genereren van pseudo-willekeurige transacties voor het te testen apparaat (DUT). Het doel is om een ​​functionele dekking van een aantal vooraf gedefinieerde gebeurtenissen te bereiken door middel van willekeurige interactie met de TU Delft.

Open Source VHDL Verification Methodology (OSVVM) is een gratis VHDL-bibliotheek die een aantal handige pakketten bevat voor het maken van beperkte willekeurige testbanken. We zijn vooral geïnteresseerd in de RandomPkg en CoveragePck, die we in dit artikel zullen gebruiken. Ik raad aan om de OSVVM GitHub-pagina te bezoeken voor meer informatie over de functies van deze bibliotheek.

Het te testen apparaat

Ik ga meteen in een voorbeeld duiken om beter uit te leggen hoe een beperkte willekeurige testbench verschilt van de klassieke testbench, die gerichte tests gebruikt. We hebben een ringbuffer FIFO gemaakt in het vorige artikel op deze blog, maar we hebben geen zelfcontrolerende testbank gemaakt om de juistheid van de module te verifiëren.

We gaan een goede testbank maken voor de ringbuffer FIFO die gebruikmaakt van beperkte willekeurige verificatie.

entity ring_buffer is
  generic (
    RAM_WIDTH : natural;
    RAM_DEPTH : natural
  );
  port (
    clk : in std_logic;
    rst : in std_logic;

    -- Write port
    wr_en : in std_logic;
    wr_data : in std_logic_vector(RAM_WIDTH - 1 downto 0);

    -- Read port
    rd_en : in std_logic;
    rd_valid : out std_logic;
    rd_data : out std_logic_vector(RAM_WIDTH - 1 downto 0);

    -- Flags
    empty : out std_logic;
    empty_next : out std_logic;
    full : out std_logic;
    full_next : out std_logic;

    -- The number of elements in the FIFO
    fill_count : out integer range RAM_DEPTH - 1 downto 0
  );
end ring_buffer;

De entiteit van de ringbuffermodule wordt weergegeven in de bovenstaande code. We gaan de TU Delft behandelen als een zwarte doos, wat inhoudt dat we er niet vanuit gaan dat we weten hoe de TU Delft wordt geïmplementeerd. Dit artikel gaat immers over de testbench, niet over de ringbuffer FIFO.

We zullen de DUT in de testbench instantiëren met behulp van de entiteitsinstantiatiemethode. De instantiatie is triviaal, dus ik zal de code voor nu weglaten, maar deze kan later in dit artikel worden gedownload.

De generieken van de TU Delft worden toegewezen aan de volgende waarden:

  • RAM_WIDTH:16
  • RAM_DEPTH:256

Testbench-strategie

Laten we de teststrategie doornemen voordat we ook maar iets gaan implementeren. De afbeelding hieronder toont het hoofdconcept van de testbank die we gaan maken.

We zullen willekeurige schrijftransacties uitvoeren aan de invoerzijde van de TU Delft. De invoergegevens worden bij elke klokcyclus op een willekeurige waarde ingesteld en de flitsers op de invoer voor schrijven inschakelen hebben een willekeurige duur.

Op dezelfde manier zullen we willekeurig lezen. We zullen het leesactiveringssignaal bevestigen in bursts die een willekeurig aantal klokcycli duren.

Parallel aan de TU Delft komt er een gedragsmodel. Dit is een FIFO die anders is geïmplementeerd dan de ringbuffer die in de TU Delft wordt gebruikt, maar toch dezelfde interface heeft. In tegenstelling tot de TU Delft hoeft het gedragsmodel niet synthetisch te zijn. Dit geeft ons de vrijheid om geavanceerde VHDL-programmeerfuncties te gebruiken om het te maken.

In een apart proces vergelijken we de output van de TU Delft met de output van het gedragsmodel. Dit proces is als enige verantwoordelijk voor het uitvoeren van deze vergelijking bij elke klokcyclus met behulp van assert-statements. Als de twee FIFO-implementaties zich op enig moment anders gedragen, zal een beweringfout ervoor zorgen dat de simulatie met een fout wordt beëindigd.

Tot slot verzamelen we functionele dekkingsgegevens door de transacties te observeren die van en naar de TU Delft gaan. Een functioneel dekkingspunt kan bijvoorbeeld betekenen dat er gelijktijdig wordt gelezen en geschreven, of dat de FIFO minimaal één keer wordt gevuld. We zullen deze gebeurtenissen volgen in ons belangrijkste testbench-sequencerproces. De simulatie wordt gestopt wanneer alle functionele dekkingsgebeurtenissen die we bewaken, hebben plaatsgevonden.

De OSVVM-bibliotheek importeren

De OSVVM-bibliotheek kan worden gebruikt met elke simulator die VHDL-2008 ondersteunt. Het is mogelijk al opgenomen in de standaardbibliotheken die bij uw simulator worden geleverd. Het is opgenomen in de ModelSim PE Student Edition, die gratis kan worden gedownload van Mentor Graphics.

ModelSim wordt geleverd met een oudere versie van OSVVM, maar dat is oké, het heeft alles wat we nodig hebben. We kunnen gewoon doorgaan en de willekeurige en dekkingspakketten als volgt importeren:

library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;

De nieuwste versie van de OSVVM-bibliotheek kan altijd worden gedownload van de GitHub-pagina. Doe dit als uw simulator deze niet heeft, of als u de nieuwste functies van de bibliotheek wilt gebruiken.

De OSSVM-variabelen declareren

De OSVVM-bibliotheek bevat pakketten met beveiligde typen. Variabelen die hiervan worden gemaakt, zijn beperkt tot het proces waarin ze zijn gedefinieerd. Daarom zullen we ze in plaats daarvan declareren als gedeelde variabelen in het declaratieve gebied van de testbench-architectuur, zoals weergegeven in de onderstaande code.

 -- OSVVM variables
  shared variable rv : RandomPType;
  shared variable bin1, bin2, bin3, bin4, bin5, bin6 : CovPType;

De rv variabele van het type RandomPType is voor het genereren van willekeurige waarden. We hebben er maar één nodig, omdat we hetzelfde object kunnen gebruiken in elk proces waar we willekeurige waarden moeten genereren. De laatste coderegel declareert zes variabelen van het type CovPType .

We hebben zes dekkingsvariabelen gedeclareerd omdat we zes dekkingsdoelen zullen hebben, we zullen naar deze objecten verwijzen als "bakken". De gedeelde variabelen moeten worden geïnitialiseerd voordat ze kunnen worden gebruikt voor het verzamelen van dekkingsgegevens. Dit doen we door de AddBins . te bellen procedure op elk van de CovPType bakken.

    -- Set up coverage bins
    bin1.AddBins("Write while empty", ONE_BIN);
    bin2.AddBins("Read while full", ONE_BIN);
    bin3.AddBins("Read and write while almost empty", ONE_BIN);
    bin4.AddBins("Read and write while almost full", ONE_BIN);
    bin5.AddBins("Read without write when almost empty", ONE_BIN);
    bin6.AddBins("Write without read when almost full", ONE_BIN);

We leveren een tekenreeksbeschrijving van de dekkingsbak als de eerste parameter voor de AddBins procedure. Deze tekenreeks zal aan het einde van de simulatie opnieuw verschijnen wanneer we de statistieken voor elk van de dekkingsvakken afdrukken. Zoals u kunt zien aan de hand van de tekstbeschrijvingen, gaan we de bakken gebruiken om te controleren of er al dan niet zeer specifieke hoekgevallen zijn opgetreden.

AddBins is een overbelaste procedure die kan worden gebruikt voor het maken van meerdere scoreborden binnen de bin-variabelen. We zullen echter slechts één scorebord hebben dat aan elke bak is gekoppeld. Daarom leveren we de gemaksconstante ONE_BIN als een parameter voor de AddBins procedure. Dit initialiseert de CovPType variabelen met elk één bin. De scoreborden die door de bakken worden vertegenwoordigd, worden geacht gedekt te zijn wanneer de gebeurtenissen die ze controleren zich minstens één keer hebben voorgedaan.

Willekeurige invoer genereren

Laten we beginnen met het maken van het proces dat invoergegevens voor de TU Delft genereert. De ringbuffer FIFO is ontworpen om pogingen tot overschrijven en overlezen te negeren. Daarom kunnen we eenvoudig willekeurige gegevens schrijven in bursts van willekeurige duur. We hoeven er niet over na te denken of de TU Delft daadwerkelijk klaar is om de data op te nemen of niet.

  PROC_WRITE : process
  begin
    wr_en <= rv.RandSlv(1)(1) and not rst;

    for i in 0 to rv.RandInt(0, 2 * RAM_DEPTH) loop
      wr_data <= rv.RandSlv(RAM_WIDTH);
      wait until rising_edge(clk);
    end loop;
  end process;

De enige overweging die dit proces met zich meebrengt, is dat de DUT niet is gereset. We schakelen het schrijfinschakelsignaal willekeurig in of uit in de eerste regel van dit proces, maar het wordt alleen ingeschakeld als rst is '0' .

De volgende for-loop schrijft willekeurige gegevens naar de DUT voor een willekeurig aantal klokcycli, zelfs als het activeringssignaal niet actief is. We kunnen dit doen omdat de TU Delft verondersteld wordt de wr_data . te negeren poort tenzij de wr_en signaal is '1' . Na de for-loop keert het programma terug naar het begin van het proces, waardoor een nieuwe willekeurige schrijftransactie wordt geactiveerd.

Willekeurige uitlezingen uitvoeren

Het proces dat gegevens van de TU Delft leest, is vergelijkbaar met het schrijfproces. We kunnen willekeurig de rd_en . activeren signaal op elk moment omdat de DUT is ontworpen om leespogingen te negeren wanneer deze leeg zijn. De gegevens die verschijnen op de rd_data poort is niet echt gecontroleerd. Dit proces regelt alleen het leesactiveringssignaal.

  PROC_READ : process
  begin
    rd_en <= rv.RandSlv(1)(1) and not rst;

    for i in 0 to rv.RandInt(0, 2 * RAM_DEPTH) loop
      wait until rising_edge(clk);
    end loop;
  end process;

Gedragsverificatie

We zullen binnen onze testbank een gedragsmodel van de TU Delft construeren om het gedrag ervan te verifiëren. Dit is een bekende testbench-strategie. Eerst voeden we het gedragsmodel gelijktijdig met dezelfde input als de TU Delft. Vervolgens kunnen we de output van de twee vergelijken om te controleren of de TU Delft het juiste gedrag vertoont.

De afbeelding hierboven toont de basislay-out van zo'n testbank. Het gedragsmodel werkt parallel aan de TU Delft. We gebruiken het als blauwdruk om de outputs van de TU Delft te toetsen.

De testbank FIFO

We zullen een gekoppelde lijst gebruiken om het gedragsmodel te implementeren. Gelinkte lijsten kunnen niet worden gesynthetiseerd, maar ze zijn perfect voor testbanken. Misschien herinner je je de Hoe maak je een gekoppelde lijst in VHDL artikel als u een regelmatige lezer van deze blog bent. We zullen de code ervan gebruiken om het gedragsmodel voor de ringbuffer FIFO te implementeren.

package DataStructures is
   type LinkedList is protected
 
      procedure Push(constant Data : in integer);
      impure function Pop return integer;
      impure function IsEmpty return boolean;
 
   end protected;
end package DataStructures;

De pakketaangifte voor de Linked List FIFO wordt getoond in de bovenstaande code. Het is een beschermd type dat de drie functies heeft; Duw, knal en is leeg. Deze worden gebruikt om elementen toe te voegen aan en te verwijderen uit de FIFO, en om te controleren of er geen elementen meer in zitten.

  -- Testbench FIFO that emulates the DUT
  shared variable fifo : LinkedList;

Beveiligde typen zijn klasse-achtige constructies in VHDL. We zullen een object van de gekoppelde lijst maken door een gedeelde variabele te declareren in het declaratieve gebied van de testbench, zoals weergegeven in de bovenstaande code.

Het gedragsmodel

Om het gedrag van de ringbuffer FIFO volledig na te bootsen, declareren we twee nieuwe signalen die de uitgangssignalen van de DUT weerspiegelen. Het eerste signaal bevat de uitvoergegevens van het gedragsmodel en het tweede is het bijbehorende geldige signaal.

  -- Testbench FIFO signals
  signal fifo_out : integer;
  signal fifo_out_valid : std_logic := '0';

De code hierboven toont de verklaring van de twee uitgangssignalen van het gedragsmodel. We hebben geen speciale ingangssignalen nodig voor het gedragsmodel, omdat deze hetzelfde zijn als de signalen die zijn aangesloten op de TU Delft. We gebruiken signalen om de DUT-uitvoer na te bootsen, omdat we hiermee gemakkelijk dekkingsgegevens kunnen verzamelen, zoals we later in dit artikel zullen zien.

PROC_BEHAVIORAL_MODEL : process
begin
  wait until rising_edge(clk) and rst = '0';

  -- Emulate a write
  if wr_en = '1' and full = '0' then
    fifo.Push(to_integer(unsigned(wr_data)));
    report "Push " & integer'image(to_integer(unsigned(wr_data)));
  end if;
    
  -- Emulate a read
  if rd_en = '1' and empty = '0' then
    fifo_out <= fifo.Pop;
    fifo_out_valid <= '1';
  else
    fifo_out_valid <= '0';
  end if;
  
end process;

Het proces dat het gedragsmodel van de ringbuffer FIFO implementeert, wordt getoond in de bovenstaande code. Dit proces wordt geactiveerd bij elke stijgende flank van de klok, als het resetsignaal niet actief is.

Het gedragsmodel duwt een nieuwe waarde naar de testbench FIFO wanneer de wr_en signaal wordt bevestigd terwijl de full signaal is '0' . Evenzo werkt de leeslogica in het gedragsmodelproces door te luisteren naar de rd_en en empty signalen. De laatste wordt beheerd door de TU Delft, maar we zullen controleren of het werkt in het volgende proces dat we zullen maken.

De uitgangen controleren

Alle logica die verantwoordelijk is voor het controleren van de uitvoer van de TU Delft, wordt verzameld in een proces met de naam «PROC_VERIFY». We gebruiken assert-statements om te controleren of de outputs van de TU Delft overeenkomen met die van het gedragsmodel. Ook controleren we of de TU Delft en het gedragsmodel overeenkomen wanneer de FIFO leeg is.

De code voor het verificatieproces wordt hieronder weergegeven.

PROC_VERIFY : process
begin
  wait until rising_edge(clk) and rst = '0';
  
  -- Check that DUT and TB FIFO are reporting empty simultaneously
  assert (empty = '1' and fifo.IsEmpty) or
         (empty = '0' and not fifo.IsEmpty)
    report "empty=" & std_logic'image(empty) 
      & " while fifo.IsEmpty=" & boolean'image(fifo.IsEmpty)
    severity failure;

  -- Check that the valid signals are matching
  assert rd_valid = fifo_out_valid
    report "rd_valid=" & std_logic'image(rd_valid) 
      & " while fifo_out_valid=" & std_logic'image(fifo_out_valid)
    severity failure;

  -- Check that the output from the DUT matches the TB FIFO
  if rd_valid then
    assert fifo_out = to_integer(unsigned(rd_data))
      report "rd_data=" & integer'image(to_integer(unsigned(rd_data)))
        & " while fifo_out=" & integer'image(fifo_out)
      severity failure;
      report "Pop " & integer'image(fifo_out);
  end if;

end process;

Het proces wordt geactiveerd door de stijgende flank van de klok, zoals we kunnen zien aan de eerste coderegel. De DUT is een geklokt proces en de stroomafwaartse logica die is verbonden met de DUT zal naar verwachting ook synchroon zijn met het kloksignaal. Daarom is het zinvol om de uitgangen op de stijgende klokflank te controleren.

Het tweede codeblok controleert of de empty signaal afkomstig van de DUT wordt alleen bevestigd als de testbank FIFO leeg is. De TU Delft en het gedragsmodel moeten het er allebei over eens zijn dat de FIFO leeg is of niet om deze test te laten slagen.

Daarna volgt een vergelijking van de gelezen data geldige signalen. De TU Delft en het gedragsmodel moeten tegelijkertijd gegevens uitvoeren, anders is er iets mis.

Ten slotte controleren we of de uitvoergegevens van de DUT overeenkomen met het volgende element dat we uit de testbench FIFO halen. Dit gebeurt natuurlijk alleen als de rd_valid signaal wordt bevestigd, wat betekent dat de rd_data signaal kan worden gesampled.

Dekkingsgegevens verzamelen

Om de hoofdstroom van de testbench te regelen, zullen we een sequencerproces maken. Dit proces initialiseert de dekkingsvakken, voert de tests uit en stopt de testbank wanneer aan alle dekkingsdoelen is voldaan. De onderstaande code toont het volledige «PROC_SEQUENCER»-proces.

PROC_SEQUENCER : process
begin

  -- Set up coverage bins
  bin1.AddBins("Write while empty", ONE_BIN);
  bin2.AddBins("Read while full", ONE_BIN);
  bin3.AddBins("Read and write while almost empty", ONE_BIN);
  bin4.AddBins("Read and write while almost full", ONE_BIN);
  bin5.AddBins("Read without write when almost empty", ONE_BIN);
  bin6.AddBins("Write without read when almost full", ONE_BIN);

  wait until rising_edge(clk);
  wait until rising_edge(clk);
  rst <= '0';
  wait until rising_edge(clk);

  loop
    wait until rising_edge(clk);

    -- Collect coverage data
    bin1.ICover(to_integer(wr_en = '1' and empty = '1'));
    bin2.ICover(to_integer(rd_en = '1' and full = '1'));
    bin3.ICover(to_integer(rd_en = '1' and wr_en = '1' and
                           empty = '0' and empty_next = '1'));
    bin4.ICover(to_integer(rd_en = '1' and wr_en = '1' and
                           full = '0' and full_next = '1'));
    bin5.ICover(to_integer(rd_en = '1' and wr_en = '0' and
                           empty = '0' and empty_next = '1'));
    bin6.ICover(to_integer(rd_en = '0' and wr_en = '1' and
                           full = '0' and full_next = '1'));

    -- Stop the test when all coverage goals have been met
    exit when
      bin1.IsCovered and
      bin2.IsCovered and
      bin3.IsCovered and
      bin4.IsCovered and
      bin5.IsCovered and
      bin6.IsCovered;
  end loop;
  
  report("Coverage goals met");

  -- Make sure that the DUT is empty before terminating the test
  wr_en <= force '0';
  rd_en <= force '1';
  loop
    wait until rising_edge(clk);
    exit when empty = '1';
  end loop;

  -- Print coverage data
  bin1.WriteBin;
  bin2.WriteBin;
  bin3.WriteBin;
  bin4.WriteBin;
  bin5.WriteBin;
  bin6.WriteBin;
  
  finish;
end process;

Eerst initialiseren we de dekkingsbakobjecten door de AddBins . aan te roepen procedure op hen, zoals we al eerder in dit artikel hebben besproken. Nadat de reset is vrijgegeven, gaan we verder met het verzamelen van dekkingsgegevens. Op elke stijgende flank van de klok wordt de code binnen de lusconstructie uitgevoerd.

Het eerste codeblok in de lus is voor het verzamelen van dekkingsgegevens. We kunnen de ICover . bellen procedure op de bak om een ​​treffer te registreren op het dekkingspunt dat het vertegenwoordigt. Als we de integer-parameter 0 , heeft de oproep geen effect. Als we de integer-parameter 1 . gebruiken , telt dit als een treffer.

Er is slechts één «bak» in elk van de dekkingsbakobjecten, omdat we ze hebben geïnitialiseerd met de ONE_BIN constante. Deze enkele bak kan worden bereikt door te bellen naar ICover(1) . We kunnen een hit of miss op het dekkingspunt registreren door onze Booleaanse uitdrukkingen om te zetten in de gehele getallen 1 of 0 met behulp van de to_integer functie

Nadat de dekkingsgegevens zijn vastgelegd, controleren we of aan alle dekkingsdoelen is voldaan door de IsCovered te bellen. functie op alle bakken. Daarna verlaten we de cirkel als alle dekkingsdoelen zijn bereikt.

We zorgen ervoor dat de TU Delft leeg is voordat we de toets beëindigen. Om dit te bereiken, nemen we de controle over van de schrijf- en leesprocessen door de wr_en . te forceren signaal naar '0' en de rd_en signaal naar '1' .

Ten slotte drukken we statistieken af ​​voor hoe vaak elk dekkingsdoel is bereikt door de WriteBin . te bellen functie op elk van de dekkingsvakken. De finish trefwoord aan het einde van het proces zorgt ervoor dat de simulator de simulatie stopt.

De testbank draaien

U kunt het volledige ModelSim-project met alle VHDL-bestanden downloaden via het onderstaande formulier.

Nadat we het project hebben geladen door het do-bestand uit te voeren dat in de Zip zit, kunnen we de testbench uitvoeren door simpelweg «runtb» in de ModelSim-console te typen. De looptijd van de testbench is willekeurig omdat de dekkingsdoelen willekeurig worden bereikt. De testresultaten zijn echter reproduceerbaar omdat het eigenlijk een pseudo-willekeurige reeks is die wordt gebruikt.

We hebben geen seed in onze code geïnitialiseerd, wat betekent dat de standaard seed-waarde zal worden gebruikt voor de pseudo-willekeurige generator. Het is mogelijk om een ​​andere seed in te stellen door de InitSeed . te bellen procedure op de RandomPType object, zal dit een andere willekeurige reeks opleveren.

De console-uitgang

De uitvoer die naar de ModelSim-console is afgedrukt nadat we de opdracht «runtb» hebben gegeven, wordt hieronder weergegeven. Er zal veel willekeurig naar en van de testbank FIFO worden gepusht terwijl de simulatie loopt.

VSIM 2> runtb
# ** Warning: Design size of 15929 statements or 2 leaf instances exceeds
#             ModelSim PE Student Edition recommended capacity.
# Expect performance to be quite adversely affected.
# ** Note: Push 34910
#    Time: 790 ns  Iteration: 0  Instance: /ring_buffer_tb
...
# ** Note: Pop 37937
#    Time: 83100 ns  Iteration: 0  Instance: /ring_buffer_tb
# ** Note: Pop 13898
#    Time: 83110 ns  Iteration: 0  Instance: /ring_buffer_tb
# %% WriteBin: 
# %% Write while empty  Bin:(1)   Count = 2  AtLeast = 1
# 
# %% WriteBin: 
# %% Read while full  Bin:(1)   Count = 3  AtLeast = 1
# 
# %% WriteBin: 
# %% Read and write while almost empty  Bin:(1)   Count = 106  AtLeast = 1
# 
# %% WriteBin: 
# %% Read and write while almost full  Bin:(1)   Count = 1  AtLeast = 1
# 
# %% WriteBin: 
# %% Read without write when almost empty  Bin:(1)   Count = 1  AtLeast = 1
# 
# %% WriteBin: 
# %% Write without read when almost full  Bin:(1)   Count = 3  AtLeast = 1
#
# Break in Process PROC_SEQUENCER at C:/crv/ring_buffer_tb.vhd line 127

Statistieken voor alle dekkingsvakken worden afgedrukt wanneer aan alle dekkingsdoelen is voldaan. Sommige bakken zijn slechts één keer geraakt, terwijl één 106 keer is geraakt. Maar uiteindelijk is elke bak minstens één keer geraakt. Zo kunnen we weten dat alle gebeurtenissen waarvoor we dekkingsvakken hebben gedefinieerd, zijn getest en geverifieerd.

De golfvorm

Laten we de golfvorm eens bekijken om een ​​idee te krijgen van wat de testbank heeft gedaan. De afbeelding hieronder toont de golfvorm met de fill_count signaal weergegeven als een analoge waarde. De FIFO is vol als het spoor voor dit signaal bovenaan staat en leeg als het onderaan staat.

Zoals we aan de golfvorm kunnen zien, wordt de ringbuffer willekeurig gevuld en geleegd. Toch hebben we deze hellingen en dalingen niet expliciet geprogrammeerd in het vulniveau. Toch zien we een organisch ogend interactiepatroon met de TU Delft.

Meer over beperkte willekeurige verificatie

Beperkte willekeurige verificatie is een goede testbankstrategie wanneer de testvector te veel permutaties heeft om een ​​uitputtende test praktisch te laten zijn. De willekeurige interacties vertonen een natuurlijker gedrag dan een gerichte hoektest zou hebben gedaan, zonder in te boeten aan nauwkeurigheid.

We kunnen er zeker van zijn dat aan alle hoekgevallen is voldaan, zolang we de dekkingsgegevensverzameling maar correct hebben ingericht. Het extra voordeel is dat gerandomiseerde testen eerder zwakke punten in de TU Delft blootleggen waar je niet specifiek op test. Zolang je alle hoekgevallen kent, kun je er gerichte tests voor maken. Maar hoekgevallen worden gemakkelijk over het hoofd gezien, en dat is wanneer u kunt profiteren van de beperkte willekeurige verificatiemethode.

Dit artikel heeft slechts het oppervlak bekrast van wat u kunt doen met beperkte willekeurige verificatie. Ik raad aan om de documenten op de OSVVM GitHub-pagina te lezen om dieper op het onderwerp in te gaan.

Ik raad ook de Advanced VHDL-testbank- en verificatiecursus van SynthWorks aan, waar ik niet bij aangesloten ben. Ik heb echter de 5-daagse versie van deze fysieke cursus gevolgd. De cursus wordt gegeven door Jim Lewis, de voorzitter van de VHDL Analysis and Standardization Group (VASG). Al met al een geweldige investering voor elk bedrijf dat zijn VHDL-testbanken naar een hoger niveau wil tillen.


VHDL

  1. Cadans versnelt SoC-verificatie met miljard poorten
  2. Siemens voegt toe aan Veloce voor naadloze hardware-ondersteunde verificatie
  3. Project onderzoekt betrouwbare ontwerp- en verificatiestroom voor IoT-beveiliging
  4. Synopsys maakt multi-die-ontwerpen mogelijk met HBM3-IP en verificatie
  5. Toegangscontrole met QR, RFID en temperatuurverificatie
  6. De ongemakkelijke, onvoorspelbare en willekeurige kant van onderhoud
  7. Willekeurige getallen genereren in Java
  8. Java 8 - Streams
  9. Slant-Bed draaibank Functies Controle met verificatie graphics
  10. Differentiële isometrische verwerking en simulatieverificatie van high-speed PCB-ontwerp
  11. Het prestatieverificatieprogramma van CAGI voor roterende compressoren