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

How to initialize content of a RAM without using Megawizard

Altera_Forum
Honored Contributor II
5,404 Views

Hello world, 

 

Here is my problem. I would like to initialize the content of a RAM block with an external text file without using the megawizard plugin. 

The following VHDL is working correctly in Xilinx synthetizer (XST). the xst synthetizer create the netlist by including the RAM Block and the RAM is initialized with the content of the ram_init.txt file. 

In quartus, the synthetizer create the netlist by implementing a RAM block (altsyncram) but the RAM block is not initialized. 

When I look at the tdf file created during the synthesis, the RAM is initialized with the file ram_init.ram0_ram_init_bcaa821.hdl.mif in database (db) folder and unfortunately, this files is full of 0. 

 

Is somebody know how to fix this??? 

 

Br 

 

--------------------------------- 

Code of the source file: 

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use std.textio.all; entity ram_init is port( -- RAM A interface rama_clk : in std_logic; rama_we : in std_logic; rama_addr : in std_logic_vector(5 downto 0); rama_din : in std_logic_vector(31 downto 0); rama_dout : out std_logic_vector(31 downto 0)); end entity ram_init; architecture syn of ram_init is type RamType is array(0 to 63) of bit_vector(31 downto 0); impure function InitRamFromFile (RamFileName : in string) return RamType is FILE RamFile : text is in RamFileName; variable RamFileLine : line; variable RAM : RamType; begin for I in RamType'range loop readline (RamFile, RamFileLine); read (RamFileLine, RAM(I)); end loop; return RAM; end function; signal RAM : RamType := InitRamFromFile("ram_init.txt"); begin rama_proc: process (rama_clk) begin if rama_clk'event and rama_clk = '0' then if rama_we = '1' then RAM(conv_integer(rama_addr)) <= to_bitvector(rama_din); end if; rama_dout <= to_stdlogicvector(RAM(conv_integer(rama_addr))); end if; end process; Content of ram_init.txt 

00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 00001111000011110000111100001111 01001010001000001100000010000100 00000000001111100000000001000001 11111101010000011100010000100100 Content of the mfi generated file: 

-- begin_signature -- ram_init -- end_signature WIDTH=32; DEPTH=64; ADDRESS_RADIX=UNS; DATA_RADIX=BIN; CONTENT BEGIN 63 : 00000000000000000000000000000000; 62 : 00000000000000000000000000000000; 61 : 00000000000000000000000000000000; 60 : 00000000000000000000000000000000; 59 : 00000000000000000000000000000000; 58 : 00000000000000000000000000000000; 57 : 00000000000000000000000000000000; 56 : 00000000000000000000000000000000; 55 : 00000000000000000000000000000000; 54 : 00000000000000000000000000000000; 53 : 00000000000000000000000000000000; 52 : 00000000000000000000000000000000; 51 : 00000000000000000000000000000000; 50 : 00000000000000000000000000000000; 49 : 00000000000000000000000000000000; 48 : 00000000000000000000000000000000; 47 : 00000000000000000000000000000000; 46 : 00000000000000000000000000000000; 45 : 00000000000000000000000000000000; 44 : 00000000000000000000000000000000; 43 : 00000000000000000000000000000000; 42 : 00000000000000000000000000000000; 41 : 00000000000000000000000000000000; 40 : 00000000000000000000000000000000; 39 : 00000000000000000000000000000000; 38 : 00000000000000000000000000000000; 37 : 00000000000000000000000000000000; 36 : 00000000000000000000000000000000; 35 : 00000000000000000000000000000000; 34 : 00000000000000000000000000000000; 33 : 00000000000000000000000000000000; 32 : 00000000000000000000000000000000; 31 : 00000000000000000000000000000000; 30 : 00000000000000000000000000000000; 29 : 00000000000000000000000000000000; 28 : 00000000000000000000000000000000; 27 : 00000000000000000000000000000000; 26 : 00000000000000000000000000000000; 25 : 00000000000000000000000000000000; 24 : 00000000000000000000000000000000; 23 : 00000000000000000000000000000000; 22 : 00000000000000000000000000000000; 21 : 00000000000000000000000000000000; 20 : 00000000000000000000000000000000; 19 : 00000000000000000000000000000000; 18 : 00000000000000000000000000000000; 17 : 00000000000000000000000000000000; 16 : 00000000000000000000000000000000; 15 : 00000000000000000000000000000000; 14 : 00000000000000000000000000000000; 13 : 00000000000000000000000000000000; 12 : 00000000000000000000000000000000; 11 : 00000000000000000000000000000000; 10 : 00000000000000000000000000000000; 9 : 00000000000000000000000000000000; 8 : 00000000000000000000000000000000; 7 : 00000000000000000000000000000000; 6 : 00000000000000000000000000000000; 5 : 00000000000000000000000000000000; 4 : 00000000000000000000000000000000; 3 : 00000000000000000000000000000000; 2 : 00000000000000000000000000000000; 1 : 00000000000000000000000000000000; 0 : 00000000000000000000000000000000; END;
0 Kudos
15 Replies
Altera_Forum
Honored Contributor II
4,367 Views

