How to Read Image in VHDL

In DSP projects, it is required to read image files and load them into VHDL implementations of the image processing algorithms for functional simulations. In addition, there are many cases that images are loaded into FPGAs during synthesis for onboard verifications.

This VHDL tutorial is to tell you how to read images in VHDL in a way that the images can be loaded into the block memory of the FPGA during synthesis or simulation.

How to Read Image in VHDL

Since VHDL cannot read image files such as BMP, JPG, TIF, etc. directly, images are required to be converted into binary text files so that VHDL can read them using the TEXTIO VHDL package. 
To convert images into binary text files, you can use Matlab or C. Once the image binary text files are ready, you can copy it to the project folder. 

Then, in VHDL, the binary text files can be read using the following function:

-- by FPGA4student.com
impure function init_mem(mif_file_name : in string) return mem_type is
    file mif_file : text open read_mode is mif_file_name;
    variable mif_line : line;
    variable temp_bv : bit_vector(DATA_WIDTH-1 downto 0);
    variable temp_mem : mem_type;
begin
    for i in mem_type'range loop
        readline(mif_file, mif_line);
        read(mif_line, temp_bv);
        temp_mem(i) := to_stdlogicvector(temp_bv);
    end loop;
    return temp_mem;
end function;
It is noted that you need to include the TEXTIO package in the VHDL code by "use std.textio.all". Then, to load the image data in the binary text files into the block memory, you just need to add the following line to the VHDL code:
signal ram_block: mem_type := init_mem(IMAGE_FILE_NAME);
Now, let's do an example code for reading images in VHDL. For simplicity, let's assume that the following is the content of the binary text file that we converted from a gray image. 
00001111
11100000
00000011
10101010
00110011
11001100
11101110
00000000
00001111
11110000
11000011
00000100
11111000
10001000
01111000
10001010
Then, save the image binary file as "IMAGE_FILE.MIF" and put it to the project folder. Now, write a VHDL code to read this image binary text file and initialize it into a block memory during synthesis or simulation.

Below is the VHDL code for reading image files into FPGA. The code is synthesizable.

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use std.textio.all;
-- FPGA4student.com: FPGA/Verilog/VHDL projects for students
-- VHDL tutorial: How to Read images in VHDL
entity read_image_VHDL is
  generic (
    ADDR_WIDTH     : integer := 4;        
    DATA_WIDTH     : integer := 8;
    IMAGE_SIZE  : integer := 15;
    IMAGE_FILE_NAME : string :="IMAGE_FILE.MIF"
  );
  port(
    clock: IN STD_LOGIC;
    data: IN std_logic_vector ((DATA_WIDTH-1) DOWNTO 0);
    rdaddress: IN STD_logic_vector((ADDR_WIDTH-1) downto 0);
    wraddress: IN STD_logic_vector((ADDR_WIDTH-1) downto 0);
    we: IN STD_LOGIC;
    re: IN STD_LOGIC;
    q: OUT std_logic_vector ((DATA_WIDTH-1) DOWNTO 0));
end read_image_VHDL;

architecture behavioral of read_image_VHDL is

TYPE mem_type IS ARRAY(0 TO IMAGE_SIZE) OF std_logic_vector((DATA_WIDTH-1) DOWNTO 0);

impure function init_mem(mif_file_name : in string) return mem_type is
    file mif_file : text open read_mode is mif_file_name;
    variable mif_line : line;
    variable temp_bv : bit_vector(DATA_WIDTH-1 downto 0);
    variable temp_mem : mem_type;
begin
    for i in mem_type'range loop
        readline(mif_file, mif_line);
        read(mif_line, temp_bv);
        temp_mem(i) := to_stdlogicvector(temp_bv);
    end loop;
    return temp_mem;
end function;

signal ram_block: mem_type := init_mem(IMAGE_FILE_NAME);
signal read_address_reg: std_logic_vector((ADDR_WIDTH-1) downto 0) := (others=>'0');
  
begin
  process (clock)
  begin
   if (rising_edge(clock)) then
      if (we = '1') then
        ram_block(to_integer(unsigned(wraddress))) <= data;
      end if;
      if (re = '1') then
        q <= ram_block(to_integer(unsigned(rdaddress)));
      end if;
    end if;
  end process;

end behavioral;

To verify if the image binary text file is read properly, let's write a testbench to test it in a simulation. Following is the testbench for reading image in VHDL:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
-- FPGA4student.com: FPGA/Verilog/VHDL projects for students
-- VHDL tutorial: How to Read images in VHDL
ENTITY tb_read_image_vhdl IS
END tb_read_image_vhdl;
ARCHITECTURE behavior OF tb_read_image_vhdl IS 
    COMPONENT read_image_VHDL
    PORT(
         clock : IN  std_logic;
         data : IN  std_logic_vector(7 downto 0);
         rdaddress : IN  std_logic_vector(3 downto 0);
         wraddress : IN  std_logic_vector(3 downto 0);
         we : IN  std_logic;
         re : IN  std_logic;
         q : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
   --Inputs
   signal clock : std_logic := '0';
   signal data : std_logic_vector(7 downto 0) := (others => '0');
   signal rdaddress : std_logic_vector(3 downto 0) := (others => '0');
   signal wraddress : std_logic_vector(3 downto 0) := (others => '0');
   signal we : std_logic := '0';
   signal re : std_logic := '0';
  --Outputs
   signal q : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clock_period : time := 10 ns;
   signal i: integer;
BEGIN
 -- Read image in VHDL
   uut: read_image_VHDL PORT MAP (
          clock => clock,
          data => data,
          rdaddress => rdaddress,
          wraddress => wraddress,
          we => we,
          re => re,
          q => q
        );

   -- Clock process definitions
   clock_process :process
   begin
  clock <= '0';
  wait for clock_period/2;
  clock <= '1';
  wait for clock_period/2;
   end process;
   -- Stimulus process
   stim_proc: process
   begin  
                data <= x"00";
  rdaddress <= x"0";
  wraddress <= x"0";
  we <= '0';
  re <= '0';
                wait for 100 ns;
  re <= '1';  
  for i in 0 to 15 loop
  rdaddress <= std_logic_vector(to_unsigned(i, 4));
  wait for 20 ns;
  end loop;
      wait;
   end process;

END;
Now, it's time to run the simulation and check if the image binary text file is loaded correctly into the block memory. The following figure shows that the image was read properly into the block RAM of FPGAs.
How to Read Image in VHDL into FPGA
To read the image data in the block memory for testing your image processing design, just provide read addresses and enable memory reading. The following simulation waveform shows the image data in the binary text file is read out correctly at the output port of the block RAM.
How to Read Image in VHDL into FPGA

2 comments:

  1. Can you help me?
    I can't Implement Design. I received 1 warning that

    Thank you in advance.

    ReplyDelete
    Replies
    1. Could you share the warning? Did you convert the image into the text format above?

      Delete

Trending FPGA Projects