# Open a picture and read its Pixel Values

I want to calculate the Histogram of an Image is grayscale color mode

I have designed a memory and a Calculator of Histogram value, now I want to get Pixel values and put them in Calculator as Input

I have a picture (for example a Bitmap), I should Open it and scan it's pixels but I don't have any idea how do that

Is there a function in ModelSim to Open a picture ? (Like File_Open for text files)

How I should read its Pixel values ?

• For simulation only, or do you want this to work in a synthesized design? (If so: what do you expect opening a file to do there?) – duskwuff -inactive- Jun 24 '16 at 20:03
• Only for simulation – G3ntle_Man Jun 24 '16 at 20:03
• @dim The point is : "Only Electronic Engineers uses ModelSim" so I should ask my question here to get a correct answer – G3ntle_Man Jun 24 '16 at 21:03
• @Mahmood Yeah, but very few electronic engineers do bitmap decoding from files. So if my hypothesis is correct (which I'm not sure), you'd actually get better results on stackoverflow with a title like "decoding a BMP file in VHDL". But, once again, I'm not sure what I'm saying. So I'm not voting to close or anything. Just speculating and wondering where you have most chances to get the answer you want/need. – dim Jun 24 '16 at 21:10
• @placeholder what I'm saying is that file format decoding is a purely algorithmic problem, whatever the language used. And few people here know how a BMP or JPEG is formatted. But I understand well the need for testing. If the question was just how to read a file, it wouldn't be the same problem. – dim Jun 25 '16 at 6:01

You can save your image as a PPM image (Wiki). Then you can load or save it as text file

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

--architecture definition

-- file declaration
-- type "text" is already declared in textio library
FILE input_file  : text OPEN read_mode IS sim_file;

BEGIN

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