instead of using a text file, generate a VHDL package instead: 

 

package mem_package is type RamType is array (0 to 63) of bit_vector(31 downto 0); constant MEM_INIT : RamType := ( x"0000", x"0001", ......etc ); end package mem_package;  

 

Then in your source code you can just say 

 

use work.mem_package.all; ..... signal myMem : RamType := MEM_INIT;  

 

Then you can re-write or modify the package without having to worry about the source. The package could be generated via the same method you generated your ram_init.txt
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Thanks for the reply, Tricky but I want to avoid the use of a package or the modification of any vhdl file and that's why I try to use an external text file. 

 

This solution with the initialization function is working fine with xst ISE and I'm wondering it's not working for Quartus.
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

I assume you're generating the mem_init text file from some external program rather than generating it by hand? why cant you just have the same program/script generate the package for you instead, its not likely to be much more complicated. 

 

On a side note - I can recreate your problem. If its initialised from a constant it generates the mif file properly. It wont work like you have it or if its the constant declaration that calls InitRamFromFile. I would raise this as a support case with altera. 

 

Another side note: any reason you're using VHDL '87 syntax for file IO rather than '93?
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Tricky thanks for the support, 

 

I notice also when we use constant for initialization the mfi file is correctly generated and it should be one solution but the modification of a package is for me not welcome in my case. 

 

 

--- Quote Start ---  

 

Another side note: any reason you're using VHDL '87 syntax for file IO rather than '93? 

 

--- Quote End ---  

Because of read function in textio package: 

procedure READ(L:inout LINE; VALUE: out bit; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out bit); procedure READ(L:inout LINE; VALUE: out bit_vector; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out bit_vector); procedure READ(L:inout LINE; VALUE: out BOOLEAN; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out BOOLEAN); procedure READ(L:inout LINE; VALUE: out character; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out character); procedure READ(L:inout LINE; VALUE: out integer; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out integer); procedure READ(L:inout LINE; VALUE: out real; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out real); procedure READ(L:inout LINE; VALUE: out string; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out string); procedure READ(L:inout LINE; VALUE: out time; GOOD : out BOOLEAN); procedure READ(L:inout LINE; VALUE: out time);
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

For your information: When I don't initialize the RAM, no mfi file is created and the tdf file does not implement INIT_FILE or INIT_FILE_LAYOUT parameter. 

I probably miss the path of my file in my vhdl or in quartus (qsf)...
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

The VHDL '87/93 syntax has nothing to do with the read/write functions in the textio package. 

 

I mean saying this: 

 

FILE RamFile : text is in RamFileName; 

 

instead of: 

 

File RamFile : text open READ_MODE is RamFileName;
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

It was an xst template. But what ever, when I modify 

File RamFile : text open READ_MODE is RamFileName 

