A generic VHDL ROM with content initialisation from a file

This post describes how to code a technology-independent VHDL ROM memory and the use of an external file for setting the initial contents.

  1. library ieee ;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_Std.all;
  4. library std ;
  5. use std.textio.all;
  6. entity spROM is
  7.  generic (initFile : string := "dummy_file_name.mif");
  8.  port (
  9.   CLK : in std_logic;
  10.   ADDRESS : in std_logic_vector;
  11.   DATAOUT : out std_logic_vector
  12. );
  13. end entity spROM;
  14. architecture arcspROM of spROM is
  15.  type romType is array(0 to 2**ADDRESS'length-1) of std_logic_vector(DATAOUT'length-1 downto 0);
  16.  -- uses VHDL 2008 hread
  17.  impure function initRomFromFile return romType is
  18.   file data_file : text open read_mode is initFile;
  19.   variable data_fileLine : line;
  20.   variable ROM : romType;
  21.  begin
  22.   for I in romType'range loop
  23.    readline(data_file, data_fileLine);
  24.    hread(data_fileLine, ROM(I));
  25.   end loop;
  26.   return ROM;
  27.  end function;
  28.  signal rom : romType := initRomFromFile;
  29.  attribute rom_style : string;
  30.  attribute rom_style of rom : signal is "block";
  31. begin
  32.  process (CLK)
  33.  begin
  34.   if (CLK'event and CLK = '1') then
  35.    DATAOUT <= rom(to_integer(unsigned(ADDRESS)));
  36.   end if;
  37.  end process;
  38. end architecture arcspROM;

Listing 2

A VHDL impure function is used so that it can reference the file name that is provided as a generic. Note also how the number of elements in the std_logic_vectors for ADDRESS and DATAOUT are not specified - they will be "inherited" from the top level file that instantiates the ROM.


The spROM module can then be instantiated in a higher-level VHDL file like this:

  1. library ieee ;
  2. use ieee.std_logic_1164.all;
  3. entity top_mem is
  4.  port (
  5.   CLK : in std_logic;
  6.   ADDRESS : in std_logic_vector(3 downto 0);
  7.   DATAOUT : out std_logic_vector(15 downto 0)
  8.  );
  9. end entity top_mem;
  10. architecture arc_top_mem of top_mem is
  11.  component spROM is
  12.   generic (initFile : string := "dummy_file_name.mif");
  13.   port (
  14.    CLK : in std_logic;
  15.    ADDRESS : in std_logic_vector;
  16.    DATAOUT : out std_logic_vector );
  17.  end component spROM_16;
  18. begin
  19.  U0 : spROM
  20.   generic map (initFile => "my_init_file.mif")
  21.   port map (
  22.    CLK => CLK,
  23.    ADDRESS => ADDRESS,
  24.    DATAOUT => DATAOUT );
  25. end architecture arc_top_mem;

Listing 3

A zip archive that includes the VHDL source files and an example memory initialisation file is available here.