[SOLVED] FILE read and save to FIFO in VHDL (like readmemh in verilog)

Status
Not open for further replies.

syedshan

Advanced Member level 1
Joined
Feb 27, 2012
Messages
463
Helped
27
Reputation
54
Reaction score
26
Trophy points
1,308
Location
Jeonju, South Korea
Visit site
Activity points
5,134
Dear all,

This is kind of urgent but in no way at all DOING-HOME-WORK-BY-SOMEONE-ELSE kind of thing. I am just stuck with time and have less experience of simulation over VHDL
I usually use verilog for my simulation but this time I have to use VHDL (dont ask why...obsessed with timing )

Any how the thing is I have to read the entire file as we use to do in verilog with readmemh command and then save respective data to FIFO (for simulation).
I know this might be simple thing but now if someone has a code snippet or web-link please share.

Waitng
bests,
 

Use the textio package:

use std.textio.all;

It allows you to read text files. The important procedures you need to know are
readline/writeline : read/write a line of text from a text file into a line type.
read/write(l, x) : where l is the line, and x is the signal/variable you want to read/write a value to.

Here is a quick demo:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
use std.textio.all;
signal x : integer;
....
 
file my_file : text open read_mode is "some_text_file.txt";
variable l : line;
 
....
 
readline(my_file, l);
read(l, x);



readline and read are procedures so must be called inside a process, procedure or function.

With VHDL 2008, read, oread, hread, write, owrite, hwrite are added for ALL standard types and the procedures exist in the same package as the types (this is mostly important for the std_logic_1164 package and numeric_std package).

There are plenty of textio tutorials out there. Google will come up with plenty. Write some code and if you get stuck, come here for help.

NOTE: I would suggest not using these in synthesisable code, only testbenches.
 

Thank you for reply

I was reading one of your other reply at here
and you wrote :
1. As you are trying to read directly into a std_logic_vector, you need to use ieee.std_logic_textio aswell as std.textio.

ok. So when I went into the ieee.std_logic_textio, for READ I have 3 arguments, and I cannot understand the 3rd argument is what i.e.
GOOD : out boolean

Code:
 procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is
                variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
                ATTRIBUTE synthesis_return OF L:variable IS "read" ;
        begin
                READ(L, tmp, GOOD);
                VALUE := STD_LOGIC_VECTOR(tmp);
        end READ;

When I run the simulation I got this. Also the code that I have used is as below.



Code:
--include this library for file handling in VHDL.
library std;
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;  --include package textio.vhd
use ieee.std_logic_textio.all;
--entity declaration
entity filehandle is
end filehandle;

--architecture definition
architecture Behavioral of filehandle is

signal clock,endoffile : bit := '0';
signal    dataread : std_logic_vector(15 downto 0); --data read from the file.
signal    datatosave : std_logic_vector(15 downto 0); --data to be saved into the output file.
signal    linenumber : integer:=1;  --line number of the file read or written.

begin


clock <= not (clock) after 1 ns;    --clock with time period 2 ns

--read process
reading :
process
    file   infile    : text is in  "1.txt";   --declare input file
    variable  inline    : line; --line number declaration
    variable  dataread1    : std_logic_vector(15 downto 0);
begin
wait until clock = '1' and clock'event;
if (not endfile(infile)) then   --checking the "END OF FILE" is not reached.
readline(infile, inline);       --reading a line from the file.
  --reading the data from the line and putting it in a real type variable.
read(inline, dataread1);
dataread <=dataread1;   --put the value available in variable in a signal.
else
endoffile <='1';         --set signal to tell end of file read file is reached.
end if;

end process reading;

--write process
writing :
process
    file      outfile  : text is out "2.txt";  --declare output file
    variable  outline  : line;   --line number declaration  
begin
wait until clock = '0' and clock'event;
if(endoffile='0') then   --if the file end is not reached.
--write(linenumber,value(real type),justified(side),field(width),digits(natural));
write(outline, dataread, right, 16);
-- write line to external file.
writeline(outfile, outline);
linenumber <= linenumber + 1;
else
null;
end if;

end process writing;
end Behavioral;
 

