Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

How to initialize content of a RAM without using Megawizard

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;

15 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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 :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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