Skip to content

VHDL · Chapter 14.6 · Testbench Development

File I/O with textio

Hard-coding every stimulus value in the testbench source does not scale; real verification keeps test vectors and golden results in files. The standard textio package, plus the std-logic textio helpers for logic values, gives a testbench file I/O through two objects: a file you open in read or write mode, and a line, which is a buffer you parse from or build up. You read a line and then read its fields to pull in a stimulus vector, you write fields into a line and then write that line to emit a result or log entry, and end-of-file tells you when the input is exhausted. This is the foundation of data-driven testing, where stimulus and expected results live in files, so adding cases means editing data rather than code. This lesson covers opening files, parsing and building lines, end-of-file handling, and hex and logic-value I/O, all simulation-only.

Foundation14 min readVHDLtextioFile I/OTestbenchData-DrivenVerification

1. Engineering intuition — keep the test data outside the code

A test with three vectors can hardcode them; a test with three thousand cannot. The scalable pattern is to put the data — input vectors and expected outputs — in a file, and have the testbench read it. Now the harness is generic ("for each line: apply inputs, check output") and the cases are just rows you add to a text file, even generated by a script. textio is how VHDL reads and writes those files: pull a line in, parse the numbers out; or format some values, push the line out to a results log. The mental model is line-oriented — you always work a line at a time, reading fields from it or writing fields into it.

2. Formal explanation — file, line, and the read/write operations

textio_basics.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
use std.textio.all;                 -- file, line, readline/read, writeline/write, endfile
use ieee.std_logic_textio.all;      -- read/write for std_logic types (hex/binary); in 1164 since 2008
 
-- FILE declarations with an open MODE:
file vec_file : text open read_mode  is "stimulus.txt";   -- input vectors
file log_file : text open write_mode is "results.txt";    -- output log
 
read_proc : process
  variable l        : line;                 -- a line buffer
  variable a, b     : std_logic_vector(7 downto 0);
  variable expected : std_logic_vector(8 downto 0);
begin
  while not endfile(vec_file) loop          -- until input is exhausted
    readline(vec_file, l);                  -- pull one line into the buffer
    hread(l, a);                            -- parse hex fields from the line, in order
    hread(l, b);
    hread(l, expected);
    -- ... apply a,b to the DUT, check against expected (14.4) ...
  end loop;
  wait;
end process;

The two objects are file (opened read_mode/write_mode) and line (a parse/build buffer). You readline to fetch a line then read/hread to extract fields in order; you write/hwrite fields into a line then writeline to emit it; endfile detects exhaustion. std_logic_textio provides read/write (and hex hread/hwrite) for std_logic types.

3. Production usage — read stimulus, write a results log

file_driven_test.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- Each input line:  "AA BB 165"  → a, b, expected (hex). Each result line logged to results.txt.
run : process
  variable il, ol   : line;
  variable a, b     : std_logic_vector(7 downto 0);
  variable exp      : std_logic_vector(8 downto 0);
begin
  while not endfile(vec_file) loop
    readline(vec_file, il);
    hread(il, a); hread(il, b); hread(il, exp);     -- parse the stimulus row
    drive_op(clk, dut_a, dut_b, dut_valid, a, b);   -- apply to DUT (14.2)
    wait until result_valid = '1';
 
    -- BUILD an output line and emit it.
    write(ol, string'("a=")); hwrite(ol, a);
    write(ol, string'(" got=")); hwrite(ol, dut_sum);
    write(ol, string'(" exp=")); hwrite(ol, exp);
    writeline(log_file, ol);                         -- one result line per vector
  end loop;
  wait;
end process;

What hardware does this become? Nonetextio is simulation-only (synthesis cannot read or write host files). Its payoff is a data-driven testbench: the harness logic is fixed, and the test content lives in stimulus.txt / results.txt. You expand coverage by adding lines, diff the results file against a golden file to score the run, and even generate vectors from a script or a higher-level model. Building the output line shows the dual of parsing — write/hwrite append fields, writeline flushes the line to the file.

4. Structural interpretation — file in, parse, drive, log out

stimulus file read and parsed to drive the DUT, results written back to a filereadlinevectorswritelinestimulus.txtvectors + expectedreadline + readparse fieldsDUT + checkdrive / compareresults.txtwriteline log → diff golden12
textio makes a testbench data-driven. A stimulus file is read a line at a time with readline; read/hread parse the line's fields into stimulus and expected values, which drive and check the DUT. Results are formatted with write/hwrite into a line and emitted with writeline to a results file, which can be diffed against a golden file to score the run. endfile detects when the input is exhausted. File and line are the two objects; everything is simulation-only. This is a data-flow structure for file-driven testing, captured by a diagram rather than a waveform.

5. Why this is structural, not timing

File I/O with textio is a data-flow concern — lines in, fields parsed, results formatted and written — so the pipeline diagram above is the right picture, not a waveform. Its effect is on test content and bookkeeping, not signal behavior; the actual DUT waveforms come from the stimulus the file feeds (covered in the stimulus and self-checking lessons). Because it is simulation-only and host-side, it has no hardware timing at all. The value is structural: separating the harness from the data so tests scale by editing files.

6. Debugging example — the parse that drifted from the file format

Expected: each line's fields load into the right variables. Observed: values are shifted, wrong, or a read error/endfile surprise, even though the file "looks right." Root cause: the read order or radix did not match the file format — fields read in the wrong order, a decimal read used where the data is hex (or vice versa), an extra/missing field per line, or the file not opened in the correct mode. A line is parsed left-to-right by successive read/hread calls, so the call sequence must mirror the columns exactly. Fix: make the read/hread calls match the file's column order and radix precisely, read the right number of fields per line, and open files in the proper mode (read_mode/write_mode). Engineering takeaway: textio parsing is positional and typed — line up the read/hread calls with the file's exact field order and radix, or the data silently lands in the wrong variables.

match_the_format.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- BUG: file has HEX fields but parsed as decimal, and in the wrong order.
-- readline(f,l); read(l, b_dec); read(l, a_dec);   -- decimal read on hex data, swapped
-- FIX: hex read, columns in the file's actual order.
readline(f, l);  hread(l, a);  hread(l, b);  hread(l, expected);

7. Common mistakes & what to watch for

  • Parse order/radix mismatch. read/hread calls must match the file's column order and number base exactly; otherwise fields land wrong.
  • Wrong open mode. Open input read_mode, output write_mode; using the wrong mode fails or truncates.
  • Ignoring endfile. Loop while not endfile(f); reading past end is an error.
  • Forgetting std_logic_textio (pre-2008). std_logic/hex line I/O needs it; in VHDL-2008 it is in std_logic_1164.
  • Trying to synthesize file I/O. textio is simulation-only; never put it in RTL.

8. Engineering insight & continuity

textio gives a testbench file I/O through file and line objects: readline/read to parse stimulus and expected values from a file, write/writeline to emit results and logs, endfile to detect the end — with std_logic_textio for hex/std_logic fields, all simulation-only. This separates the harness from the data, the essence of scalable testing. It leads directly into the methodology that uses it: the next lesson, Data-Driven and Vector-Based Testing — structuring whole test suites around files of vectors and golden results.