an application note by Stephen Tang of the Interactive Audio Manipulation Processor (iAMP) Team
std_logic
and std_ulogic
Data Types
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.
std_logic
and std_ulogic
Data TypesAccording 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) |
U | 0 | 55 |
X | 1 | 58 |
0 | 2 | 30 |
1 | 3 | 31 |
Z | 4 | 5A |
W | 5 | 57 |
L | 6 | 4C |
H | 7 | 2D |
- | 8 | 63 |
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.
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.
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.
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.
Once this process is complete, you will have a binary file ready to use. My file is adcsamples.binary.
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.
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