Question

I have a memory module for an Altera FPGA target that I've written to be inferred into one of Altera's ALTSYNCRAM blocks. The memory is 1024x16 and I have a memory initialization file specified with an attribute. When synthesizing, the synthesis report indicates that it generated the type of RAM block that I wanted, and it notes that the initialization file is the one I specified. When trying to simulate with Altera's edition of ModelSim, the data signal starts out completely uninitialized, and I can't figure out why. I looked on forums and such and some people mentioned that ModelSim might not support the ".mif" format that I was using, but would support ".hex" so I changed my initialization file to ".hex". I also read that relative file paths can be an issue, but I checked my simulation directory and it looks like QuartusII copied the initialization file into that directory when I tried to simulate.

Any ideas on why the memory isn't being initialized and how to make it do so?

A heavily trimmed model that contains the inferred memory:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
--use work.types.all;
entity CPU is
--...
end entity CPU;
architecture rtl of CPU is
--these types are actually included in a package
subtype reg is std_logic_vector(15 downto 0);
type mem is array (0 to 1023) of reg;

--...
    --memory read port
    signal MR : reg;
    signal MRA : std_logic_vector(9 downto 0); --flops
    --memory write port
    signal MW : reg; --flops
    signal MWA : std_logic_vector(9 downto 0); --flops
    signal MWE : std_logic; --flop

    signal data : mem;
    attribute ram_init_file : string;
    attribute ram_init_file of data : signal is "RAM_init.hex";
    attribute ramstyle : string;
    attribute ramstyle of data : signal is "no_rw_check";
begin
--...
     --memory spec
     MR <= data(to_integer(unsigned(MRA(9 downto 0))));
    memory_process : process(clk)
    begin
        if (clk'event and clk = '1') then
                if(MWE = '1') then
                    data(to_integer(unsigned(MWA(9 downto 0)))) <= MW;
                end if;
        end if;
    end process;
end architecture rtl; --CPU

Modelsim does not show any warnings or errors while compiling CPU.vhd, nor does it have any indication of loading the initialization file.

This is my first design using Altera software or memory initialization files, and it wouldn't surprise me if the problem was something really basic, or I'm approaching this from a fundamentally incorrect angle. I'd normally define the memory with a constant in a package, but this is for a class, and it requires that I have a memory initialization file (it requires .mif format too, but that's only a 3 character change between simulation and synthesis file).

Was it helpful?

Solution

It looks like Modelsim may have a "mem load" command you can use at the start of your simulation in order to initialize the memory. Take a look at the end of this thread:

Initialization altsyncram

OTHER TIPS

Being able to initialize RAM on an FPGA depends on both the synthesizer and the specific FPGA you are using. Some FPGA families support this, others don't. I know this is not the answer you want to hear, but you'll need to check the documentation from Altera.

Modelsim does not pay attention to synthesis attributes. That is a vendor specific convention. You can refer to them in simulation as with any other user-defined attribute but it doesn't know that some attributes invoke special behavior in various third-party synthesizers.

If you want to initialize the RAM for simulation you will need to do one of the following:

  1. Write a function that reads the contents of the memory file and call it during initialization of the data signal.

  2. Convert the memory contents to a VHDL constant defined in a separate package and assign the constant to the data signal as the initializer. This can be automated with a script.

  3. Use the Verilog system task $readmemh (requires Modelsim with mixed language license)

For option 1, the function should be of the form:

impure function read_mem(fname : string) return mem is
  variable data : mem;
begin
  -- ** Perform read with textio **
  ...
  return data;
end function;

signal data : mem := read_mem(data'ram_init_file);

The Quartus documentation on RAM initialization is sparse and only demonstrates initialized data assigned from within a VHDL process rather than reading from a file. The Xilinx documentation on RAM/ROM inferencing (p258) provides examples for doing this with general purpose VHDL. The same technique can be used for simulating a design targeted to Altera. XST supports this use of file I/O for synthesis but Quartus may choke on it. If that is the case you will have to use a configuration to swap between a synthesis oriented RAM model and one specifically for simulation that initializes with the function.

The Xilinx example only shows how to read files with ASCII binary. I have a general purpose ROM component that reads hex as well as binary which you can adapt into a RAM for what you need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top