Using Binary Files in VHDL Test Benches


an application note by Stephen Tang of the Interactive Audio Manipulation Processor (iAMP) Team


Contents


Why Binary Files?

The inspiration for this application note came from Gunthrope, O'Reilly, and Lewis' application note, TestBenches Using File I/O under VHDL. I recommend that you read that document before this one, since I make use of concepts that are explained there.

The GOL appnote provides useful information on using ASCII text files for test benches. From a text file, one can easily extract character strings and integers. Similarly, it is easy to write such information to a text file.

However, if you wish to read/store logic vector information from/to a text file, the process is not as simple. As you may be aware, the VHDL language is very strongly typed, which prevents you from using one data type as a stand-in for another (this is in contrast to C, where char and int variables can both be used to store character literals, since the ASCII character set is essentially an enumerated list of integers). The IEEE Standard 1164 offers conversion functions and cast-to-type operators for closely related data types, such as integers and real numbers, or std_logic and std_ulogic, but it does not offer any conversion routines for unrelated data types, such as characters and std_logic.

The aforementioned file I/O appnote contains an example code listing where several conversion functions are used to extract information from a text file into a line variable, then to convert the data in the line variable into an integer, then to convert the integer into a std_logic_vector. Though I have not tried, I suspect that if the text file contained std_logic values such as 'Z', 'X', or 'U', the conversion from text to integer would have failed. As far as I know, there are no standard routines to convert character data types directly to std_logic. Hence, you would have to write your own conversion routines. While this in itself is not a difficult task, why bother if you don't have to?

And in fact, you don't have to. The solution is to store the std_logic information in a binary file. This appnote describes how you can do this.


About the std_logic and std_ulogic Data Types

According to IEEE Standard 1164, the std_ulogic data type is defined as an enumeration type:

  type std_ulogic is (
    'U',  -- Uninitialized
    'X',  -- Forcing unknown
    '0',  -- Forcing zero
    '1',  -- Forcing one
    'Z',  -- High impedance
    'W',  -- Weak unknown
    'L',  -- Weak zero
    'H',  -- Weak one
    '-'   -- Don't care
  );

std_logic is defined similarly. Since an enumeration is a way of assigned meaningful labels to a set of numbers, it follows that 'U' corresponds to a numerical '0', 'X' to a numerical '1', '0' to a numerical '2', etc.

The problem with creating a text file containing strings that represent standard logic vectors is that the strings contain characters. That is, if you enter the vector "001X", the file will actually contain the bytes $30, $30, $31, and $58, which are the values that the ASCII characters '0', '1', and 'X' correspond to. The value $58 for the character 'X' is certainly not equal to $01, the value to which the enumerated std_ulogic 'X' is assigned.

We therefore need to map ASCII values to standard logic values:

std_logic value enumerated value ASCII value (hex)
U055
X158
0230
1331
Z45A
W557
L64C
H72D
-863

But how do we enter byte values from 0 through 8 into a file? The lowest byte value of any ASCII character is the space, which has the value $20. Entering non-ASCII bytes into a file is something that most text editors cannot do. A hex editor is required. If you know all about hex editors, you can skip the next two sections.


Getting a Hex Editor

The first step is get a hex editor program. Unfortunately, none of the UNIX or PC labs in the EE department have any hex editors installed. Fortunately, the Linux labs, CEB548A, CEB344, and CEB548 do. Try running ghex or khexedit from the command line (they're in /usr/bin, so they should already be in your path). If you're more of a GUI person, you can access them from the menus Applications->GHex and KDE menus->Utilities->Hex Editor on the Gnome panel (assuming you haven't changed the default panel settings).

If you're a Linux user, your distribution will almost invariably come with at least one hex editor. Given the popularity of KDE and Gnome, you will likely have either khexedit or ghex already installed. For Windows users, I recommend Ultra Edit, an excellent shareware programmer's editor that features a hex edit mode. Even if you aren't going to be editing binary files, get it anyway for the many programmer-friendly features.


Using a Hex Editor

Hex editors are pretty simple. The screenshot below is of GHex, but most hex editors have the same basic interface. There is a main window pane that represents the contents of the file being edited as a sequence of bytes, with each byte shown in hexadecimal. To the right of the main pane is a text pane that shows the ASCII characters that correspond to each byte shown in the main pane. If a byte falls outside of the range of printable characters, that byte is shown as a "." in the righthand pane. In the screenshot, the byte highlighted by the edit cursor is $0A, the carriage return character. If you click in the main pane, you can edit the contents of the file by typing a number or the characters "a" through "f". Clicking ing the right pane allows you to edit the file text-editor style. Usually hex editors work in overwrite mode, though some may allow you to insert data rather than just overwriting what's already there.

screenshot of GHex


Creating a Binary Data File

Here I will walk through the steps of creating a binary data file that contains std_logic values.

The easiest way to start is to create your data file with a text editor. I wanted a set of 24-bit vectors to supply my test bench with, so I created the file adcsamples.txt, which contains one vector per line.

Next, contatenate all the lines in the file into a single line. This will get rid of all the carriage return characters except the one at the end of the file. adcsamples.joined.txt shows this.

Remember that your file contains ASCII data right now. We must now open the file in a hex editor and perform a search-and-replace for every ASCII character. The screenshot below shows a search-and-replace dialog in GHex, in which the character '0' is being replaced by $02, the std_logic enumerated value for the logic level '0' -- see the above table.

replacing the character '0' with the digit 2

Once this process is complete, you will have a binary file ready to use. My file is adcsamples.binary.


Using the Data File in VHDL

We're almost done. In the VHDL test bench, we need three things: a signal to hold the logic vector, a variable to hold the logic vector as it is read from the file, and a file variable to point to the file that contains the logic vectors:

  signal SampleFromADC: std_logic_vector(SAMPLE_WIDTH-1 downto 0);
  variable SampleFromFile: std_logic_vector(SAMPLE_WIDTH-1 downto 0);
  file ADCsampleFile: std_logic_vector_file is "adcsamples.binary";

We can then use the following lines of code to write the data into a signal:

  read(ADCsampleFile, SampleFromFile);
  SampleFromADC <= SampleFromFile;

To put things in context, here is a complete test bench in which I use the concepts described in this app note.


References

Jason Gunthrope, Darren O'Reilly, and Ryan Lewis, TestBenches Using File I/O under VHDL.

Peter Ashenden, The Student's Guide to VHDL, Morgan Kaufmann Publishers, Inc., San Franciso, CA, 1998, p. 42.


document last modifed 2000 04 12

Interactive Audio Manipulation Processor Team - Todd Carter, Daniel Ross, Stephen Tang

send feedback to Stephen Tang