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 1021FFFAI 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!
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
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).
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.