VHDL coding tips and tricks: VHDL: Reading and Writing Real Numbers From a File

Wednesday, March 31, 2010

VHDL: Reading and Writing Real Numbers From a File

    If you want to test your VHDL design with a large number of inputs, then its not efficient or reader-friendly to put all the inputs directly into your testbench code. One option is to store the inputs in a text file and let the testbench read the contents of it as needed. Similarly it makes sense to write the outputs of your design to a file, which can be read with another software, lets say Matlab, for verification. 

      There are lot of ways in which this can be done. Each project probably requires a different approach. In this example, I have one file 1.txt where few real real numbers are saved. The example code reads each line from the input file(1.txt), extracts the real number from the read line and writes to another file, 2.txt, in a specific format.

Let me share the VHDL code for this.

Reading and writing real numbers from a file:


--include this library for file handling in VHDL.
library std;
use std.textio.all;  

--entity declaration
entity filehandle is
end filehandle;

--architecture definition
architecture Behavioral of filehandle is

--data read from the 1.txt file.
signal dataread : real;

begin

--file read and write process
read_write : process
    file read_file : text is in  "1.txt";   --declare input file
    file write_file : text is out  "2.txt";   --declare output file
    variable read_line, write_line : line; --'line' declarations
    variable data_read1 : real;
begin
    --as long as there is a line to read from the file, we will read one line
    --from 1.txt and write to file 2.txt as per the specified format.
    if (not endfile(read_file)) then   --checking the "END OF FILE" is not reached.
        --reading a line from the file and putting it in a variable 'read_line'.
        readline(read_file, read_line);
        --reading the data from the line and putting it a variable 'data_read'.
        read(read_line, data_read1);
        --assign to a signal so as we can see it in the simulation waveform
        dataread <= data_read1;   

        --write a 'line' to the variable 'write_line'. Function format is as follows:
        --write(linenumber,value(real type),justified(side),field(width),digits(natural));
        write(write_line, data_read1, right, 16, 4);
        write(write_line, data_read1, right, 16, 8);
        --write line to external file pointed by 'write_file'.
        writeline(write_file, write_line);
        write(write_line, data_read1, left, 16, 4);
        write(write_line, data_read1, left, 16, 8);
        --write line to external file pointed by 'write_file'.
        writeline(write_file, write_line);
    else
        wait;  --end of testing.
    end if;
    wait for 10 ns;
end process read_write;

end Behavioral;

Contents of the Files:


The contents of files 1.txt and 2.txt are shown below. The format of the text files are also indicated in the image. 

To simulate the code in modelsim or any other tool, simply create a file named 1.txt with the following contents in it, in the same directory as the VHDL code.
1.0
2.3
4.5
6.5
8.0



How does this work?


    After reading each line from the text file, I write two lines into the output file. First line is in right justified and second one is in left justified format. How many places need to placed after the decimal point is specified by the last argument in the write function. The total width of each number is specified by the second last argument. 

    endfile() is a function which is used to check whether the end of the file is reached. It returns a '1' when the end of a file is reached while reading.

    The data from the file cannot be read directly into a signal. That is why I have first read it into a variable and then assigned it to a signal. This helps us to see the values in the simulation waveform.

The textio.vhd package offers the following data types:
type LINE is access STRING;  -- A LINE is a pointer to a STRING value
type TEXT is file of STRING; -- A file of variable-length ASCII records.
type SIDE is (RIGHT, LEFT);   -- For justifying output data within fields.
subtype WIDTH is NATURAL;     -- For specifying widths of  output fields.

    textio also offers a large number of functions to read or write to a file. You can see the list of all available functions and the arguments used here.

Note :- One advantage of file handling in VHDL is that, you can test a large number of input combinations for checking the integrity of your design. Large number of input combinations can be automatically generated and saved into a file, and then read using the testbench. 

