Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16557 Discussions

VHDL textio hread problem

Altera_Forum
Honored Contributor II
5,032 Views

Hi, 

 

I am trying to create a component which will behave like a ROM in simulation. I would like it to take an input text file. I am trying to use the textio functionality. The component will have an address input and a rd input. It will have a rddata output. When rd is set high I want to read the data from the text file at the line set by address and make rddata the value read. 

 

e.g. 

 

prog_file.txt : 

 

01 

02 

a1 

a2 

 

If address=X"03" and rising edge on rd. 

rddata should equal a1.  

 

Here is what I have so far: 

LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE ieee.std_logic_textio.all; LIBRARY STD; USE STD.textio.all; LIBRARY work; ENTITY test_program_file_io IS GENERIC ( filename : string = prog_file.txt; data_width : integer = 8; addr_width : integer = 15 ); PORT ( address : IN std_logic_vector(addr_width-1 DOWNTO 0); rd : IN std_logic; rddata : OUT std_logic_vector(data_width-1 DOWNTO 0) ); END ENTITY; ARCHITECTURE sim OF test_program_file_io IS FILE file_input : text; SIGNAL value_read : std_logic_vector(data_width-1 DOWNTO 0); SIGNAL count : integer := 0; BEGIN rddata <= value_read; read_hex_value_from_file : PROCESS VARIABLE v_in_line : line; VARIABLE v_value : std_logic_vector(data_width-1 DOWNTO 0); BEGIN WAIT ON rd UNTIL rd = '1'; count <= to_integer(unsigned(address)); file_open(file_input, filename, read_mode); WHILE((NOT ENDFILE(file_input)) AND (count > 0) LOOP READLINE(file_input,v_in_line); count <= count - 1; END LOOP; HREAD(v_in_line,v_value); WAIT ON rd UNTIL rd = '0'; value_read <= v_value; file_close(file_input); END PROCESS; END ARCHITECTURE; 

 

I believe that the loop using count is not working because it is in a concurrent statement but I am not sure how to do this without them, I am thinking that to get the functionality I want, if address is 3 then i need to perform 3 readline ops (while checking for endline) and then do the hread and output the value. I cant think of a way of doing a variable number of readline ops without the loop.  

 

note hread is only compatible with vhdl-2008  

 

Any help or ideas would be greatly appreciated. 

 

Thanks 

 

James
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
3,296 Views

Why not just read the text file into an array using an initialisation function? and then just access the array with the address? This will perform far better than opening and closing the file on every single read access. 

 

 

--- Quote Start ---  

 

note hread is only compatible with vhdl-2008  

 

--- Quote End ---  

 

 

technically correct, but you included the non-standard library std_logic_textio which is a 3rd party library that gave you the ability to read/write directly to std_logic/std_logic_vector with VHDL 1993. The functionality of this package is included in std_logic_1164 in VHDL 2008.
0 Kudos
Altera_Forum
Honored Contributor II
3,296 Views

Is there any reason you're making an asynchronous rom? and not a synchronous one? 

 

btw, heres what I think you want: 

 

architecture sim of my_rom is type rom_t is array(0 to N-1) of std_logic_vector(7 downto 0); function init_rom return rom_t is file rom_file : text open read_mode is filename; variable ret : rom_t; variable l : line; begin for i in 0 to N-1 loop readline(rom_file, l); hread(l, ret(i)); end loop; return ret; end function init_rom; constant ROM : rom_t := init_rom; begin process(rd, addr) begin if rd='1' then rddata <= ROM( to_integer( to_unsigned( address ) ); end if; end process; end architecture sim;
0 Kudos
Altera_Forum
Honored Contributor II
3,296 Views

Hi Tricky, 

 

Thanks for your response. With a bit of playing I managed to get your code working and I have used it in my simulation. I had to declare the function as impure and I put in a check for the end of file for a bit of safety. This is what i ended up with: 

 

LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; LIBRARY STD; USE STD.textio.all; LIBRARY work; ENTITY test_program_file_io IS GENERIC ( filename : string := "prog_file.txt"; data_width : integer := 8; addr_width : integer := 15 ); PORT ( address : IN std_logic_vector(addr_width-1 DOWNTO 0); rd : IN std_logic; rddata : OUT std_logic_vector(data_width-1 DOWNTO 0) ); END ENTITY; ARCHITECTURE sim OF test_program_file_io IS CONSTANT N : integer := (2**addr_width); TYPE rom_t IS ARRAY (0 TO N-1) OF std_logic_vector(7 DOWNTO 0); IMPURE FUNCTION init_rom RETURN rom_t IS FILE rom_file : text OPEN read_mode IS filename; VARIABLE ret : rom_t; VARIABLE l : line; BEGIN FOR i IN 0 TO N-1 LOOP IF(NOT ENDFILE(rom_file)) THEN readline(rom_file, l); hread(l, ret(i)); END IF; END LOOP; RETURN ret; END FUNCTION init_rom; CONSTANT ROM : rom_t := init_rom; BEGIN PROCESS(rd, address) BEGIN IF(rd='1')THEN rddata <= ROM(to_integer(unsigned(address))); END IF; END PROCESS; END ARCHITECTURE; 

 

 

--- Quote Start ---  

technically correct, but you included the non-standard library std_logic_textio which is a 3rd party library that gave you the ability to read/write directly to std_logic/std_logic_vector with VHDL 1993. The functionality of this package is included in std_logic_1164 in VHDL 2008.  

--- Quote End ---  

 

 

Yes you are right, I was working with vhdl-1993 but updated my simulation to use vhdl-2008 so I could use the hread and cut a corner. I missed removing that library. 

 

 

--- Quote Start ---  

Is there any reason you're making an asynchronous rom? and not a synchronous one? 

--- Quote End ---  

 

 

Not really, the application might not be the best. I was trying to improve my simulation skills and using it like a ROM I could connect it in my work simulation. My aim was to be able to read in a selected line from a input text file so I can dump a hex program to a text file and load it into my simulation sequentially. I also wanted to be able to start from somewhere other than the start of the file.  

 

After playing I think that you are right and initializing an array is the simplest path. 

 

Thanks 

 

James
0 Kudos
Reply