Write to File in VHDL using TextIO Library

Write to File in VHDL using TextIO Library

When you simulate a design in VHDL it is very useful to have the possibility to save some simulation results. For example, if you need to compare the simulation results with reference test vector, or simply to document the simulation in a test report.

Write File Test Bench Architecture
Write File Test Bench Architecture

In VHDL, there are predefined libraries that allow the user to write to an output ASCII file in a simple way. The TextIO library is a standard library that provides all the procedure to read from or write to a file.

It is clear that these procedures cannot be used in a synthesizable RTL VHDL code, I mean no file handling possibility is present into a silicon device using simple RTL VHDL code, but they are very useful in test bench design.

 

There are several different ways to open a file and write to it.

In VHDL, File are handled as array of line an example of VHDL syntax to write to file is:

Declare and Open file in write mode:
file file_handler     : text open write_mode is “filename.dat”;
Variable row          : line;
Variable v_data_write : integer;


Write value to line
write(row, v_data_write);

Write line to the file
writeline(file_handler ,row);

The last action is used to write the desired value from the line to the file. If v_data_read is an integer value, the “write” procedure will try to write an integer value to the output line, if it is a real value, the procedure will try to write a real number and so on.

In this bunch of VHDL code, the file is opened during the file declaration on row 2.

A complete example of a process that write to a file is given below:

-- procedure WRITE(L : inout LINE; VALUE : in integer; JUSTIFIED: in SIDE := right; FIELD: in WIDTH := 0);
.
.
signal o_valid        : std_logic;
signal o_add          : std_logic_vector(7 downto 0);
.
.
.
p_dump  : process(i_rstb,i_clk)

file test_vector      : text open write_mode is "output_file.txt";
variable row          : line;

begin

  
  if(i_rstb='0') then

  ------------------------------------
  elsif(rising_edge(i_clk)) then
    
    if(o_valid = '1') then
    
      write(row,o_add, right, 15);
      
      write(row,conv_integer(o_add), right, 15);

      hwrite(row,o_add, right, 15);

      hwrite(row,"00000000"&o_add, right, 15);
      
      writeline(test_vector,row);
    
    end if;
  end if;
end process p_dump;

The code above implements a process that at each clock cycle to an output file the following value:

  • Column 1: 8-bit value
  • Column 2: integer values;
  • Column 3: 8-bit hexadecimal value
  • Column 4: 16-hexadecimal value

Data is written if control signal “o_valid” is ‘1’.

This code writes all the values right justified and each column contains 15 character

The output file will have the following format:

00000011              3             03           0003
00001010             10             0A           000A
00000010              2             02           0002
01011010             90             5A           005A

Here below there are the procedures you can find in IEEE TextIO standard library to write to a file different type of values:

procedure WRITELINE(file f : TEXT; L : inout LINE);

procedure TEE (file F :       TEXT; L : inout LINE);

procedure WRITE(L : inout LINE; VALUE : in bit;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in bit_vector;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in BOOLEAN;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in character;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in integer;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in real;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0;
    DIGITS: in NATURAL := 0);

procedure WRITE (L      : inout LINE; VALUE : in REAL;
         FORMAT : in    STRING);

procedure WRITE(L : inout LINE; VALUE : in string;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0);

procedure WRITE(L : inout LINE; VALUE : in time;
    JUSTIFIED: in SIDE := right;
    FIELD: in WIDTH := 0;
    UNIT: in TIME := ns);

alias SWRITE is WRITE [LINE, STRING, SIDE, WIDTH];
alias STRING_WRITE is WRITE [LINE, STRING, SIDE, WIDTH];
alias BWRITE is WRITE [LINE, BIT_VECTOR, SIDE, WIDTH];
alias BINARY_WRITE is WRITE [LINE, BIT_VECTOR, SIDE, WIDTH];

procedure OWRITE (L         : inout LINE; VALUE : in BIT_VECTOR;
        JUSTIFIED : in    SIDE := right; FIELD : in WIDTH := 0);
alias OCTAL_WRITE is OWRITE [LINE, BIT_VECTOR, SIDE, WIDTH];
procedure HWRITE (L         : inout LINE; VALUE : in BIT_VECTOR;
        JUSTIFIED : in    SIDE := right; FIELD : in WIDTH := 0);
