Using Text Files During VHDL Simulation

VHDL provides a method for accessing files which is useful during simulation when the input stimuli cannot be easily described using conventional VHDL statements or when we want to log results. First, we must declare the file type. For example, if the file will contain text, then we must declare a file of type "string" - this requires the textio package which comes as part of VHDL's built-in libraries:

  1. use std.textio.all;
  2. architecture arctbench of tbench is
  3.   type textfile is file of string; -- file of text
  4.   type intfile is file of integer; -- file of integers
  5. begin

..once the file type is declared, we can declare a "file object" which uses that type:

  1. file myfile:text open write_mode is "logfile.txt";

This line of code can be better explained if broken down into its various parts:

  • myfile: the file object name
  • text: the file type
  • write_mode: the access mode
  • logfile.txt: the file logical name

The first thing to notice is that the file seems to have 2 names - the file object name is the one that you use to reference the file in your VHDL code, the file logical name is the name that the operating system (Windows, Linux, etc) uses for the file. The access mode specifies how the file will be used and has 3 possible values:

  • read_mode: reads from an existing file.
  • write_mode: creates an empty file to be written.
  • append_mode: data is added to the end of an existing file or a new one is created.

Reading from files

Now that we know how declare a file for reading, we need to know how to read the values from the file. This is done by using 2 procedures available from the textio package:

  • readline (filename, linename) : reads a line from the file filename and stores it in a variable of type line called linename.
  • read (linename, variablename) : reads an element from the line linename and stores it to variablename.'s an example of how to use them:

  1. use std.textio.all;
  2. .
  3. .
  4. architecture arctbench of tbench is
  5.   -- file declaration
  6.   -- type "text" is already declared in textio library
  7.   file datainfile : text open read_mode is "datain.txt";
  8. begin
  9.   process
  10.     -- file variables
  11.     variable vdatainline : line;
  12.     variable vdatain : bit_vector(7 downto 0);
  13.   begin
  15.     for i in 0 to 7 loop          -- read 8 lines
  16.       wait until (s_clk'event and s_clk = '1');
  17.       readline (datainfile, vdatainline);        -- read line from input file
  18.       read (vdatainline, vdatain);                -- read the 1st 8 bits from line
  19.       datainout <= to_stdlogicvector(vdatain);    -- send to data input
  20.   end loop;
  21. end process;

..there are some restrictions on the type of variable that can used with the read and write procedures - they must be one of the following:

  • bit
  • bit_vector
  • boolean
  • character
  • integer
  • real
  • string
  • time

Writing to files

Writing to a file is very similar to reading, first the file must be declared with the access mode set to either write_mode or append mode, then each line must be created and then written to the file. There are two procedures in the textio library to do this

  • writeline (filename, linename) : writes a line called linename to a file with object name filename.
  • write (linename, variablename) : writes an element stored in variablename to the line linename.

In this example, then value of dataout is written into a file with logical name dataoutfile:

  1. process (clk)
  2.   variable vdataout : bit_vector(7 downto 0);  -- variable written to line
  3.   variable vdataoutline : line;                -- line variable written to file
  4. begin
  5.   if (datavalid = '1') then
  6.     vdataout := to_bitvector(dataout);        -- convert dataout to bit_vector
  7.     write (vdataoutline, vdataout);           -- write variable to line
  8.     writeline (dataoutfile, vdataoutline);    -- write line to file
  9.   end if;
  10. end process;

A text functions library

The VHDL procedures for reading and writing files are a bit cumbersome to use. Stefan Doll has written a library that contains functions that make it much easier to read & write files. I have added a couple of extra functions; hchar_to_slv which converts a single hexadecimal character to a 4-bit std_logic_vector and printt which prints a string to a file with the current simuation time appended to the end - this makes it easy to correlate the printed message to the simulation waveforms.

The library can be downloaded here.

To use this library, just declare it in the usual way - it contains 2 packages: text_util and conv_util:

  1. library sim_util;
  2. use sim_util.text_util.all;
  3. use sim_util.conv_util.all;