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