Skip to content
VLSI Mentor

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 filestimulus.txtvectors + expectedreadline + readparse fieldsDUT + checkdrive / compareresults.txtwriteline log → diff goldenreadlinevectorswriteline12
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.

Standards & specifications

Governing standard
IEEE Std 1076 (VHDL)(opens IEEE in a new tab)

Defines the VHDL language — types, the simulation cycle, and the semantics a conforming analyser and simulator must implement. Synthesis restrictions and vendor coding rules are tool behaviour, not language rules.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of VHDL Testbenches — Stimulus, Checking & Self-Checking Design.