VHDL coding tips and tricks: File reading and writing in VHDL - Part 2

Thursday, February 17, 2011

File reading and writing in VHDL - Part 2

I have published a post on file reading and writing using VHDL before. You can access it here. As you know file manipulation will help you to verify your design more effectively at the debugging stage of your design.

For file operation we use the library named textio in the STD directory. This library contains the in built functions for reading and writing files.

Reading Files in VHDL:

The below code reads a set of binary numbers from the file named read.txt and put them into a 4 bit std_logic_vector signal. The text file used with the code can be downloaded from here.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use STD.textio.all; --Dont forget to include this library for file operations.

ENTITY read_file IS
END read_file;

ARCHITECTURE beha OF read_file IS

    signal  bin_value : std_logic_vector(3 downto 0):="0000";
   
BEGIN
   
   --Read process
    process
      file file_pointer : text;
        variable line_content : string(1 to 4);
      variable line_num : line;
        variable j : integer := 0;
        variable char : character:='0';
   begin
        --Open the file read.txt from the specified location for reading(READ_MODE).
      file_open(file_pointer,"C:\read.txt",READ_MODE);   
      while not endfile(file_pointer) loop --till the end of file is reached continue.
      readline (file_pointer,line_num);  --Read the whole line from the file
        --Read the contents of the line from  the file into a variable.
      READ (line_num,line_content);
        --For each character in the line convert it to binary value.
        --And then store it in a signal named 'bin_value'.
        for j in 1 to 4 loop       
            char := line_content(j);
            if(char = '0') then
                bin_value(4-j) <= '0';
            else
                bin_value(4-j) <= '1';
            end if;
        end loop;  
        wait for 10 ns; --after reading each line wait for 10ns.
      end loop;
      file_close(file_pointer);  --after reading all the lines close the file. 
        wait;
    end process;

end beha;

The above VHDL code can also be downloaded from here. I have commented the codes so that you can understand the flow of the code. The values read from the file are represented by a signal named bin_value. The simulation waveform is given below:

The main points to be noted are:
  • Declare file pointers and other variables required as given in the above code.
  • file_open() to open the file. Change the path of the file depending on where your file is stored.
  • Use read and readline functions.
  • Finally after everything is over, close the file using file_close.


Writing Files in VHDL:

  The following code is used for writing a file. Remember that these codes contain just examples and depending on what you have to write to the file the code should be changed. The code writes binary numbers from 0000 to 1111 to a file named write.txt


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
use STD.textio.all;

ENTITY write_file IS
END write_file;

ARCHITECTURE beha OF write_file IS
   
BEGIN
   
   --Write process
    process
      file file_pointer : text;
        variable line_content : string(1 to 4);
        variable bin_value : std_logic_vector(3 downto 0);
      variable line_num : line;
        variable i,j : integer := 0;
        variable char : character:='0';
   begin
        --Open the file write.txt from the specified location for writing(WRITE_MODE).
      file_open(file_pointer,"C:\write.txt",WRITE_MODE);     
        --We want to store binary values from 0000 to 1111 in the file.
      for i in 0 to 15 loop
        bin_value := conv_std_logic_vector(i,4);
        --convert each bit value to character for writing to file.
        for j in 0 to 3 loop
            if(bin_value(j) = '0') then
                line_content(4-j) := '0';
            else
                line_content(4-j) := '1';
            end if;
        end loop;
        write(line_num,line_content); --write the line.
      writeline (file_pointer,line_num); --write the contents into the file.
        wait for 10 ns;  --wait for 10ns after writing the current line.
      end loop;
      file_close(file_pointer); --Close the file after writing.
        wait;
    end process;

end beha;

The above code can also be downloaded from here. Any file writing code should have the following structure:

  • Declare file pointers and other variables required as given in the above code.
  • file_open() to open the file. Change the path of the file depending on where your file is stored.
  • Use write and writeline functions.
  • Finally after everything is over, close the file using file_close.
Note:- The codes are tested successfully using Xilinx Webpack 12.1. Note that file reading is a part of testbench design. In actual FPGA you cannot read or write files. But for functional verification of your design this is a must know.