alias HEX_WRITE is HWRITE [LINE, BIT_VECTOR, SIDE, WIDTH];

 

If you appreciated this post, please help us to share it with your friend.

[social_sharing style=”style-7″ fb_like_url=”https://surf-vhdl.com/write-to-file-in-vhdl-using-textio-library?utm_source=POST&utm_medium=FB&utm_campaign=SHARE” fb_color=”light” fb_lang=”en_US” fb_text=”like” fb_button_text=”Share” tw_lang=”en” tw_url=”https://surf-vhdl.com/write-to-file-in-vhdl-using-textio-library?utm_source=POST&utm_medium=TW&utm_campaign=SHARE” tw_button_text=”Share” g_url=”https://surf-vhdl.com/write-to-file-in-vhdl-using-textio-library?utm_source=POST&utm_medium=GPLUS&utm_campaign=SHARE” g_lang=”en-US” g_button_text=”Share” linkedin_url=”https://surf-vhdl.com/write-to-file-in-vhdl-using-textio-library?utm_source=POST&utm_medium=LK&utm_campaign=SHARE” linkedin_lang=”en_US” alignment=”center”]

 

If you need to contact us, please write to: surf.vhdl@gmail.com

We appreciate any of your comment, please post below:

 

13 thoughts to “Write to File in VHDL using TextIO Library”

  1. Having read this I thought it was extremely enlightening.

    I appreciate you spending some time and effort to put this article together.

    I once again find myself personally spending a lot of time both reading and
    commenting. But so what, it was still worthwhile!

  2. i tried this with writing bits to .bin file but it doesn’t work????? I made a simple inverter and i want to store the outputs in a file. here is the code:

    ———————————————————————————-
    — Company:
    — Engineer:

    — Create Date: 09/19/2019 03:56:37 PM
    — Design Name:
    — Module Name: inverter_w_tb – Behavioral
    — Project Name:
    — Target Devices:
    — Tool Versions:
    — Description:

    — Dependencies:

    — Revision:
    — Revision 0.01 – File Created
    — Additional Comments:

    ———————————————————————————-

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use std.textio.all;

    — Uncomment the following library declaration if using
    — arithmetic functions with Signed or Unsigned values
    –use IEEE.NUMERIC_STD.ALL;

    — Uncomment the following library declaration if instantiating
    — any Xilinx leaf cells in this code.
    –library UNISIM;
    –use UNISIM.VComponents.all;

    entity inverter_w_tb is
    — Port ( );
    end inverter_w_tb;

    architecture Behavioral of inverter_w_tb is

    type bitf is file of std_ulogic;
    constant clk_period : time := 10 ns;
    signal done : std_logic := ‘0’;
    signal x_in : std_ulogic := ‘0’;
    signal clk : std_ulogic := ‘0’;
    signal x_out: std_ulogic;

    component inverter is
    port (
    data_in : in std_ulogic;
    clk : in std_ulogic;
    data_out: out std_ulogic);
    end component inverter;

    begin
    done x_in,
    clk => clk,
    data_out=> x_out);

    clk_process: process
    begin
    for i in 0 to 8 loop
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
    end loop;
    wait;
    end process;

    stim_process: process
    begin
    x_in<='1';
    wait for clk_period;
    x_in<='1';
    wait for clk_period;
    x_in<='0';
    wait for clk_period;
    x_in<='0';
    wait for clk_period;
    x_in<='0';
    wait for clk_period;
    x_in<='0';
    wait for clk_period;
    x_in<='1';
    wait for clk_period;
    x_in<='0';
    wait;
    end process;

    write_process: process(clk)
    file file_handler : bitf open write_mode is "output.bin";
    variable row: line;
    begin
    if rising_edge(clk) then
    write(row, x_out);
    writeline(file_handler, row);
    end process;

    end Behavioral;

  3. Hello, thank you for this fantastic guide. I have a problem with it, could you help me? I’m acquiring data from the XADC of an evaluation board (ARTY), I can see converted data on an external led matrix but I can’t store these converted data on a .txt file with this VHDL code. Have you any suggestions?

    1. this code can be used only in a test-bench.
      If you are acquiring data on a real board, you need to connect your board with an external PC (or arduino board) and store this data in a file.
      Check my online courses. There are some example
      Ciao

Leave a Reply

Your email address will not be published. Required fields are marked *