Unfortunately, I don't think there is a way of doing this using just VHDL and ModelSim. You will most likely want to use a scripting language such as MatLab or Python to generate ASCII text file which can be read in from VHDL.
I wrote the following function in Matlab to do the conversion for 16 bit grayscale image data.
% Convert an image to a VHDL compatible input file
function img_to_vhdl_txt(grayscale_img,filename)
% Invert image.
grayscale_img = grayscale_img';
% Columnize the image and convert each pixel to a 4 digit hex string
hex_stream = cellstr(num2str(grayscale_img(:),'%04x'));
% write out file using new line as the delimter
dlmwrite(filename, hex_stream, '-append', 'delimiter', '', 'newline', 'pc');
end
Once you generate the necessary data file you can read it in one pixel at a time using this VHDL component:
----------------------------------------------------------------------------------
-- Reads bytes from a file located at the path specified in the "input_file"
-- declaration. At the end of the file EOF is set high.
--
-- Expects ASCII hex data as the input. Reads one line per clock. For example,
-- if the desired output is: 01,23,45,67,89,AB,CD,EF the input text file should
-- contain:
-- 01
-- 23
-- 45
-- ..
-- EF
--
----------------------------------------------------------------------------------
--include this library for file handling in VHDL.
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all; --include package textio.vhd
--entity declaration
entity read_file is
generic
(
sim_file : string := "..\..\Testbench\image_in.raw";
DATA_WIDTH : integer := 12;
DATA_WIDTH_BYTES : integer := 2
);
port
(
clk : in std_logic;
enable : in std_logic;
eof : out std_logic;
valid : out std_logic;
data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end read_file;
--architecture definition
architecture Behavioral of read_file is
-- file declaration
-- type "text" is already declared in textio library
FILE input_file : text OPEN read_mode IS sim_file;
BEGIN
-- Read process
PROCESS(clk)
-- file variables
VARIABLE vDatainline : line;
VARIABLE vDatain : std_logic_vector((DATA_WIDTH_BYTES*8)-1 DOWNTO 0);
BEGIN
if rising_edge(clk) then
valid <= '0';
if not endfile(input_file) then
if enable = '1' then
readline (input_file, vDatainline); -- Get line from input file
hread (vDatainline, vDatain); -- Read line as Hex
valid <= '1'; -- Data is valid
data <= ((vDatain(DATA_WIDTH-1 downto 0))); -- Convert variable to signal
end if;
eof <= '0';
else
eof <= '1';
end if;
end if;
END PROCESS;
end Behavioral;
Alternatively, you could try generating a memory initialization file (Altera=.mif, Xilinx=.coe) from the data (once again using a script or external program) and generate an IP ROM for simulation using Altera's/Xilinx's tools.
Hope this helps (and if you find a better way to do it please post back here)