如何读取图像文件并将其转换为vhdl中的位 [英] how to read image file and convert it to bits in vhdl

查看:186
本文介绍了如何读取图像文件并将其转换为vhdl中的位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用vhdl中的textio包读取图像文件。
如果我用记事本打开一个.jpg,我会得到一些垃圾数据,但实际上它是ASCII数据。在这里,我试图读取这些ascii数据并将它们转换为字节。



下面是我的代码:

  library ieee; 
使用ieee.std_logic_1164.all;
使用std.textio.all;
使用ieee.std_logic_textio.all;

实体file_io是

端口(
clk:在std_logic;
数据:out std_logic_vector(7 downto 0)
);
终端实体;

file_io的架构行为是

signal test_data:std_logic_vector(7 downto 0);
使用ieee.numeric_std.all;
使用std.textio.all;
使用ieee.std_logic_textio.all;
begin

File_reader:process(clk)
file f:text open read_mode是C:\ Users \Public \Pictures \Sample Pictures \Chrysanthemum。 JPG;
变量L:line;
变量var_int:integer:= 0;
变量var_char:character;

开始

如果rising_edge(clk)然后
而不是endfile(f)循环
readline(f,L);
read(L,var_char);
var_int:= character'pos(var_char);
test_data< = std_logic_vector(to_unsigned(var_int,test_data'length));
结束循环;
结束如果;
数据< = test_data;
结束流程;
结构架构行为;

testbench:

  LIBRARY ieee; 
使用ieee.std_logic_1164.ALL;
使用std.textio.all;

ENTITY file_io_test IS
END file_io_test;

架构行为OF file_io_test IS
使用work.io.all;
signal clk:std_logic:='0';
信号数据:std_logic_vector(7 downto 0);

- 时钟周期定义
常数clk_period:时间:= 10 ns;

BEGIN
- 实例化被测单位(UUT)
UUT:
实体work.file_io(behav)
端口图(
clk => clk,
Data => Data
);

- 时钟过程定义(此处生成占空比为50%的时钟。
clk_process:process
begin
clk< ='1';
等待clk_period / 2; - 5ns信号为'1'。
clk< ='0';
等待clk_period / 2; - 接下来5 ns信号为' 0'。

结束流程;
结束行为;

我只得到波形中的一个字节。预期的结果是:每个时钟周期新字符应该是rread并且应该获得新字节。



下面是波形:



下面是我想要阅读的图片:



VHDL中可以一次读取一个原始字符(符合您的需要)。



参见IEEE Std 1076-2008 5.5文件类型:



所以我们所要做的就是声明一个文件类型,我们会隐式定义这些程序。



我们可以使用它们来调用原始读取,而不会因textio引起任何行结束问题:

  library ieee ; 
使用ieee.std_logic_1164.all;

实体file_io是
端口(
clk:在std_logic中;
数据:out std_logic_vector(7 downto 0);
done:out boolean
);
终端实体;

file_io的架构foo是
使用ieee.numeric_std.all;
begin

File_reader:
process(clk)
- C:\ Users \Public \Pictures \Sample Pictures\Chrysanthemum.jpg ;
constant filename:string:=Chrysanthemum.jpg; - 本地到sim
变量char_val:character;
变量状态:FILE_OPEN_STATUS;
变量openfile:boolean; - 默认为FALSE
类型f是字符文件;
file ffile:f;
变量char_count:natural:= 0;
如果rising_edge(clk)则为
,如果不是openfile则为
,然后是
file_open(status,ffile,filename,READ_MODE);
如果状态/ = OPEN_OK则
报告FILE_OPEN_STATUS =&
FILE_OPEN_STATUS'IMAGE(状态)
严重性失败;
结束如果;
报告FILE_OPEN_STATUS =& FILE_OPEN_STATUS'IMAGE(状态);
openfile:= TRUE;
else
如果不是endfile(ffile)那么
read(ffile,char_val);
- 报告char_val =& character'image(char_val);
char_count:= char_count + 1;
Data< = std_logic_vector(
to_unsigned(character'pos(char_val),
Data'length));
结束如果;
如果是endfile(ffile)那么 - 可以在最后一个字符后出现
报告ENDFILE,read&
integer'image(char_count)& 人物;
done< = TRUE;
FILE_CLOSE(ffile);
结束如果;
结束如果;
结束如果;
结束流程;
end architecture foo;

library ieee;
使用ieee.std_logic_1164.all;

实体file_io_test是
end file_io_test;

file_io_test的架构行为是
signal clk:std_logic:='0';
信号数据:std_logic_vector(7 downto 0);
信号完成:布尔值;
常数clk_period:时间:= 10 ns;
begin
uut:
entity work.file_io(foo)
port map(
clk => clk,
data => data,
done => done
);

clk_process:
流程
如果没有,则开始
然后
clk< ='1';
等待clk_period / 2;
clk< ='0';
等待clk_period / 2;
其他
等;
结束如果;
结束流程;
结束架构行为;

现在我们可以拥有所有字符,而不是可以在我们的阅读中分隔一行:





请注意,包std.textio不会通过任何内容显示上下文项目。


I am trying to read an image file using textio package in vhdl. If i open an .jpg with notepad , i will get some junk data but actually it is ASCII data . Here i am trying to read these ascii data and convert them into bytes.

below is my code:

library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;

entity file_io is

 port (
     clk:             in  std_logic;
     Data:            out std_logic_vector(7 downto 0)
 );
 end entity;

 architecture behav of file_io is

signal test_data : std_logic_vector(7 downto 0);
use ieee.numeric_std.all; 
use std.textio.all;
use ieee.std_logic_textio.all;
begin

File_reader:process(clk)
    file f    : text open read_mode is "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
    variable L:   line;
    variable var_int:   integer:= 0;
    variable var_char:   character;  

begin

if rising_edge(clk) then
        while not endfile(f) loop
                 readline(f, L);
         read(L, var_char);
         var_int := character'pos(var_char);
         test_data  <= std_logic_vector(to_unsigned(var_int, test_data'length));  
        end loop;
     end if;
    Data <= test_data;
  end process;
end architecture behav;

testbench:

LIBRARY ieee;
use ieee.std_logic_1164.ALL;
use std.textio.all;

ENTITY file_io_test IS 
END file_io_test;

ARCHITECTURE behavior OF file_io_test IS
use work.io.all;
    signal clk:         std_logic := '0';
    signal Data: std_logic_vector(7 downto 0);

    -- Clock period definitions
    constant clk_period : time := 10 ns;

    BEGIN
      -- Instantiate the Unit Under Test (UUT)
    UUT:
     entity work.file_io(behav)
    port map (
           clk => clk,
        Data => Data
          );

    -- Clock process definitions( clock with 50% duty cycle is generated here.
     clk_process :process
       begin
         clk <= '1';
         wait for clk_period/2;  --for 5 ns signal is '1'.
          clk <= '0';
         wait for clk_period/2;  --for next 5 ns signal is '0'.

     end process;
    end behavior;  

I am getting only one byte in waveform. expected result is : Every clock cycle new character should be rread and new byte should be obtained.

below is waveform:

below is the image I am trying to read:

解决方案

The question has a fundamental flaw. You can't use textio to read binary values, it's for text.

See IEEE Std 1076-2008 16.4 Package TEXTIO paragraphs 3 (in part) and 4:

Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. ...

The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.

And that can be demonstrated with your Chrysanthemum.jpg:

It is possible in VHDL to read raw characters one at a time (matching your need).

See IEEE Std 1076-2008 5.5 File types:

So all we have to do is declare a file type and we get these procedures defined implicitly.

We can use them to invoke raw read, without any end of line issues caused by textio:

library ieee;
use ieee.std_logic_1164.all;

entity file_io is
    port (
        clk:    in  std_logic;
        Data:   out std_logic_vector(7 downto 0);
        done:   out boolean
 );
 end entity;

architecture foo of file_io is
    use ieee.numeric_std.all;
begin

File_reader:
    process (clk)
        -- "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
        constant filename:  string := "Chrysanthemum.jpg"; -- local to sim
        variable char_val:  character;
        variable status: FILE_OPEN_STATUS;
        variable openfile:  boolean;  -- FALSE by default
        type f is file of character;
        file ffile: f;
        variable char_count:    natural := 0;
    begin
        if rising_edge (clk) then
            if not openfile then
                file_open (status, ffile, filename, READ_MODE);
                if status /= OPEN_OK then
                    report "FILE_OPEN_STATUS = " & 
                            FILE_OPEN_STATUS'IMAGE(status)
                    severity FAILURE;
                end if;
                report "FILE_OPEN_STATUS = " & FILE_OPEN_STATUS'IMAGE(status);
                openfile := TRUE;
            else 
                if not endfile(ffile) then
                    read(ffile, char_val);
                    -- report "char_val = " & character'image(char_val);
                    char_count := char_count + 1;
                    Data  <= std_logic_vector (
                             to_unsigned(character'pos(char_val),
                             Data'length) );
                 end if;
                 if endfile(ffile) then  -- can occur after last character
                    report "ENDFILE, read " & 
                          integer'image(char_count) & "characters";
                    done <= TRUE;
                    FILE_CLOSE(ffile);
                end if;
            end if;
        end if;
    end process;
end architecture foo;

library ieee;
use ieee.std_logic_1164.all;

entity file_io_test is 
end file_io_test;

architecture behavior of file_io_test is
    signal clk:         std_logic := '0';
    signal data:        std_logic_vector(7 downto 0);
    signal done:        boolean;
    constant clk_period: time := 10 ns;
begin
uut:
    entity work.file_io(foo)
        port map (
           clk => clk,
           data => data,
           done => done
        );

clk_process:
    process
    begin
        if not done then
             clk <= '1';
             wait for clk_period/2;
              clk <= '0';
             wait for clk_period/2;
         else
             wait;
         end if;
     end process;
end architecture behavior;  

Now we can have all the characters than can delimit a line show up in our read:

Note that package std.textio is not made visible through any context item.

这篇关于如何读取图像文件并将其转换为vhdl中的位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