Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20688 Discussions

Initializing inferred RAM from a text file

efe373
New Contributor I
675 Views

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

0 Kudos
4 Replies
ShengN_Intel
Employee
645 Views

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

https://www.intel.com/content/www/us/en/programmable/quartushelp/13.0/mergedProjects/program/red/red_view_using_editor.htm#:~:text=The%20In%2DSystem%20Memory%20Content%20Editor%20allows%20you%20to%20read,clocks%20with%20a%20JTAG%20interface.

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).

ShengN_Intel_0-1670228163670.png

https://www.intel.com/content/www/us/en/docs/programmable/683819/22-1/in-system-memory-content-editor.html

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.

 

0 Kudos
efe373
New Contributor I
642 Views

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

0 Kudos
ShengN_Intel
Employee
639 Views

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.

 

0 Kudos
ShengN_Intel
Employee
598 Views

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.


0 Kudos
Reply