28 comments:

  1. hi,,
    good post...
    smtimes when we try to open a file which is already open then modelsim shows some 'error'(not warning) but things keep on working fine..so i use to ignore dat error..
    anyways..plz. tell us is there any difference b/n asic coding style n fpga coding style... ?

    ReplyDelete
  2. @hank : once you open the file, you have to close it. otherwise you cant open it.

    asic coding means gate level or transistor level coding.But in fpga coding, we only consider the function. In ASIC coding we can change the routing and other things. Its like bulding a circuit from scratch.

    ReplyDelete
  3. Im wondering why you've done this, and not used the std_logic_textio package? with this you can read/write directly with std_logic(_vector)s?

    In addition, there is no need for an extra string variable. The line type is just a pointer to a string, and you can dereference it to access each character by:

    char := line_num.all(i);

    ReplyDelete
  4. can u please suggest how to store the output of the file reading part in array....?

    ReplyDelete
  5. VHDL can also deal with truly binary (non-ascii) files by declaring a file type of integer:

    type binary_file is file of integer;
    file dat : binary_file is in FILENAME;

    Now the file 'dat' can be read directly into an array 'rd_array' (array(0 to SIZE) of integer), skipping the line buffer altogether:

    read(dat,rd_array(0));

    May be useful, depending on application.

    ReplyDelete
    Replies
    1. If its a truly binary file is it possible to force data type upon it ? I mean can we declare it as a

      ------ type binary_file is file of STD_LOGIC_VECTOR(63 downto 0)

      ?????

      and then assign directly arrays of RAM block as is ?

      Delete
  6. how can we read a bmp image in vhdl . can u give the code

    ReplyDelete
    Replies
    1. hi rahul...,,,
      me doing a project on image processing..,
      fr dis i require vhdl coding for reading an image..,
      so, plz give me code if u have it..,
      plzzzzzzzzzzzzzzzzz sent it to my mail pravee.adapala@gmail.com

      Delete
    2. Hello,
      Can you plz send me the vhdl code for image reading ?
      You send it to my email allobro18@hotmail.com
      Thank you in advance,

      Delete
    3. This comment has been removed by the author.

      Delete
    4. Hello,
      Can you plzzzzzzzzzz send me the vhdl code for image reading ?
      You send it to my email mounaho@gmail.com
      Thank you in advance,

      Delete
  7. but I got an error like this :
    Error (10533): VHDL Wait Statement error at write_file.vhd(37): Wait Statement must contain condition clause with UNTIL keyword

    what might be the problem??

    ReplyDelete
  8. but I got the error like this :

    Error (10533): VHDL Wait Statement error at write_file.vhd(37): Wait Statement must contain condition clause with UNTIL keyword

    what might be the problem?

    ReplyDelete
  9. but I got an error like this :
    Error (10533): VHDL Wait Statement error at write_file.vhd(37): Wait Statement must contain condition clause with UNTIL keyword

    what might be the problem??

    ReplyDelete
  10. how to read hex file in vhdl??? pls help....

    ReplyDelete
  11. I tried to synthesize the your code...but throwing an error...
    ERROR:Xst:1914 - "F:/StudY/Project_all/BE_ENTC/VLSI/Programs/read_file_h/read_file_h.vhd" line 46: File does not exist.

    ReplyDelete
  12. hi, i read all the pixel values of an image in to one dimensional array, now i want to write those pixel values in the array to text file.Please help me

    ReplyDelete
  13. This comment has been removed by a blog administrator.

    ReplyDelete
  14. Hello All,
    I have changed the above VHDL code in order to read the following txt file:

    11 11 11 11 11 11 11
    21 22 23 24 25 26 27
    31 32 33 34 35 36 37
    41 42 43 44 45 46 47


    My problem that when I simulate it the output is 11 21 31 41 . So, it is reading only the first element of each line and notl all the elements of each line. Could you please let me know what is wrong?

    Here is my code:

    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    use STD.textio.all; --Dont forget to include this library for file operations.
    use ieee.numeric_std.all;
    use ieee.std_logic_arith.all;


    ENTITY read_file IS
    END read_file;

    ARCHITECTURE beha OF read_file IS

    signal bin_value : std_logic_vector(7 downto 0):="00000000";


    BEGIN

    --Read process
    process
    file file_pointer : text;
    variable line_content : integer;
    variable line_num : line;


    begin
    --Open the file read.txt from the specified location for reading(READ_MODE).
    file_open(file_pointer,"C:\imagebinary.txt",READ_MODE);

    while not endfile(file_pointer) loop --till the end of file is reached continue.
    readline (file_pointer,line_num); --Read the whole line from the file

    --Read the contents of the line from the file into a variable.
    READ (line_num,line_content);


    bin_value <= conv_std_logic_vector ( line_content, bin_value'length);


    wait for 1 ns; --after reading each line wait for 1ns.
    end loop;
    file_close(file_pointer); --after reading all the lines close the file.
    wait;

    end process;

    end beha;


    Thank you!:)

    ReplyDelete
  15. how to read multiple file... i have to read like 100 text file and write the data into 100 BRAMs.. is there any way to loop the reading process of txt file.

    ReplyDelete
  16. hi all,
    is there any way to read multiple txt files. i have like 100 txt files which is to be written into 100 BRAMs for the time being i am reading all the files one by one . plz tell me the way to loop the reading process of txt file

    ReplyDelete
  17. Hello,
    Can you plzzzzzzzzzzzz send me the vhdl code for image reading ?
    You send it to my email mounaho@gmail.com
    Thank you in advance,

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

    ReplyDelete
    Replies
    1. the file reading and writing works only for testbenches. These codes cannot be synthesised.

      What are you trying to do on the board? I can also help on personal projects for a fee. Send me an email for that.
      thanks.

      Delete
    2. This comment has been removed by the author.

      Delete
  19. Hi guys .
    I have a .DAT file of ECG and want to read it in vhdl to perform some computations on it.
    Can some one help me??
    Thanks in advance

    ReplyDelete
  20. I tried the code,but showing me error: Xst:1914 - "D:/Xilinx/14.7/ISE_DS/RAM/RAM.vhd" line 27: File does not exist.
    what to do?

    ReplyDelete
  21. why are you still using USE ieee.std_logic_arith.ALL;? You already explained http://vhdlguru.blogspot.nl/2010/03/why-library-numericstd-is-preferred.html

    ReplyDelete