如何在VHDL中读取图像

在DSP项目中,需要读取图像文件并将其加载到用于功能仿真的图像处理算法的VHDL实现中。另外,在很多情况下,在合成过程中将图像加载到FPGA进行板载验证。

该VHDL教程将告诉您如何在VHDL中读取图像,以便在合成或仿真过程中将图像加载到FPGA的块存储器中。

如何在VHDL中读取图像

以来 VHDL无法直接读取BMP,JPG,TIF等图像文件,需要将图像转换为二进制文本文件,以便VHDL可以使用TEXTIO VHDL包读取图像。 
要将图像转换为二进制文本文件,可以使用Matlab或C。一旦准备好图像二进制文本文件,就可以将其复制到项目文件夹中。 

然后,在VHDL中,可以使用以下功能读取二进制文本文件:

-- by FPGA4学生.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;
请注意,您需要通过以下方式在VHDL代码中包含TEXTIO包:采用 std.textio。所有然后,要将二进制文本文件中的图像数据加载到块存储器中,只需在VHDL代码中添加以下行:
signal ram_block: mem_type := init_mem(IMAGE_FILE_NAME);
现在,让我们做一个示例代码,以VHDL读取图像。为简单起见,我们假定以下是我们从灰色图像转换而来的二进制文本文件的内容。 
00001111
11100000
00000011
10101010
00110011
11001100
11101110
00000000
00001111
11110000
11000011
00000100
11111000
10001000
01111000
10001010
然后,将图像二进制文件另存为“ IMAGE_FILE.MIF”,并将其放入项目文件夹。现在,编写VHDL代码以读取该图像二进制文本文件,并在合成或仿真过程中将其初始化到块存储器中。

以下是用于将图像文件读入FPGA的VHDL代码。该代码是可综合的。

library ieee;
采用 ieee.std_logic_1164.ALL;
采用 ieee.numeric_std.ALL;
采用 std.textio。all;
-- FPGA4学生.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;

为了验证是否正确读取了图像二进制文本文件,让我们编写一个测试平台以在模拟中对其进行测试。以下是在VHDL中读取图像的测试平台:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
采用 ieee.numeric_std.all;
-- FPGA4学生.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;
现在,该运行模拟并检查图像二进制文本文件是否正确加载到块存储器中了。下图显示该图像已正确读取到FPGA的Block RAM中。
如何将VHDL中的图像读入FPGA
要读取块存储器中的图像数据以测试图像处理设计,只需提供读取地址并启用存储器读取即可。下面的仿真波形显示二进制文本文件中的图像数据已在Block RAM的输出端口正确读取。
如何将VHDL中的图像读入FPGA
FPGA Verilog VHDL课程

3条评论:

  1. 你能帮助我吗?
    我可以't实施设计。我收到1条警告

    先感谢您。

    回复删除
    回覆
    1. 您可以分享警告吗?您是否将图片转换为上面的文本格式?

      删除

热门FPGA项目