instead of: 

FILE RamFile : text is in RamFileName; 

it changes absolutly nothing in quartus and a lot of EDA tools are still supporting VHDL 87 syntax
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Just a simple question: Did you verify, that compile time calculations, e.g. memory initialization from a text file is supported by Quartus? It surely works in ModelSim, but I didn't yet see it operational in Quartus synthesis. It may be anyway.

0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Well it doesnt complain, but the Altera coding guidlines dont have any mention of textio in there. 

 

I still think the easiest method to make it work will be by outputting a constant into a package (or the entire package). I still dont understand how if you generate a text file from a script or some C code, you cant generate a package aswell/instead. 

 

Otherwise, you will have to raise the issue with altera via mysupport and see what they come up with.
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

 

--- Quote Start ---  

Well it doesnt complain, but the Altera coding guidlines dont have any mention of textio in there. 

--- Quote End ---  

doesn't complain is not enough, because a lot of simulation related stuff is ignored by the Quartus compiler intentionally. It may be the case also with this kind of initialisation. Initialisation within the VHDL code is always considered, e.g. for inferred ROM or RAM preloaded data.
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Hello people, 

 

@FvM it is why i opened this topic in the Altera's forum. The synthesis output tdf file (AHDL) is generating an initiliaze file (mfi) for the RAM. When I don't initilialize the RAM 

signal RAM : RamType; 

instead of 

signal RAM : RamType := InitRamFromFile("ram_init.txt"); 

no initiliaze file (mfi) for the RAM is created. 

 

For your information, XST which is the xilinx's synthetiser is working correctly with this manner. 

I raise my issue to altera via mysupport. 

 

So wait and see... 

Thanks for your help :)
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Quartus II simply ignores TEXTIO during synthesis, though it should really be giving you an error that you're doing something unsupported! File I/O should be supported for initializing constants. It's only a hard error if you want to describe a process that loads the contents of a file "at runtime". Off and on, I see designs where someone is attempting to do exactly that, e.g. load a JPEG into device RAM and manipulate it. FPGA != general purpose processor attached to your computer :)  

 

You can use the ram_init_file synthesis attribute to specify the MIF file for an inferred RAM. Unfortunately, this proprietary mechanism won't work in other tools or, importantly, during simulation.
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

 

--- Quote Start ---  

Unfortunately, this proprietary mechanism won't work in other tools or, importantly, during simulation. 

--- Quote End ---  

It works fine in ModelSim simulation (in Quartus simulation anyway), when using *.hex rather than *.mif initialization files. But ModelSim has special requirements for the *.hex file location. 

 

In any cases, where the initialization file content can be generated by a well-defined (not necessarily simple) algorithm, e.g. a function lookup-table, you have the option to calculate it at compile time by VHDL code, which is the most portable construct to my opinion.
0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

Reply from Anthony in mysupport (by the way thank you) 

 

 

--- Quote Start ---  

 

The reason of the failed RAM initialization in your design is that File I/O operations in VHDL aren’t supported to be synthesized in Quartus II. Due to this the RAM initialization with a text file isn’t supported in VHDL for inferred RAMs. You may refer to the section “Specifying Initial Memory Contents at Power-Up” on page 6-27 of Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis to learn how inferred RAM can be initialized in VHDL. 

 

BTW, Quartus II supports the $readmemb and $readmemh system commands in Verilog to initialize memories with a text file. You may consider implementing your design in Verilog to meet your design requirement. 

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
4,367 Views

 

--- Quote Start ---  

instead of using a text file, generate a VHDL package instead: 

 

Then you can re-write or modify the package without having to worry about the source. The package could be generated via the same method you generated your ram_init.txt 

--- Quote End ---  

 

 

when writing reusable code including a package makes things a bit more complicated. if i want to use the code multiple times with different parameters, i have to copy the VHDL source and the package to new files. if i could initialize things from text files i could pass a string generic to the source and not copy any files. 

 

oh well. :o
0 Kudos
Reply