VHDL-testbenches aansturen vanuit externe stimulus-bestanden met TEXTIO
Stimulusdata lezen uit een extern bestand is een krachtige manier om een Device-Under-Test (DUT) in VHDL te sturen. Door een reeks signaalwaarden en simulatiestijden in een platte-tekstbestand te scripten, kunnen ontwerpers snel testpatronen wisselen zonder de testbench-logica te wijzigen. Dit artikel, de tweede in een reeks over VHDL-bestandstoegang, demonstreert hoe je een stimulusbestand leest met de TEXTIO bibliotheek en de waarden toepast op een 4-input multiplexer.
Testcase Overzicht
De DUT is een standaard, asynchrone 4-naar-1 multiplexer met 8-bit datawoorden. De testbench voert geen uitgangsverificatie uit — het stuurt slechts de invoeren aan zodat de waveform handmatig kan worden onderzocht. De entiteitsdeclaratie wordt hieronder ter referentie herhaald.
entity mux_4 is port( din_0 : in unsigned(7 downto 0); din_1 : in unsigned(7 downto 0); din_2 : in unsigned(7 downto 0); din_3 : in unsigned(7 downto 0); sel : in unsigned(1 downto 0); dout : out unsigned(7 downto 0)); end entity;
Signalen die verbinden met de DUT worden gedeclareerd in de testbench-architectuur en geïnstantieerd met het label DUT:
signal din_0 : unsigned(7 downto 0); signal din_1 : unsigned(7 downto 0); signal din_2 : unsigned(7 downto 0); signal din_3 : unsigned(7 downto 0); signal sel : unsigned(1 downto 0); signal dout : unsigned(7 downto 0); DUT: entity work.mux_4(rtl) port map ( din_0 => din_0, din_1 => din_1, din_2 => din_2, din_3 => din_3, sel => sel, dout => dout );
Het Stimulusbestand Ontwerpen
Hoewel veel formaten mogelijk zijn, illustreert het onderstaande voorbeeld een duidelijke, menselijk-leesbare layout. Elke regel vertegenwoordigt een simulatiestap en bevat:
- wait_time – vertraging vanaf de vorige stap (bijv.
10 ns) - sel – 2-bit selectorwaarde
- din_0 tot din_3 – 8-bit datawaarden in hexadecimaal
- Optionele trailing commentaar beginnend met
#voor console-uitvoer
Commentaar dat een regel begint wordt door de testbench genegeerd; commentaar dat een dataset volgt wordt geprint naar de simulator-console.
# Kolom beschrijving: # wait_time | sel | din_0 | din_1 | din_2 | din_3 # Optionele console printout 0 ns 0 AA BB CC DD # Initiële waarden instellen 10 ns 1 AA BB CC DD # Testen door selector-signaal te wijzigen 10 ns 2 AA BB CC DD 10 ns 3 AA BB CC DD 10 ns 3 A1 B1 C1 D1 # Testen door alle data-invoeren te wijzigen 10 ns 3 A2 B2 C2 D2 10 ns 3 A3 B3 C3 D3 10 ns 3 00 00 00 D2 # Alle niet-geselecteerde invoeren wijzigen 10 ns 3 01 02 03 D2 10 ns 3 11 22 33 D2 1 ns 0 CC DD EE FF # Alle invoeren snel wijzigen 1 ns 1 DD EE FF CC 1 ns 2 EE FF CC DD 1 ns 3 FF CC DD EE 10 ns 0 00 00 00 00 # Simulatiestop
Het Bestand Lezen met TEXTIO
Hieronder is het kernproces dat het stimulusbestand opent, elke regel parst, waarden toewijst aan de DUT-invoeren, en commentaar afhandelt. Het voorbeeld veronderstelt een goed geformatteerd bestand — één spatie scheidt kolommen, en het # teken wordt gevolgd door een enkele spatie.
PROC_SEQUENCER : process file text_file : text open read_mode is "stimulus.txt"; variable text_line : line; variable ok : boolean; variable char : character; variable wait_time : time; variable selector : sel'subtype; variable data : dout'subtype; begin while not endfile(text_file) loop readline(text_file, text_line); -- Lege regels en single-line comments overslaan if text_line.all'length = 0 or text_line.all(1) = '#' then next; end if; read(text_line, wait_time, ok); assert ok report "Read 'wait_time' failed for line: " & text_line.all severity failure; hread(text_line, selector, ok); assert ok report "Read 'sel' failed for line: " & text_line.all severity failure; sel <= selector; hread(text_line, data, ok); assert ok report "Read 'din_0' failed for line: " & text_line.all severity failure; din_0 <= data; hread(text_line, data, ok); assert ok report "Read 'din_1' failed for line: " & text_line.all severity failure; din_1 <= data; hread(text_line, data, ok); assert ok report "Read 'din_2' failed for line: " & text_line.all severity failure; din_2 <= data; hread(text_line, data, ok); assert ok report "Read 'din_3' failed for line: " & text_line.all severity failure; din_3 <= data; wait for wait_time; -- Trailing commentaar naar console printen, indien aanwezig read(text_line, char, ok); -- Verwachte newline overslaan read(text_line, char, ok); if char = '#' then read(text_line, char, ok); -- Verwachte newline overslaan report text_line.all; end if; end loop; finish; end process;
Simulatie-uitvoer
Wanneer uitgevoerd in ModelSim toont de console de trailing comments samen met de cumulatieve simulatiestijd. Het volgende fragment toont de reeks geprinte notities:
# ** Note: Setting initial values # Time: 0 ns Iteration: 1 Instance: /file_stim_tb # ** Note: Testing by changing the selector signal # Time: 10 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Testing by changing all data inputs # Time: 40 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Changing all unselected inputs # Time: 70 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Changing all inputs fast # Time: 91 ns Iteration: 0 Instance: /file_stim_tbf # ** Note: Simulation stop # Time: 104 ns Iteration: 0 Instance: /file_stim_tb # Break in Process PROC_SEQUENCER at file_stim_tb.vhd line 98
De waveform geproduceerd door de testbench spiegelt de timing en datawaarden uit het bestand, wat ontwerpers in staat stelt het DUT-gedrag visueel te verifiëren.
Belangrijkste Punten
- Externe stimulusbestanden geven ontwerpers fijnmazige controle over testreeksen zonder testbench-code te wijzigen.
TEXTIOgebruiken houdt de testbench beknopt, maar vereist gedisciplineerde bestandsformattering.- Altijd een zelf-controlemechanisme opnemen — ofwel door te vergelijken met een behavioraal model of door verwachte uitvoeren in het stimulusbestand in te sluiten.
Door het bovenstaande voorbeeld te volgen, kun je de volledige flexibiliteit van VHDL's TEXTIO benutten om complexe testscenario's aan te sturen terwijl je een schone, onderhoudbare testbench-structuur behoudt.

VHDL
- Driehoekige vijl uitgelegd: ontwerp, toepassingen en onderhoud
- Digitale Handtekeningen Gebruiken om Binaire Bestandsintegriteit te Verifiëren op Linux
- C# using-statements: imports, aliasen en static directives
- C Bestandsbehandeling: I/O onder de knie krijgen met fopen, fprintf, fread en fseek
- C Header-bestanden begrijpen: Typen, gebruik en best practices
- FPGA Block RAM initialiseren vanuit tekstbestanden met VHDL's TEXTIO-bibliotheek
- Een self-checking testbench in VHDL bouwen – Een praktische gids
- Verilog File I/O onder de knie: Openen, Lezen, Schrijven en Sluiten
- Python JSON: Encoding, Decoding en Bestandsafhandeling – Een Praktische Gids
- Java-bestandsbewerkingen onder de knie krijgen met java.io – Aanmaken, lezen, schrijven en verwijderen
- Bestanden Lezen in Java met BufferedReader – Een Praktische Gids met Voorbeelden