ok. So when I went into the ieee.std_logic_textio, for READ I have 3 arguments, and I cannot understand the 3rd argument is what i.e.
GOOD : out boolean
Did you consider to consult a VHDL specification?
The success indication returned via parameter GOOD allows a process to recover gracefully from unexpected discrepancies in input format.
Getting a read value of undefined suggests that the data in the input file is not corresponding to the format expected according to the data type in READ(), in case of std_logic_vector:
The representation of a BIT_VECTOR value is formed by a sequence of characters, either 1 or 0. No leading or trailing quotation characters are present.
You are mentioning a "real type variable", so why you are using std_logic_vector?
 
ok. So when I went into the ieee.std_logic_textio, for READ I have 3 arguments, and I cannot understand the 3rd argument is what i.e.
GOOD : out boolean

Thats the format for all read procedures. the std_logic_textio package is not a standard VHDL package, but is fine to use. The functionality was wrapped into std_logic_1164 in VHDL 2008.
The "good" argument allows you to check that the data in the text file is value. If you dont provide a variable for that argument, if the data in the text file is invalid (like you're trying to read "Hello" into a std_logic_vector), the testbench will fail. With the good parameter, the testbench will continue, and you can act on it how you like.

something like this:

Code:
variable good : boolean;

read(l, my_slv, good);

if not good then report "There was some bad data in the text file, but I dont care" severity warning;


Code:
    file   infile    : text is in  "1.txt";   --declare input file

This is the VHDL '87 format for files. You should use the VHDL '93 format:

file infile : text open read_mode is "1.txt";

Code:
wait until clock = '1' and clock'event;

You cannot 'event in a wait until statement, as 'event is not a signal. You need to change it to either:

wait until clock = '1'
or
wait until rising_edge(clock);
 
oh...
Thank you for both of your help.

I find the solution and am posting for future references for any one including me since I always forget how I did :|
ALthough it is the worst piece of code but any ways

Main things are
1. std_logic_vector(to_signed(dataread, 16))
2. variable dataread1 : integer; --data read declared as integer, later it is transformed into std_logic_vector by above method

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
library std;
use std.textio.all;  --include package textio.vhd
use ieee.std_logic_textio.all;

entity filehandle is
port(
data_out : out std_logic_vector(15 downto 0)
);
end filehandle;

--architecture definition
architecture Behavioral of filehandle is
--period of clock,bit for indicating end of file.
signal endoffile : bit := '0';
signal clock : std_logic := '0';
signal rst : std_logic := '1';
signal    dataread : integer;
signal    linenumber : integer:=1; --line number of the file read or written.
signal rd_en : std_logic := '0';
signal wr_en: std_logic := '1';

COMPONENT FIFOa
--<skipping component here to save space>
END COMPONENT;

begin
uutF : FIFOa
  PORT MAP (
    rst => rst,
    wr_clk => clock,
    rd_clk => clock,
    din => std_logic_vector(to_signed(dataread, 16)) ,
    wr_en => wr_en,
    rd_en => rd_en,
    dout => data_out,
    full => open,
    empty => opem,
    valid => open,
    rd_data_count => open,
    wr_data_count => open
  );

clock <= not (clock) after 5 ns;    --clock with time period 2 ns

process

begin
wait for 30 ns;		rst <= '0';
wait for 500 ns ;	rd_en <= '1';
end process;

--read process
reading :
process
    file   infile    : text is in  "1.txt";   --declare input file
    variable  inline    : line; --line number declaration
    variable  dataread1    : integer;
begin
-- wait until clock = '1' and clock'event;
wait until rising_edge(clock);
if (not endfile(infile)) then   --checking the "END OF FILE" is not reached.
readline(infile, inline);       --reading a line from the file.
  --reading the data from the line and putting it in a real type variable.
read(inline, dataread1);
wr_en <= '1';
dataread <= dataread1;   --put the value available in variable in a signal.
else
endoffile <='1';         --set signal to tell end of file read file is reached.
wr_en <= '0';
end if;

end process reading;
end Behavioral;
 
I find the solution and am posting for future references for any one including me since I always forget how I did :|

Thanks. People should do that more often... The posting for future reference thing, not the forgetting how they did it thing. XD
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…