29 comments:

  1. hi,
    I tried same approach to read and write file..
    my compiler setting is for vhdl93
    error msg was smthing like : this is for vhdl87

    wat i came to know is that in vhdl93 the way to read and write file is different(ref: appendix of Parry),,
    can u plz tell us that hw to do it for vhdl93 as part of my design can only be compiled using vhdl93 only,,
    thanks for writing great posts

    ReplyDelete
  2. @hank : check this link now,for the file reading and writing codes.I will update my blog with a relevant post later on the same topic.
    http://eesun.free.fr/DOC/vhdlref/refguide/language_overview/test_benches/reading_and_writing_files_with_text_i_o.htm

    ReplyDelete
  3. hi,,
    thanks for the nice link.
    I have one more doubt..
    watever literature i saw on this topic..most of them have one thing common: a part of code is with the rising edge and another part is with the falling edge..like in ur above example u r doing writitng on falling edge..
    why is it happening dis way??plz explain..
    I was planning something in which i can read a file and apply those i/p directly on one of my ports ..the whole thing on rising edge only..
    suggest smthing..

    ReplyDelete
  4. Dont worry about the rising and falling edge thing. Its just that I am waiting for some time for updating the signals. Read -> wait for some time -> the write.

    check the code in the new link. It doesnt require any thing like that. Only thing you have to make sure is that, value written to the file is proper.You can do it in whichever way you want.I introduced here a half clock cycle delay.If you want you can use one whole clock cycle delay.

    ReplyDelete
  5. very nice blog..
    how to make the comparison. Read -> Process -> Write. For example: if the files 1.txt contains:
    0
    1
    2
    3
    4
    5
    with the formula if the input >= 3 then the output = 5 else the output = 0
    i want to make the output file 2.txt be :
    0
    0
    0
    5
    5
    5

    I always fail when modifying the above program, whether it's because if statemens I still do not know.
    thankyou if you want to help..

    ReplyDelete
  6. hii.. this is very helpful link, thanx for your information. I've tried several ways to get results like I want. for example, by using the following code:
    ...
    signal X : integer :=3;
    ...
    if (endoffile = '0') then
    dataread =0 when dataread <=X else dataread =5;
    write(outline, dataread, right, 3, 1);
    linenumber <= linenumber + 1;
    else
    null;
    end if;

    what's wrong with my structure code. command error on modelsim -> near "=": expecting <= or :=

    ReplyDelete
  7. @rino : You can simply modify the above program to get what you want(comparison). Read an element.And inside a if condition write whatever value you want to write to the other file.
    If you need help with your projects contact me.

    ReplyDelete
  8. OK..
    i'm finished my project with comparison. the problem for how to make the comparison just if condition. same with you said. thanx for guide. i like this blog

    ReplyDelete
  9. Hello, I'm Korean Student studying VHDL.
    Sorry for my english....

    I'm making Drum loop machine for my term project.
    It loads wav files as drum beat from sd card then play it.

    so I want to use SD Card
    But I can't find any appropriate example or solutions....

    May I borrow your hand???

    ReplyDelete
    Replies
    1. Hi,

      Thanks for this interesting and practical VHDL example. I spend a lot of my time at work writing VHDL components and I'm always looking for better ways of testing them. I have previously discounted text file driven testing because of the complexities of handling strings and files in the language, however your example makes it look quite simple!

      I look forward to reading more posts in the future

      Chris, www.beesnotincluded.com

      Delete
  10. hi
    how we can simulate this program..
    can you tell me procedure what i have to write in signal and wave form window...
    regards...

    ReplyDelete
    Replies
    1. you dont need to create a waveform.. simply click on "simulate".

      Delete
    2. Hi vipin,

      I click the simulate but the output file is empty although i did set the input file just follow the code..

      Delete
  11. hi....wher to store input and output file prior to simulating??????

    ReplyDelete
    Replies
    1. store it in text files. the name of the file names are given in the code.

      Delete
  12. Where on my computer do I save the text file? Because whenever i try to simulate the code I get the following error:

    ** Error: (vsim-7) Failed to open VHDL file "1.txt" in rb mode.
    #
    # No such file or directory. (errno = ENOENT)
    # Time: 0 ns Iteration: 0 Instance: /read_file

    Please what do I do to solve this problem?

    ReplyDelete
  13. hii i want to read 65536 pixel values how to read it? this wil read?? for abve tsst bench?

    type ram2 is array (1 to 65536) of integer;
    signal pixel:ram2;

    process(clk,rst)
    begin

    if (rst='1') then
    temp<=0;
    if (clk'event and clk='1') then
    for i in 1 to 65535 loop
    pixel(i) <= conv_integer(datain);

    end loop;
    end if;
    end if;

    end process;

    ReplyDelete
  14. I want know how to write VHDL code for ASCII to Binary and vice-versa code. help me....

    ReplyDelete
  15. Hi,

    Thanks for the post. I want to write to a text file which isn't empty in my VHDL testbench without losing that data. every time that I do that it will start writing from the first line and clear the whole previous data. Could you please tell me if its possible?

    Thanks

    ReplyDelete
  16. In which directory should the .txt files be stored?

    ReplyDelete
  17. Hi, I tried to compile this VHDL program, but I have an error in this line :
    signal dataread : real;

    The error message is :
    Error (10414): VHDL Unsupported Feature error at filehandle.vhd(14): cannot synthesize non-constant real objects or values

    How can we fix this error please?

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. Hey guys, I am trying to include these functions in my test bench but I am getting the following error regarding both file infile : text is in ""; and file outfile : text is out "";
    -------> expecting an expression or operand

    Does anybody have an idea where this could come from?

    ReplyDelete
  20. This comment has been removed by the author.

    ReplyDelete
  21. Thank you so much. This code helped me a lot. How to do the same thing for a 2D array ? Please reply soon.

    ReplyDelete
  22. is this code works for reading hexadecimal values..??

    ReplyDelete
  23. I have data I want to read into a fifo from a text file. My prof says the text file has to be simulated as a testbench, but that still leaves me with the fifo implementation file and fifo simulation file. How do I run the two testbenches that require communication with the same fifo module? In other words, is there a way to identify the simulation running the text read as a "component" testbench?.. similar to how one would run a component module in a testbench? Any help is appreciated. Thx.

    ReplyDelete
  24. how to handle the excel sheet data in VHDL code or test bench

    ReplyDelete