Forum Discussion
Initializing inferred RAM from a text file
Hello,
I have written a simple dual-port RAM in VHDL following the single-port RAM example from Quartus, and I want to initialize this RAM using an external text file containing binary values. However, when I compile the design and check the contents of the RAM, everything is 0. What can be the problem? I am posting my dual-port RAM code and initialization text file.
Also, how can I use the In-System Memory Content Editor if I infer memory using HDL? Is there even a way to do that?
-- Quartus Prime VHDL Template -- Single-port RAM with single read/write address and initial contents library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; entity dual_port_ram is generic ( FILE_PATH : string := "ram_content_bin.txt"; DATA_WIDTH : natural := 8; ADDR_WIDTH : natural := 6 ); port ( clk : in std_logic; addr_a : in std_logic_vector((ADDR_WIDTH - 1) downto 0); addr_b : in std_logic_vector((ADDR_WIDTH - 1) downto 0); data_a : in std_logic_vector((DATA_WIDTH-1) downto 0); data_b : in std_logic_vector((DATA_WIDTH-1) downto 0); wren_a : in std_logic; wren_b : in std_logic; q_a : out std_logic_vector((DATA_WIDTH -1) downto 0); q_b : out std_logic_vector((DATA_WIDTH -1) downto 0) ); end dual_port_ram; architecture rtl of dual_port_ram is -- Build a 2-D array type for the RAM subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t; impure function init_ram_bin return memory_t is file text_file : text open read_mode is FILE_PATH; variable text_line : line; variable ram_content : memory_t; variable bv : bit_vector(ram_content(0)'range); begin for i in 0 to 2**ADDR_WIDTH - 1 loop readline(text_file, text_line); read(text_line, bv); ram_content(i) := To_StdLogicVector(bv); end loop; return ram_content; end function; -- Declare the RAM signal and specify a default value. Quartus Prime -- will create a memory initialization file (.mif) based on the -- default value. signal ram : memory_t := init_ram_bin; begin process(clk) begin if(rising_edge(clk)) then if(wren_a = '1') then ram(to_integer(unsigned(addr_a))) <= data_a; end if; end if; end process; q_a <= ram(to_integer(unsigned(addr_a))); process(clk) begin if(rising_edge(clk)) then if(wren_b = '1') then ram(to_integer(unsigned(addr_b))) <= data_b; end if; end if; end process; q_b <= ram(to_integer(unsigned(addr_b))); end rtl;
000000000 100000010 011110000 000000000 101001100 001001011 101000000 011000011 100000001 100000010 000000000 010010000 000000000 000000000 000000000 010010011
Thanks,
Efe
4 Replies
- ShengN_altera
Super Contributor
Hi @efe373 ,
Check this link https://community.intel.com/t5/Intel-Quartus-Prime-Software/VHDL-How-to-initialize-RAM-from-file/m-p/30348
RAM initialization from files through textio library functions is only supported by ModelSim and other simulators, but not by Quartus. For synthesis, you can only use *.hex or *.mif files
Easiest way is to use .mif file check this link https://www.intel.com/content/www/us/en/programmable/quartushelp/13.0/mergedProjects/hdl/vhdl/vhdl_file_dir_ram_init.htm
type mem_t is array(0 to 255) of unsigned(7 downto 0);
signal ram : mem_t;
attribute ram_init_file : string;
attribute ram_init_file of ram :
signal is "my_init_file.mif";
As for In-System Memory Content Editor check this link
You can open the In-System Memory Content Editor after instantiating in the design one or more altsyncram megafunctions with the Allow In-System Memory Content Editor to capture and update content independently of the system clock option turned on (image).
The In-System Memory Content Editor works by turning single‑port RAM blocks into dual-port RAM blocks. One port is connected to your clock domain and data signals, and the other port is connected to the JTAG clock and data signals for editing or viewing.
Noted: Only single-port memorys can therefore be used with ISME, because if you use a dual-port RAM the second port is already in use by your design and is therefore not available to ISME.
https://www.intel.com/content/www/us/en/docs/programmable/683819/22-1/ip-cores-supporting-ismce.html
you can use the ISMCE in RAM: 1 PORT and the ROM: 1 PORT IP Cores.
Related video: https://www.youtube.com/watch?v=YI34AoA74_c&t=5s
Thanks,
Best Regards,
Sheng
p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 4/5 survey.
- efe373
New Contributor
Hi Sheng,
Thanks for your answer. For the In-System Memory Content Editor, I was curious about enabling the feature for the RAMs inferred in HDL, not by a megafunction wizard. I assume it is not possible from your answer but I am not sure. Also, as you have mentioned this feature is for single-port RAMs, does it mean that there is no way I can enable this feature for dual-port RAMs?
Thanks,
Efe
- ShengN_altera
Super Contributor
Hi @efe373 ,
Just go through your reply, as mentioned in previous post:
The In-System Memory Content Editor works by turning single‑port RAM blocks into dual-port RAM blocks. One port is connected to your clock domain and data signals, and the other port is connected to the JTAG clock and data signals for editing or viewing.
Noted: Only single-port memorys can therefore be used with ISME, because if you use a dual-port RAM the second port is already in use by your design and is therefore not available to ISME.
Let me know if you have any further concern.
Thanks,
Best Regards,
Sheng
p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 4/5 survey.
- ShengN_altera
Super Contributor
Hi,
Do you have any further concern?
Thanks,
Best Regards,
Sheng
p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 4/5 survey.