Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15559 Discussions

Trouble populating memory from text file

Altera_Forum
Honored Contributor II
1,598 Views

Hello everyone, I need help populating my memory from a text file. Here is my RAM vhdl code: 

 

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE STD.TEXTIO.ALL; -- Add a generic parameter ENTITY rem_ram IS PORT ( address : IN std_logic_vector(7 DOWNTO 0); read_data : OUT std_logic_vector(31 DOWNTO 0) ); END ENTITY rem_ram; ARCHITECTURE rtl OF rem_ram IS TYPE ram_type IS ARRAY(0 TO (2**address'LENGTH)-1) OF std_logic_vector(read_data'RANGE); FUNCTION init_rom RETURN ram_type IS VARIABLE r : ram_type; BEGIN FOR i IN r'RANGE LOOP r(i) := (OTHERS => '0'); END LOOP; RETURN r; END FUNCTION; -- FILL MEMORY FROM TEXT FILE FUNCTION fill_memory RETURN ram_type IS VARIABLE mem : ram_type; TYPE HexTable IS ARRAY (CHARACTER RANGE <>) OF INTEGER; CONSTANT lookup : HexTable('0' TO 'F'):= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15); FILE infile: text OPEN read_mode IS "mem_ram.txt"; VARIABLE buff: LINE; VARIABLE addr_s: STRING(2 DOWNTO 1); VARIABLE data_s : STRING(8 DOWNTO 1); VARIABLE addr1, byte_cnt: INTEGER; VARIABLE data: INTEGER RANGE 4294967295 DOWNTO 0; BEGIN WHILE (not endfile(infile)) LOOP readline(infile, buff); read(buff, addr_s); read(buff, byte_cnt); addr1 := lookup(addr_s(2))*16 + lookup(addr_s(1)); readline (infile, buff); FOR i IN 1 TO byte_cnt LOOP read(buff, data_s); data := lookup(data_s(8))*268435456 + lookup(data_s(7))*16777216 + lookup(data_s(6))*1048576 + lookup(data_s(5))*65536 + lookup(data_s(4))*4096 + lookup(data_s(3))*256 + lookup(data_s(2))*16 + lookup(data_s(1)); mem(addr1) := CONV_STD_LOGIC_VECTOR(data, 32); addr1 := addr1 + 1; END LOOP; END LOOP; RETURN mem; END FUNCTION; SIGNAL ram : ram_type := fill_memory; BEGIN read_data <= ram(CONV_INTEGER(UNSIGNED(address))); END ARCHITECTURE rtl;  

 

and here is the text file: 

 

00 8C020000 04 8C030001 08 00430820 0C AC010003 10 1022FFFF 14 1021FFFA  

 

I suspect that maybe there's an illegal (outside of the hex range) character in the .txt file but I don't see any. Maybe I need to save the text file in a different encoding format? Like ASCII or UTF-8? 

 

Thanks everyone!
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
176 Views

Forgot to specify the exact error I am getting 

 

Error (10385): VHDL error at rem_ram.vhd(46): index value nul is outside the range ('0' to 'F') of object "lookup" Error (10658): VHDL Operator error at rem_ram.vhd(46): failed to evaluate call to operator ""*"" Error (10658): VHDL Operator error at rem_ram.vhd(46): failed to evaluate call to operator ""+"" Error (12153): Can't elaborate top-level user hierarchy Error: Quartus Prime Analysis & Synthesis was unsuccessful. 4 errors, 1 warning Error: Peak virtual memory: 696 megabytes Error: Processing ended: Fri Mar 09 15:50:18 2018 Error: Elapsed time: 00:00:15 Error: Total CPU time (on all processors): 00:00:34 Error (293001): Quartus Prime Full Compilation was unsuccessful. 6 errors, 1 warning
Altera_Forum
Honored Contributor II
176 Views

Is this for simulation? Altera doesn't support initialisation of ram from text file during synthesis.

Altera_Forum
Honored Contributor II
176 Views

This is for compilation. Well, that is too bad then.

Altera_Forum
Honored Contributor II
176 Views

Even if it was possible, there are other issues with the code. For a start, this seems like a terribly complicated way to initialise the ram. Whats wrong with just reading the values straight to a std_logic_vector? non-standard std_logic_textio package has the hread function to do just that. (in VHDL 2008, this is included in std_logic_1164 package).  

Then there is the problem that most implementations limit integer to 2**31-1. So integer cannot be given a value of 2**32. 

Also, Strings are usually declared (1 to N) by convention, rather than (N downto 1).
Altera_Forum
Honored Contributor II
176 Views

Instead of doing it in code, you could use a .hex or .mif file to initialize the RAM.

Altera_Forum
Honored Contributor II
176 Views

So instead of using .txt file, i just need to change it to .mif?

Altera_Forum
Honored Contributor II
176 Views

No, you have to use an attribute to populate the ram with a .mif/.hex: 

 

http://quartushelp.altera.com/15.0/mergedprojects/hdl/vhdl/vhdl_file_dir_ram_init.htm 

 

Be aware though, that this will NOT initialise the ram during simulation. You will need to read in the text file and parse it manually. If you use a ram from the megafunctions library, you can specify the .mif as a generic and this block will parse the file for you, populating the contents in both simulation and synthesis.
Altera_Forum
Honored Contributor II
176 Views

the link is broken?

Altera_Forum
Honored Contributor II
176 Views

link works for me from 2 different places - on google chrome?

Altera_Forum
Honored Contributor II
176 Views

Firefox. But I disabled HTTPS-Everywhere and it works fine now.

Reply